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