Starsector API
Loading...
Searching...
No Matches
MilitaryResponseScript.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign;
2
3import java.util.List;
4
5import com.fs.starfarer.api.EveryFrameScript;
6import com.fs.starfarer.api.Global;
7import com.fs.starfarer.api.campaign.CampaignFleetAPI;
8import com.fs.starfarer.api.campaign.FactionAPI;
9import com.fs.starfarer.api.campaign.FleetAssignment;
10import com.fs.starfarer.api.campaign.SectorEntityToken;
11import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.ActionType;
12import com.fs.starfarer.api.campaign.ai.FleetAssignmentDataAPI;
13import com.fs.starfarer.api.campaign.ai.ModularFleetAIAPI;
14import com.fs.starfarer.api.campaign.rules.MemoryAPI;
15import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
16import com.fs.starfarer.api.util.IntervalUtil;
17import com.fs.starfarer.api.util.Misc;
18
20
21 public static String RESPONSE_ASSIGNMENT = "response"; // custom value added to assignments so we know which to clear
22
23 public static class MilitaryResponseParams {
24 public ActionType type;
25 public String responseReason;
26 public FactionAPI faction;
27
28 public SectorEntityToken actor;
29 public SectorEntityToken target;
30 public float responseFraction;
31 public float responseDuration;
32 public String travelText;
33 public String actionText;
34
35 public MilitaryResponseParams(ActionType type, String responseReason,
36 FactionAPI faction, SectorEntityToken target,
37 float responseFraction, float responseDuration) {
38 this.type = type;
39 this.responseReason = responseReason;
40 this.faction = faction;
41 this.target = target;
42 this.responseFraction = responseFraction;
43 this.responseDuration = responseDuration;
44 }
45
46
47 }
48
49
50 protected IntervalUtil tracker = new IntervalUtil(0.05f, 0.15f);
51 protected MilitaryResponseParams params;
52 protected float elapsed;
53
54 public MilitaryResponseScript(MilitaryResponseParams params) {
55 this.params = params;
58 }
59
60 public void advance(float amount) {
61 float days = Global.getSector().getClock().convertToDays(amount);
62 tracker.advance(days);
63
64 elapsed += days;
65
66
67// if (params != null) {
68// System.out.println("MRS: " + params.responseReason);
69// } else {
70// System.out.println("NULL MRS params");
71// }
72
73 if (tracker.intervalElapsed()) {
75 }
76 }
77
78
79 public void initiateResponse() {
80 if (params.target.getContainingLocation() == null) return;
81// if (params.faction.getId().equals(Factions.PIRATES) && params.target.isInCurrentLocation()) {
82// System.out.println("wefwefwe");
83// }
84 List<CampaignFleetAPI> fleets = params.target.getContainingLocation().getFleets();
85 for (CampaignFleetAPI fleet : fleets) {
87 }
88 }
89
90 protected boolean isTemporarilyNotResponding(CampaignFleetAPI fleet) {
91 if (fleet.getBattle() != null) return true;
92
93 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.FLEET_BUSY)) return true;
94 FleetAssignmentDataAPI curr = fleet.getCurrentAssignment();
95 if (curr != null && curr.getAssignment() == FleetAssignment.STANDING_DOWN) return true;
96
97 MemoryAPI memory = fleet.getMemoryWithoutUpdate();
98 if (memory.getBoolean(MemFlags.FLEET_MILITARY_RESPONSE)) return true;
99
100 return false;
101 }
102
103 protected void seeIfFleetShouldRespond(CampaignFleetAPI fleet) {
104// if (fleet.getContainingLocation() == Global.getSector().getCurrentLocation()) {
105// System.out.println("fwefwef");
106// }
107
108 if (!couldRespond(fleet)) return;
109
110 if (isTemporarilyNotResponding(fleet)) return;
111
112 List<CampaignFleetAPI> fleets = params.target.getContainingLocation().getFleets();
113 float potentialFP = 0;
114 float respondingFP = 0f;
115
116 float closestDist = Float.MAX_VALUE;
117 CampaignFleetAPI closestNonResponder = null;
118
119 for (CampaignFleetAPI other : fleets) {
120 if (!couldRespond(other)) continue;
121
122 float fp = other.getFleetPoints();
123
124 potentialFP += fp;
125 boolean responding = isResponding(other);
126 if (responding) {
127 respondingFP += fp;
128 }
129
130 //if (other == fleet) continue;
131
132 if (!responding && !isTemporarilyNotResponding(other)) {
133 float distOther = Misc.getDistance(params.target, other);
134 if (distOther < closestDist) {
135 closestDist = distOther;
136 closestNonResponder = other;
137 }
138 }
139 }
140
141 float fraction = params.responseFraction / getResponseTotal();
142
143 //float dist = Misc.getDistance(params.target, fleet);
144 if (potentialFP > 0 &&
145 respondingFP / potentialFP < fraction &&
146 closestNonResponder == fleet) {
147
148 respond(fleet);
149 }
150 }
151
152 protected void respond(CampaignFleetAPI fleet) {
153 unrespond(fleet);
154
155// if (fleet.getContainingLocation() != null && fleet.getContainingLocation().getName().startsWith("Corvus")) {
156// System.out.println("fwefwe");
157// }
158 //fleet.getAssignmentsCopy().get(0)
159 Misc.setFlagWithReason(fleet.getMemoryWithoutUpdate(),
160 MemFlags.FLEET_MILITARY_RESPONSE, params.responseReason, true, (1.5f + (float) Math.random()) * 0.2f);
161
162 fleet.addAssignmentAtStart(FleetAssignment.PATROL_SYSTEM, params.target, 3f, params.actionText, null);
163 FleetAssignmentDataAPI curr = fleet.getCurrentAssignment();
164 if (curr != null) {
165 curr.setCustom(RESPONSE_ASSIGNMENT);
166 }
167
168 float dist = Misc.getDistance(params.target, fleet);
169 if (dist > 2000f) {
170 fleet.addAssignmentAtStart(FleetAssignment.GO_TO_LOCATION, params.target, 3f, params.travelText, null);
171 //fleet.addAssignmentAtStart(FleetAssignment.DELIVER_CREW, params.target, 3f, params.travelText, null);
172 curr = fleet.getCurrentAssignment();
173 if (curr != null) {
174 curr.setCustom(RESPONSE_ASSIGNMENT);
175 }
176 }
177
178 //Global.getSector().addPing(fleet, Pings.DANGER);
179 }
180
181 protected void unrespond(CampaignFleetAPI fleet) {
182 Misc.setFlagWithReason(fleet.getMemoryWithoutUpdate(),
183 MemFlags.FLEET_MILITARY_RESPONSE, params.responseReason, false, 0f);
184 boolean firstOrbitPassive = true;
185 for (FleetAssignmentDataAPI curr : fleet.getAI().getAssignmentsCopy()) {
186 if (RESPONSE_ASSIGNMENT.equals(curr.getCustom())) {
187 fleet.getAI().removeAssignment(curr);
188 } else if (curr.getAssignment() == FleetAssignment.ORBIT_PASSIVE && firstOrbitPassive) {
189 // "preparing for patrol" or some such, very likely - don't want to go back to that
190 // after the response is done
191 fleet.getAI().removeAssignment(curr);
192 firstOrbitPassive = false;
193 }
194 }
195 }
196
197 protected boolean isResponding(CampaignFleetAPI fleet) {
198 return Misc.flagHasReason(fleet.getMemoryWithoutUpdate(), MemFlags.FLEET_MILITARY_RESPONSE, params.responseReason);
199 }
200
201 protected boolean couldRespond(CampaignFleetAPI fleet) {
202 if (fleet.getFaction() != params.faction) return false;
203 if (fleet.getAI() == null) return false;
204 if (fleet.isPlayerFleet()) return false;
205 if (fleet.isStationMode()) return false;
206
207 // don't check for this here as it would skew proportiions of what's assigned where if a fleet is busy for a bit
208 //if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.FLEET_BUSY)) return false;
209
210 if (fleet.getAI() instanceof ModularFleetAIAPI) {
211 ModularFleetAIAPI ai = (ModularFleetAIAPI) fleet.getAI();
212 if (ai.getAssignmentModule().areAssignmentsFrozen()) return false;
213 }
214
215 if (fleet.getCurrentAssignment() != null &&
216 fleet.getCurrentAssignment().getAssignment() == FleetAssignment.GO_TO_LOCATION_AND_DESPAWN) {
217 return false;
218 }
219
220 MemoryAPI memory = fleet.getMemoryWithoutUpdate();
221
222 boolean patrol = memory.getBoolean(MemFlags.MEMORY_KEY_PATROL_FLEET);
223 boolean warFleet = memory.getBoolean(MemFlags.MEMORY_KEY_WAR_FLEET);
224 boolean pirate = memory.getBoolean(MemFlags.MEMORY_KEY_PIRATE);
225 boolean noMilitary = memory.getBoolean(MemFlags.FLEET_NO_MILITARY_RESPONSE);
226 if (!(patrol || warFleet || pirate) || noMilitary) return false;
227
228 return true;
229 }
230
231 protected String getResponseTotalKey() {
232 return "$mrs_" + params.responseReason;
233 }
234
235 protected void addToResponseTotal() {
236 MemoryAPI memory = params.faction.getMemoryWithoutUpdate();
237 String key = getResponseTotalKey();
238
239 float curr = memory.getFloat(key);
240 memory.set(key, curr + params.responseFraction, 60f);
241 }
242
243 protected void removeFromResponseTotal() {
244 MemoryAPI memory = params.faction.getMemoryWithoutUpdate();
245 String key = getResponseTotalKey();
246
247 float curr = memory.getFloat(key);
248 if (curr > params.responseFraction) {
249 memory.set(key, Math.max(0, curr - params.responseFraction), 60f);
250 } else {
251 memory.unset(key);
252 }
253 }
254
255 protected float getResponseTotal() {
256 MemoryAPI memory = params.faction.getMemoryWithoutUpdate();
257 String key = getResponseTotalKey();
258
259 float curr = memory.getFloat(key);
260 if (curr < params.responseFraction) curr = params.responseFraction;
261 if (curr < 1) curr = 1;
262 return curr;
263 }
264
265 public void forceDone() {
266 if (params != null) {
267 elapsed = params.responseDuration;
268 }
269 }
270
271 public boolean isDone() {
272 if (params == null || elapsed >= params.responseDuration) {
274 params = null;
275 return true;
276 }
277 return false;
278 }
279
280 public boolean runWhilePaused() {
281 return false;
282 }
283
284 public MilitaryResponseParams getParams() {
285 return params;
286 }
287
288 public float getElapsed() {
289 return elapsed;
290 }
291
292 public void setElapsed(float elapsed) {
293 this.elapsed = elapsed;
294 }
295
296
297
298}
static SectorAPI getSector()
Definition Global.java:59