001package com.fs.starfarer.api.impl.campaign.abilities.ai;
002
003import org.lwjgl.util.vector.Vector2f;
004
005import com.fs.starfarer.api.campaign.CampaignFleetAPI;
006import com.fs.starfarer.api.campaign.ai.FleetAIFlags;
007import com.fs.starfarer.api.campaign.econ.MarketAPI;
008import com.fs.starfarer.api.campaign.rules.MemoryAPI;
009import com.fs.starfarer.api.impl.campaign.abilities.GoDarkAbility;
010import com.fs.starfarer.api.impl.campaign.events.BaseEventPlugin.MarketFilter;
011import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
012import com.fs.starfarer.api.util.IntervalUtil;
013import com.fs.starfarer.api.util.Misc;
014
015public class GoDarkAbilityAI extends BaseAbilityAI {
016
017        private IntervalUtil interval = new IntervalUtil(0.05f, 0.15f);
018
019//      public GoDarkAbilityAI(AbilityPlugin ability, ModularFleetAIAPI ai) {
020//              super(ability, ai);
021//      }
022
023        public void advance(float days) {
024                interval.advance(days * EmergencyBurnAbilityAI.AI_FREQUENCY_MULT);
025                if (!interval.intervalElapsed()) return;
026                
027                
028                MemoryAPI mem = fleet.getMemoryWithoutUpdate();
029                
030                
031                if (ability.isActiveOrInProgress()) {
032                        mem.set(FleetAIFlags.HAS_SPEED_PENALTY, true, 0.2f);
033                        mem.set(FleetAIFlags.HAS_LOWER_DETECTABILITY, true, 0.2f);
034                }
035                
036                CampaignFleetAPI pursueTarget = mem.getFleet(FleetAIFlags.PURSUIT_TARGET);
037                CampaignFleetAPI fleeingFrom = mem.getFleet(FleetAIFlags.NEAREST_FLEEING_FROM);
038                Vector2f travelDest = mem.getVector2f(FleetAIFlags.TRAVEL_DEST);
039                boolean wantsTransponderOn = mem.getBoolean(FleetAIFlags.WANTS_TRANSPONDER_ON);
040                
041//              if (pursueTarget != null && pursueTarget.isPlayerFleet() && fleeingFrom != null) {
042//                      System.out.println("dfsdfwefwe");
043//              }
044                
045                // if being pursued
046                if (fleeingFrom != null) {
047                        float dist = Misc.getDistance(fleet.getLocation(), fleeingFrom.getLocation()) - fleet.getRadius() - fleeingFrom.getRadius();
048                        if (dist < 0) return;
049                        float detRange = fleeingFrom.getMaxSensorRangeToDetect(fleet);
050                        float ourSpeed = fleet.getFleetData().getBurnLevel();
051                        float theirSpeed = fleeingFrom.getFleetData().getBurnLevel();
052                        // slower than closest pursuer, but could hide using go dark: do it
053                        if (!ability.isActiveOrInProgress()) {
054                                if (dist > detRange * GoDarkAbility.DETECTABILITY_MULT + 100f && ourSpeed < theirSpeed &&
055                                                dist > detRange && dist < detRange + 300f) {
056                                        ability.activate();
057                                }
058                        } else { // already seen by them, or faster than them with "go dark" off
059                                //if (dist < detRange || ourSpeed / GoDarkAbility.MAX_BURN_MULT  > theirSpeed) {
060                                // since going dark means "slow moving", ourSpeed doesn't actually include that, so it's still
061                                // as if go dark was turned off
062                                if (dist < detRange || ourSpeed > theirSpeed) {
063                                        ability.deactivate();
064                                }
065                        }
066                        return;
067                }
068                
069                // if wants to use transponder & not being pursued, don't do it
070                //if (wantsTransponderOn) {
071                if (fleet.isTransponderOn()) {
072                        return;
073                }
074                
075//              if (pursueTarget != null && pursueTarget.isPlayerFleet()) {
076//                      System.out.println("dfsdfwefwe");
077//              }
078                
079                // if ok with using it, and not being pursued
080                // if pursuing, target can't see us, and we're gaining: leave on
081                // if pursuing, target can see us or we're losing groung: turn off
082                if (pursueTarget != null) {
083                        float closingSpeed = Misc.getClosingSpeed(fleet.getLocation(), pursueTarget.getLocation(), 
084                                                                                                          fleet.getVelocity(),pursueTarget.getVelocity());
085                        if (closingSpeed <= 1 && ability.isActiveOrInProgress()) {
086                                ability.deactivate();
087                        }
088                        return;
089                }
090                
091                // is the destination nearby? turn on
092                boolean smuggler = mem.getBoolean(MemFlags.MEMORY_KEY_SMUGGLER);
093                boolean pirate = mem.getBoolean(MemFlags.MEMORY_KEY_PIRATE);
094                // don't use for general pirates; too grief-y
095                pirate = false;
096                
097                boolean nearestMarketHostile = false;
098                MarketAPI nearestMarket = Misc.findNearestLocalMarket(fleet, 2000, new MarketFilter() {
099                        public boolean acceptMarket(MarketAPI market) {
100                                return true;
101                        }
102                });
103                if (nearestMarket != null && nearestMarket.getFaction().isHostileTo(fleet.getFaction())) {
104                        nearestMarketHostile = true;
105                }
106                
107                if ((smuggler || pirate || nearestMarketHostile) && !ability.isActiveOrInProgress() && travelDest != null) {
108                        float dist = Misc.getDistance(fleet.getLocation(), travelDest);
109                        if (dist < 1500) {
110                                ability.activate();
111                        }
112                        return;
113                }
114        }
115}
116
117
118
119
120
121