001package com.fs.starfarer.api.impl.campaign.abilities.ai;
002
003import org.lwjgl.util.vector.Vector2f;
004
005import com.fs.starfarer.api.Global;
006import com.fs.starfarer.api.campaign.CampaignFleetAPI;
007import com.fs.starfarer.api.campaign.FleetAssignment;
008import com.fs.starfarer.api.campaign.SectorEntityToken;
009import com.fs.starfarer.api.campaign.ai.FleetAIFlags;
010import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
011import com.fs.starfarer.api.campaign.rules.MemoryAPI;
012import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
013import com.fs.starfarer.api.util.IntervalUtil;
014import com.fs.starfarer.api.util.Misc;
015
016public class SustainedBurnAbilityAI extends BaseAbilityAI {
017
018        public static final float AI_FREQUENCY_MULT = 1f;
019        
020        private IntervalUtil interval = new IntervalUtil(0.05f, 0.15f);
021
022//      public EmergencyBurnAbilityAI(AbilityPlugin ability, ModularFleetAIAPI ai) {
023//              super(ability, ai);
024//      }
025
026        public void advance(float days) {
027                interval.advance(days * SustainedBurnAbilityAI.AI_FREQUENCY_MULT);
028                if (!interval.intervalElapsed()) return;
029                
030                MemoryAPI mem = fleet.getMemoryWithoutUpdate();
031                if (ability.isActiveOrInProgress()) {
032                        mem.set(FleetAIFlags.HAS_SPEED_BONUS, true, 0.2f);
033                        mem.set(FleetAIFlags.HAS_HIGHER_DETECTABILITY, true, 0.2f);
034                }
035                
036                boolean smuggler = mem.getBoolean(MemFlags.MEMORY_KEY_SMUGGLER);
037                if (smuggler) {
038                        if (ability.isActive()) ability.deactivate();
039                        return;
040                }
041                
042                
043                if (fleet.getAI() instanceof ModularFleetAIAPI) {
044                        ModularFleetAIAPI ai = (ModularFleetAIAPI) fleet.getAI();
045                        if (ai.getTacticalModule().isMaintainingContact()) {
046                                if (ability.isActive()) ability.deactivate();
047                                return;
048                        }
049                }
050                
051                if (mem.getBoolean(FleetAIFlags.HAS_LOWER_DETECTABILITY) && !ability.isActive()) {
052                        return;
053                }
054                
055//              if (true) {
056//                      if (!ability.isActive()) {
057//                              ability.activate();
058//                      } else {
059//                              ability.deactivate();
060//                      }
061//                      return;
062//              }
063//              if (fleet.getAI() != null && fleet.getAI().getCurrentAssignmentType() == FleetAssignment.STANDING_DOWN) {
064//                      return;
065//              }
066                
067                CampaignFleetAPI pursueTarget = mem.getFleet(FleetAIFlags.PURSUIT_TARGET);
068                CampaignFleetAPI fleeingFrom = mem.getFleet(FleetAIFlags.NEAREST_FLEEING_FROM);
069
070//              float moveDir = Misc.getDesiredMoveDir(fleet);
071                
072                float burn = Misc.getBurnLevelForSpeed(fleet.getVelocity().length());
073//              if (ability.isActive() && burn >= 5f) {
074//                      float diff = Misc.getAngleDiff(moveDir, Misc.getAngleInDegrees(fleet.getVelocity()));
075//                      if (diff > 90f) {
076//                              ability.deactivate();
077//                              return;
078//                      }
079//              }
080                
081                
082                float activationTime =  ability.getSpec().getActivationDays() * Global.getSector().getClock().getSecondsPerDay();
083                if (fleeingFrom != null) {
084                        float dist = Misc.getDistance(fleet.getLocation(), fleeingFrom.getLocation());
085                        float speed = Math.max(1f, fleeingFrom.getTravelSpeed());
086                        float time = dist / speed;
087                        if (!ability.isActive()) { // far enough to wind up and get away
088                                if (time >= activationTime + 5f) {
089                                        ability.activate();
090                                }
091                        } else { // too close to wind up, better chance of getting away by turning SB off
092                                if (burn <= 3 && time < 5f) {
093                                        ability.deactivate();
094                                }
095                        }
096                        return;
097                }
098                
099                if (pursueTarget != null) {
100//                      if (pursueTarget.isPlayerFleet()) {
101//                              System.out.println("fwefewwe");
102//                      }
103                        if (ability.isActive()) {
104                                float toTarget = Misc.getAngleInDegrees(fleet.getLocation(), pursueTarget.getLocation());
105                                float velDir = Misc.getAngleInDegrees(fleet.getVelocity());
106                                float diff = Misc.getAngleDiff(toTarget, velDir);
107                                if (diff > 60f) {
108                                        ability.deactivate();
109                                }
110                        }
111                        return;
112                }
113                
114                
115                if (fleet.getAI() != null && fleet.getAI().getCurrentAssignment() != null) {
116                         FleetAssignment curr = fleet.getAI().getCurrentAssignmentType();
117                         SectorEntityToken target = fleet.getAI().getCurrentAssignment().getTarget();
118                         boolean inSameLocation = target != null && target.getContainingLocation() == fleet.getContainingLocation();
119                         float distToTarget = 100000f;
120                         if (inSameLocation) {
121                                 distToTarget = Misc.getDistance(target.getLocation(), fleet.getLocation());
122                         }
123                         boolean close = distToTarget < 2000;
124                         
125                         if (close && 
126                                         (curr == FleetAssignment.ORBIT_PASSIVE ||
127                                          curr == FleetAssignment.ORBIT_AGGRESSIVE ||
128                                          curr == FleetAssignment.DELIVER_CREW ||
129                                          curr == FleetAssignment.DELIVER_FUEL ||
130                                          curr == FleetAssignment.DELIVER_MARINES ||
131                                          curr == FleetAssignment.DELIVER_PERSONNEL ||
132                                          curr == FleetAssignment.DELIVER_RESOURCES ||
133                                          curr == FleetAssignment.DELIVER_SUPPLIES ||
134                                          curr == FleetAssignment.RESUPPLY ||
135                                          curr == FleetAssignment.GO_TO_LOCATION ||
136                                          curr == FleetAssignment.GO_TO_LOCATION_AND_DESPAWN)
137                                          ) {
138                                 if (ability.isActive()) ability.deactivate();
139                                 return;
140                         }
141                         if (inSameLocation && (
142                                         curr == FleetAssignment.RAID_SYSTEM ||
143                                         curr == FleetAssignment.PATROL_SYSTEM)) {
144                                 if (ability.isActive()) ability.deactivate();
145                                 return;
146                         }
147                }
148                
149                
150                Vector2f travelDest = mem.getVector2f(FleetAIFlags.TRAVEL_DEST);
151                if (travelDest != null) {
152                        float dist = Misc.getDistance(fleet.getLocation(), travelDest);
153                        float speed = Math.max(1f, fleet.getTravelSpeed());
154                        float time = dist / speed;
155                        if (!ability.isActive()) {
156                                if (time > activationTime * 2f) {
157                                        ability.activate();
158                                }
159                        }
160                        return;
161                }
162                
163                
164                
165        }
166        
167        
168}
169
170
171
172
173
174