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}