001package com.fs.starfarer.api.impl.combat.threat;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import org.lwjgl.util.vector.Vector2f;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.combat.CombatEngineAPI;
010import com.fs.starfarer.api.combat.ShieldAPI;
011import com.fs.starfarer.api.combat.ShipAPI;
012import com.fs.starfarer.api.combat.ShipCommand;
013import com.fs.starfarer.api.combat.ShipSystemAIScript;
014import com.fs.starfarer.api.combat.ShipSystemAPI;
015import com.fs.starfarer.api.combat.ShipwideAIFlags;
016import com.fs.starfarer.api.combat.ShipwideAIFlags.AIFlags;
017import com.fs.starfarer.api.util.IntervalUtil;
018import com.fs.starfarer.api.util.Misc;
019import com.fs.starfarer.api.util.WeightedRandomPicker;
020
021
022public class EnergyLashSystemAI implements ShipSystemAIScript {
023
024        protected ShipAPI ship;
025        protected CombatEngineAPI engine;
026        protected ShipwideAIFlags flags;
027        protected ShipSystemAPI system;
028        protected EnergyLashSystemScript script;
029        
030        protected IntervalUtil tracker = new IntervalUtil(0.5f, 1f);
031        
032        public void init(ShipAPI ship, ShipSystemAPI system, ShipwideAIFlags flags, CombatEngineAPI engine) {
033                this.ship = ship;
034                this.flags = flags;
035                this.engine = engine;
036                this.system = system;
037                
038                script = (EnergyLashSystemScript)system.getScript();
039        }
040        
041        public void advance(float amount, Vector2f missileDangerDir, Vector2f collisionDangerDir, ShipAPI target) {
042                tracker.advance(amount);
043                
044                if (tracker.intervalElapsed()) {
045                        if (system.getCooldownRemaining() > 0) return;
046                        if (system.isOutOfAmmo()) return;
047                        if (system.isActive()) return;
048                        if (ship.getFluxTracker().isOverloadedOrVenting()) return;
049                        
050                        ShipAPI pick = getWeightedTargets(target).getItemWithHighestWeight();
051                        if (pick != null) {
052                                ship.getAIFlags().setFlag(AIFlags.CUSTOM1, 1.5f, pick);
053                                ship.giveCommand(ShipCommand.USE_SYSTEM, null, 0);
054                                //System.out.println("Lash target: " + pick);
055                        }
056                }
057        }
058        
059        public List<ShipAPI> getPossibleTargets() {
060                List<ShipAPI> result = new ArrayList<>();
061                CombatEngineAPI engine = Global.getCombatEngine();
062                
063                List<ShipAPI> ships = engine.getShips();
064                for (ShipAPI other : ships) {
065                        if (other == ship) continue;
066                        if (!script.isValidLashTarget(ship, other)) continue;
067                        if (!script.isInRange(ship, other)) continue;
068                        result.add(other);
069                }
070                return result;
071        }
072        
073        public WeightedRandomPicker<ShipAPI> getWeightedTargets(ShipAPI shipTarget) {
074                WeightedRandomPicker<ShipAPI> picker = new WeightedRandomPicker<>();
075                
076                for (ShipAPI other : getPossibleTargets()) {
077                        float w = 0f;
078                        if (ship.getOwner() == other.getOwner()) {
079                                if (ThreatSwarmAI.isAttackSwarm(other)) {
080                                        RoilingSwarmEffect swarm = RoilingSwarmEffect.getSwarmFor(other);
081                                        if (swarm != null && !VoltaicDischargeOnFireEffect.isSwarmPhaseMode(other)) {
082                                                w = 0.5f;
083                                        } else {
084                                                continue;
085                                        }
086                                } else {
087                                        if (other.getSystem() == null) continue;
088                                        if (!(other.getSystem().getScript() instanceof EnergyLashActivatedSystem)) continue;
089                                        if (other.getSystem().getCooldownRemaining() > 0) continue;
090                                        if (other.getSystem().isActive()) continue;
091                                        if (other.getFluxTracker().isOverloadedOrVenting()) continue;
092                                        
093                                        EnergyLashActivatedSystem otherSystem = (EnergyLashActivatedSystem) other.getSystem().getScript();
094                                        w = otherSystem.getCurrentUsefulnessLevel(ship, other);
095                                }
096//                              if (other.getSystem().getSpecAPI().hasTag(Tags.SHIP_SYSTEM_MOVEMENT)) {
097//                              }
098//                              if (other.getSystem().getSpecAPI().hasTag(Tags.SHIP_SYSTEM_OFFENSIVE)) {
099//                                      Object test = ship.getAIFlags().getCustom(AIFlags.MANEUVER_TARGET);
100//                                      if (test instanceof ShipAPI) {
101//                                              ShipAPI otherTarget = (ShipAPI) test;
102//                                              float dist = Misc.getDistance(other.getLocation(), otherTarget.getLocation());
103//                                              dist -= other.getCollisionRadius() + otherTarget.getCollisionRadius();
104//                                              if (dist < 1500f) {
105//                                              }
106//                                      }
107//                              }
108                        } else {
109                                ShieldAPI targetShield = other.getShield();
110                                boolean targetShieldsFacingUs = targetShield != null &&
111                                                        targetShield.isOn() &&
112                                                        Misc.isInArc(targetShield.getFacing(), Math.max(30f, targetShield.getActiveArc()),
113                                                                        other.getLocation(), ship.getLocation());
114                                if (targetShieldsFacingUs && EnergyLashSystemScript.DAMAGE <= 0) continue;
115                                
116                                float dist = Misc.getDistance(ship.getLocation(), other.getLocation());
117                                dist -= ship.getCollisionRadius() + other.getCollisionRadius();
118                                if (dist < 0) dist = 0;
119                                if (other == shipTarget) {
120                                        w += 0.25f;
121                                }
122                                if (dist < 1000f) {
123                                        w += (1f - (dist / 1000f)) * 0.5f;
124                                }
125                                if (other.isPhased()) {
126                                        w += 0.5f;
127                                }
128                                w += 0.01f;
129                        }
130                        picker.add(other, w);
131                }
132                return picker;
133        }
134
135}
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157