001package com.fs.starfarer.api.impl.combat.dweller;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import com.fs.starfarer.api.Global;
007import com.fs.starfarer.api.combat.CombatAssignmentType;
008import com.fs.starfarer.api.combat.CombatEngineAPI;
009import com.fs.starfarer.api.combat.CombatFleetManagerAPI;
010import com.fs.starfarer.api.combat.CombatFleetManagerAPI.AssignmentInfo;
011import com.fs.starfarer.api.combat.CombatTaskManagerAPI;
012import com.fs.starfarer.api.combat.DeployedFleetMemberAPI;
013import com.fs.starfarer.api.combat.ShipAPI;
014import com.fs.starfarer.api.fleet.FleetGoal;
015import com.fs.starfarer.api.impl.campaign.ids.HullMods;
016import com.fs.starfarer.api.impl.campaign.ids.Tags;
017import com.fs.starfarer.api.util.IntervalUtil;
018
019/**
020 * Like the Threat one:
021 * Doesn't care about command points etc, just functions in a different way. May use command points/tasks/etc
022 * to accomplish its goals, just as an implementation detail, but conceptually it's fundamentally different from how
023 * human-type fleets work.
024 * 
025 * @author Alex
026 *
027 */
028public class DwellerCombatStrategyAI {
029        
030        public static float SND_BASE = 60f;
031        public static float SND_TIMER = 60f;
032        public static float SND_FRACTION = 0.5f;
033        
034        protected boolean playerSide;
035        protected CombatTaskManagerAPI taskManager;
036        protected CombatFleetManagerAPI fleetManager;
037        protected CombatFleetManagerAPI enemyFleetManager;
038        protected int owner;
039        protected boolean allyMode = false;
040        
041        protected IntervalUtil everySecond = new IntervalUtil(0.8f, 1.2f);
042        protected CombatEngineAPI engine;
043        protected float mw, mh;
044        
045        protected boolean abort = false;
046        
047        protected AssignmentInfo mainDefend1;
048        protected AssignmentInfo mainDefend2;
049        
050        protected boolean gaveInitialOrders = false;
051        
052        
053        public DwellerCombatStrategyAI(int owner) {
054                engine = Global.getCombatEngine();
055                this.owner = owner;
056                playerSide = owner == 0;
057                allyMode = playerSide;
058                //allyMode = false;
059                fleetManager = engine.getFleetManager(owner);
060                taskManager = fleetManager.getTaskManager(allyMode);
061                taskManager.getCommandPointsStat().modifyFlat("DwellerCombatStrategyAI", 1000000000);
062                
063                enemyFleetManager = engine.getFleetManager(owner == 0 ? 1 : 0);
064                
065                if (fleetManager.getGoal() == FleetGoal.ESCAPE || enemyFleetManager.getGoal() == FleetGoal.ESCAPE) {
066                        abort = true;
067                } else {
068                        if (fleetManager.getAdmiralAI() != null) {
069                                taskManager.clearTasks();
070                                fleetManager.getAdmiralAI().setNoOrders(true);
071                        }
072                }
073                
074                mw = engine.getMapWidth();
075                mh = engine.getMapHeight();
076        }
077        
078        protected void giveInitialOrders() {
079                                
080        }
081        
082        
083        public void advance(float amount) {
084                //if (true) return;
085                if (abort) return;
086                if (engine.isPaused()) return;
087                
088                everySecond.advance(amount);
089                if (everySecond.intervalElapsed()) {
090                        // if non-threat ships are deployed from this fleetManager, don't want to be doing any Threat things
091                        List<DeployedFleetMemberAPI> deployed = fleetManager.getDeployedCopyDFM();
092                        if (deployed.isEmpty()) return;
093                        
094                        boolean someMatching = false;
095                        for (DeployedFleetMemberAPI member : deployed) {
096                                if (!member.isFighterWing() && member.getShip() != null &&
097                                                member.isAlly() == allyMode &&
098                                                !member.getShip().getVariant().hasHullMod(HullMods.DWELLER_HULLMOD)) {
099                                        abort = true;
100                                        return;
101                                } else if (!member.isFighterWing() && member.getShip() != null &&
102                                                member.isAlly() == allyMode) {
103                                        someMatching = true;
104                                }
105                        }
106                        
107                        if (!someMatching) return;
108                        
109                        if (!gaveInitialOrders) {
110                                giveInitialOrders();
111                                gaveInitialOrders = true;
112                        }
113                        
114                        for (DeployedFleetMemberAPI member : fleetManager.getDeployedCopyDFM()) {
115                                ShipAPI ship = member.getShip();
116                                if (ship == null || ship.getAI() == null) continue;
117                                
118                                if (isMaw(ship)) {
119                                        AssignmentInfo curr = taskManager.getAssignmentInfoForTarget(member);
120                                        if (curr == null) {
121                                                taskManager.createAssignment(CombatAssignmentType.DEFEND, member, false);
122                                                taskManager.orderSearchAndDestroy(member, false);
123                                        }
124                                } else if (isEye(ship)) {
125                                        AssignmentInfo curr = taskManager.getAssignmentInfoForTarget(member);
126                                        if (curr == null) {
127                                                taskManager.createAssignment(CombatAssignmentType.HEAVY_ESCORT, member, false);
128                                                taskManager.orderSearchAndDestroy(member, false);
129                                        }
130                                } else if (isStinger(ship)) {
131//                                      AssignmentInfo curr = taskManager.getAssignmentInfoForTarget(member);
132//                                      if (curr == null) {
133//                                              taskManager.createAssignment(CombatAssignmentType.HEAVY_ESCORT, member, false);
134//                                              taskManager.orderSearchAndDestroy(member, false);
135//                                      }
136                                }
137                        }
138                        
139                        cleanUpEmptyAssignments();
140                }
141        }
142        
143        
144        protected void cancelOrders(DeployedFleetMemberAPI member, boolean withSearchAndDestroy) {
145                AssignmentInfo curr = taskManager.getAssignmentFor(member.getShip());
146                if (curr != null) {
147                        taskManager.removeAssignment(curr);
148                }
149                if (withSearchAndDestroy) {
150                        taskManager.orderSearchAndDestroy(member, false);
151                }
152        }
153        
154        public void cleanUpEmptyAssignments() {
155                taskManager.reassign(); // so assigned members isn't empty
156                List<AssignmentInfo> remove = new ArrayList<>();
157                for (AssignmentInfo curr : taskManager.getAllAssignments()) {
158                        if (curr.getType() == CombatAssignmentType.CONTROL) continue;
159                        if (curr.getType() == CombatAssignmentType.CAPTURE) continue;
160                        if (curr.getType() == CombatAssignmentType.DEFEND) continue;
161                        if (curr.getAssignedMembers().isEmpty()) {
162                                remove.add(curr);
163                        }
164                }
165                for (AssignmentInfo curr : remove) {
166                        taskManager.removeAssignment(curr);
167                }
168                
169                taskManager.clearEmptyWaypoints();
170        }
171        
172        
173        public static boolean isMaw(ShipAPI ship) {
174                boolean isMaw = ship != null && ship.isCapital();
175                return isMaw;
176        }
177        public static boolean isEye(ShipAPI ship) {
178                boolean isEye = ship != null && ship.isCruiser() && ship.getHullSpec().hasTag(Tags.DWELLER_RECKLESS);
179                return isEye;
180        }
181        public static boolean isStinger(ShipAPI ship) {
182                boolean isEye = ship != null && ship.isCruiser() && ship.getHullSpec().hasTag(Tags.DWELLER_TIMID);
183                return isEye;
184        }
185        public static boolean isTendril(ShipAPI ship) {
186                boolean isTendril = ship != null && ship.isDestroyer();
187                return isTendril;
188        }
189}
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212