001package com.fs.starfarer.api.impl.campaign;
002
003import java.util.List;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.EveryFrameScript;
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.Script;
010import com.fs.starfarer.api.campaign.CampaignFleetAPI;
011import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
012import com.fs.starfarer.api.campaign.FleetAssignment;
013import com.fs.starfarer.api.campaign.SectorEntityToken;
014import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
015import com.fs.starfarer.api.campaign.ai.FleetAssignmentDataAPI;
016import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
017import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
018import com.fs.starfarer.api.impl.campaign.ids.Tags;
019import com.fs.starfarer.api.util.IntervalUtil;
020import com.fs.starfarer.api.util.Misc;
021
022public class CargoPodsResponse implements EveryFrameScript {
023        
024        public static String PODS_BUSY_REASON = "pods";
025        
026        
027        protected IntervalUtil tracker = new IntervalUtil(0.05f, 0.15f);
028        protected float elapsed;
029        protected CustomCampaignEntityAPI pods;
030        
031        public CargoPodsResponse(CustomCampaignEntityAPI pods) {
032                this.pods = pods;
033        }
034
035        public void advance(float amount) {
036                float days = Global.getSector().getClock().convertToDays(amount);
037                tracker.advance(days);
038                
039                elapsed += days;
040                
041                
042                if (tracker.intervalElapsed()) {
043                        checkResponse();
044                }
045        }
046
047        public boolean isDone() {
048                return elapsed >= 3f || !pods.isAlive() || pods.hasTag(Tags.NON_CLICKABLE);
049        }
050
051        public boolean runWhilePaused() {
052                return false;
053        }
054
055        
056        public void checkResponse() {
057                List<CampaignFleetAPI> fleets = pods.getContainingLocation().getFleets();
058                
059                CampaignFleetAPI closest = null;
060                float minDist = Float.MAX_VALUE;
061                
062                for (CampaignFleetAPI fleet : fleets) {
063                        if (!couldInvestigatePods(fleet)) continue;
064                        
065                        float dist = Misc.getDistance(pods, fleet);
066                        if (dist < minDist) {
067                                minDist = dist;
068                                closest = fleet;
069                        }
070                }
071                
072                if (closest != null && minDist < 500f) {
073                        respond(closest);
074                        elapsed = 10f; // make it "done"
075                }
076        }
077        
078        protected float getBaseDur(CampaignFleetAPI fleet) {
079                float dur = pods.getCargo().getFuel() + pods.getCargo().getSpaceUsed() + pods.getCargo().getTotalPersonnel();
080                dur = dur / fleet.getCargo().getMaxCapacity();
081                
082                return dur;
083        }
084
085        
086        protected void respond(final CampaignFleetAPI fleet) {
087                unrespond(fleet);
088                
089                //float dur = (1.5f + (float) Math.random());
090                float dur = getBaseDur(fleet);
091                dur *= 5f;
092                if (dur > 1f) dur = 1f;
093                
094                Misc.setFlagWithReason(fleet.getMemoryWithoutUpdate(), 
095                                                                MemFlags.FLEET_BUSY, PODS_BUSY_REASON, true, dur);
096                
097                Vector2f loc = Misc.getUnitVectorAtDegreeAngle(
098                                Misc.getAngleInDegrees(pods.getLocation(), fleet.getLocation()));
099                loc.scale(fleet.getRadius() + pods.getRadius());
100                Vector2f.add(loc, pods.getLocation(), loc);
101                final SectorEntityToken holdLoc = pods.getContainingLocation().createToken(loc);
102                
103                fleet.addAssignmentAtStart(FleetAssignment.HOLD, holdLoc, dur, "investigating " + pods.getName().toLowerCase(), 
104                                new Script() {
105                                        public void run() {
106                                                Misc.fadeAndExpire(pods);
107                                                fleet.getCargo().addAll(pods.getCargo());
108                                                pods.getCargo().clear();
109                                        }
110                                });
111                FleetAssignmentDataAPI curr = fleet.getCurrentAssignment();
112                if (curr != null) {
113                        curr.setCustom(MilitaryResponseScript.RESPONSE_ASSIGNMENT);
114                }
115                fleet.addScript(new EveryFrameScript() {
116                        private boolean done = false;
117                        public boolean runWhilePaused() {
118                                return false;
119                        }
120                        public boolean isDone() {
121                                return done || !Misc.isBusy(fleet) || pods.hasTag(Tags.NON_CLICKABLE) || !pods.isAlive();
122                        }
123                        public void advance(float amount) {
124                                Vector2f loc = Misc.getUnitVectorAtDegreeAngle(
125                                                Misc.getAngleInDegrees(pods.getLocation(), fleet.getLocation()));
126                                loc.scale(fleet.getRadius() + pods.getRadius());
127                                Vector2f.add(loc, pods.getLocation(), loc);
128                                holdLoc.setLocation(loc.x, loc.y);
129                                
130                                if (!pods.isAlive()) {
131                                        if (Misc.isBusy(fleet)) {
132                                                unrespond(fleet);
133                                        }
134                                        done = true;
135                                }
136                        }
137                });
138        }
139        
140        protected void unrespond(CampaignFleetAPI fleet) {
141                Misc.setFlagWithReason(fleet.getMemoryWithoutUpdate(), 
142                                                           MemFlags.FLEET_BUSY, PODS_BUSY_REASON, false, 0f);
143                for (FleetAssignmentDataAPI curr : fleet.getAI().getAssignmentsCopy()) {
144                        if (MilitaryResponseScript.RESPONSE_ASSIGNMENT.equals(curr.getCustom())) {
145                                fleet.getAI().removeAssignment(curr);
146                        }
147                }
148        }
149        
150        protected boolean couldInvestigatePods(CampaignFleetAPI fleet) {
151                //if (fleet.getFaction() != params.faction) return false;
152                if (fleet.getAI() == null) return false;
153                if (fleet.isPlayerFleet()) return false;
154                
155                if (!fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.MEMORY_KEY_PIRATE)) return false;
156                
157                if (fleet.getBattle() != null) return false;
158                if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.FLEET_BUSY)) return false;
159                
160                if (fleet.getAI() instanceof ModularFleetAIAPI) {
161                        ModularFleetAIAPI ai = (ModularFleetAIAPI) fleet.getAI();
162                        if (ai.getAssignmentModule().areAssignmentsFrozen()) return false;
163                        if (ai.isFleeing() || ai.isMaintainingContact()) return false;
164                        if (ai.isCurrentAssignment(FleetAssignment.INTERCEPT)) return false;
165                }
166                
167                
168                VisibilityLevel level = pods.getVisibilityLevelTo(fleet);
169                if (level == VisibilityLevel.NONE) return false;
170                
171                if (fleet.getCurrentAssignment() != null && 
172                                fleet.getCurrentAssignment().getAssignment() == FleetAssignment.GO_TO_LOCATION_AND_DESPAWN) {
173                        return false;
174                }
175                
176                float dur = getBaseDur(fleet);
177                if (dur < 0.05f) return false;
178                
179                //MemoryAPI memory = fleet.getMemoryWithoutUpdate();
180//              boolean patrol = memory.getBoolean(MemFlags.MEMORY_KEY_PATROL_FLEET);
181//              boolean noMilitary = memory.getBoolean(MemFlags.FLEET_NO_MILITARY_RESPONSE);
182//              if (!patrol || noMilitary) return false;
183                
184                return true;
185        }
186        
187        
188        
189
190}