001package com.fs.starfarer.api.combat;
002
003import java.util.ArrayList;
004import java.util.HashMap;
005import java.util.List;
006import java.util.Map;
007
008public class ShipwideAIFlags {
009        public static enum AIFlags {
010                //IS_ENGAGED,
011                
012                HARASS_MOVE_IN,
013                HARASS_MOVE_IN_COOLDOWN,
014                
015                AVOIDING_BORDER,
016                DO_NOT_AVOID_BORDER,
017                CAMP_LOCATION,
018                FACING_OVERRIDE_FOR_MOVE_AND_ESCORT_MANEUVERS,
019                ESCORT_OTHER_SHIP,
020                //PULL_BACK_FIGHTERS, // can do ship.setForceCarrierPullBackTime()
021                
022                
023                
024                MANEUVER_TARGET,
025                MOVEMENT_DEST_WHILE_SIDETRACKED,
026                CARRIER_FIGHTER_TARGET,
027                MAINTAINING_STRIKE_RANGE,
028                //CARRIER_DEFEND_TARGET,
029                DRONE_MOTHERSHIP,
030                
031                DO_NOT_USE_SHIELDS,
032                DO_NOT_USE_FLUX,
033                DO_NOT_VENT,
034                DO_NOT_AUTOFIRE_NON_ESSENTIAL_GROUPS,
035                RUN_QUICKLY,
036                TURN_QUICKLY,
037                PURSUING,
038                HAS_INCOMING_DAMAGE,
039                KEEP_SHIELDS_ON,
040                STAY_PHASED, // will not re-phase but should stay phased if cloak is on
041                PHASE_BRAWLER_DUMPING_FLUX, // will not re-phase but should stay phased if cloak is on
042                DO_NOT_BACK_OFF,
043                
044                /**
045                 * To function reliably, requires DO_NOT_BACK_OFF to be set, also.
046                 */
047                DO_NOT_BACK_OFF_EVEN_WHILE_VENTING,
048                BACK_OFF,
049                BACK_OFF_MIN_RANGE,
050                BACK_OFF_MAX_RANGE,
051                STANDING_OFF_VS_SHIP_ON_MAP_BORDER,
052                BACKING_OFF,
053                SAFE_VENT,
054                OK_TO_CANCEL_SYSTEM_USE_TO_VENT,
055                
056                MANEUVER_RANGE_FROM_TARGET,
057                
058                SAFE_FROM_DANGER_TIME,
059                
060                PREFER_LEFT_BROADSIDE,
061                PREFER_RIGHT_BROADSIDE,
062                
063                AUTO_FIRING_AT_PHASE_SHIP,
064                AUTO_BEAM_FIRING_AT_PHASE_SHIP,
065                
066                DELAY_STRIKE_FIRE,
067                
068                PHASE_ATTACK_RUN,
069                PHASE_ATTACK_RUN_FROM_BEHIND_DIST_CRITICAL,
070                PHASE_ATTACK_RUN_IN_GOOD_SPOT,
071                PHASE_ATTACK_RUN_TIMEOUT,
072                
073                DO_NOT_PURSUE,
074                
075                TIMID_ESCORT,
076                ESCORT_RANGE_MODIFIER,
077                IGNORES_ORDERS,
078                
079                
080                /**
081                 * Only set for phase ships using the default phase cloak AI. 
082                 */
083                IN_CRITICAL_DPS_DANGER,
084                //MANEUVER_TARGET,
085                
086                
087                /**
088                 * Fighters only, attack run related. 
089                 */
090                IN_ATTACK_RUN,
091                POST_ATTACK_RUN,
092                WANTED_TO_SLOW_DOWN,
093                FINISHED_SPREADING,
094                WING_NEAR_ENEMY,
095                WING_WAS_NEAR_ENEMY,
096                WING_SHOULD_GET_SOME_DISTANCE,
097
098                
099                REACHED_WAYPOINT,
100                //ATTACK_RUN_WAYPOINT,
101                
102                
103                /**
104                 * Whether the ship wants to be escorted by nearby friendlies. 
105                 */
106                NEEDS_HELP,
107                
108                SYSTEM_TARGET_COORDS,
109                
110                BIGGEST_THREAT,
111                
112                MOVEMENT_DEST,
113                
114                HAS_POTENTIAL_MINE_TRIGGER_NEARBY,
115                
116                TARGET_FOR_SHIP_SYSTEM,
117                
118                CUSTOM1,
119                CUSTOM2,
120                CUSTOM3,
121                CUSTOM4,
122                CUSTOM5,
123        }
124        
125        public static final float FLAG_DURATION = 0.5f;
126        
127        private class FlagData {
128                AIFlags flag;
129                float elapsed;
130                float durationOverride = 0;
131                Object custom;
132                private FlagData(AIFlags flag) {
133                        super();
134                        this.flag = flag;
135                }
136        }
137        
138
139        private Map<AIFlags, FlagData> flags = new HashMap<AIFlags, FlagData>();
140        
141        public void unsetFlag(AIFlags flag) {
142//              if (flag == AIFlags.BACK_OFF) {
143//                      System.out.println("wefwefwefe");
144//              }
145                flags.remove(flag);
146        }
147        
148        public void setFlag(AIFlags flag) {
149//              if (flag == AIFlags.BACK_OFF) {
150//                      System.out.println("fwfwefew");
151//              }
152                FlagData data = flags.get(flag);
153                if (data != null) {
154                        data.elapsed = 0;
155                } else {
156                        flags.put(flag, new FlagData(flag));
157                }
158        }
159        
160        public void setFlag(AIFlags flag, float duration) {
161                setFlag(flag, duration, null);
162        }
163        
164        public void setFlag(AIFlags flag, float duration, Object custom) {
165//              if (flag == AIFlags.DO_NOT_BACK_OFF) {
166//                      System.out.println("fwfwefew");
167//              }
168                //if (flag == AIFlags.BACK_OFF) {
169//              if (flag == AIFlags.CARRIER_FIGHTER_TARGET) {
170//                      System.out.println("fwfwefew");
171//              }
172//              if (flag == AIFlags.BACK_OFF) {
173//                      System.out.println("fwfwefew");
174//              }
175//              if (flag == AIFlags.DO_NOT_USE_SHIELDS) {
176//                      System.out.println("fwfwefew");
177//              }
178                FlagData data = flags.get(flag);
179                if (data != null) {
180                        data.elapsed = 0;
181                        data.custom = custom;
182                } else {
183                        data = new FlagData(flag);
184                        data.durationOverride = duration;
185                        data.custom = custom;
186                        flags.put(flag, data);
187                }
188        }
189        
190        public Object getCustom(AIFlags flag) {
191                FlagData data = flags.get(flag);
192                if (data != null) {
193                        return data.custom;
194                }
195                return null;
196        }
197        
198        public void removeFlag(AIFlags flag) {
199//              if (flag == AIFlags.BACK_OFF) {
200//                      System.out.println("wefwefwefe");
201//              }
202                flags.remove(flag);
203        }
204        
205        public void advance(float amount) {
206                List<AIFlags> remove = new ArrayList<AIFlags>();
207                for (AIFlags flag : flags.keySet()) {
208                        FlagData data = flags.get(flag);
209                        data.elapsed += amount;
210                        //if (data.elapsed > FLAG_DURATION && data.elapsed > data.durationOverride) {
211                        if ((data.durationOverride <= 0 && data.elapsed > FLAG_DURATION) ||
212                                        (data.durationOverride > 0 && data.elapsed > data.durationOverride)) {
213                                remove.add(flag);
214                        }
215                }
216                for (AIFlags flag : remove) {
217//                      if (flag == AIFlags.BACK_OFF) {
218//                              System.out.println("wefwefwefe");
219//                      }
220                        flags.remove(flag);
221                }
222        }
223        
224        /**
225         * Checks whether a specific AI flag is set.
226         * This is how different ship AI modules communicate with each other, when they need to.
227         * @param flag
228         * @return
229         */
230        public boolean hasFlag(AIFlags flag) {
231                return flags.containsKey(flag);
232        }
233}
234
235
236
237
238
239
240
241