Starsector API
Loading...
Searching...
No Matches
PEActionStage.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.intel.punitive;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.List;
6
7import com.fs.starfarer.api.Global;
8import com.fs.starfarer.api.campaign.CampaignFleetAPI;
9import com.fs.starfarer.api.campaign.SectorEntityToken;
10import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.ActionType;
11import com.fs.starfarer.api.campaign.econ.Industry;
12import com.fs.starfarer.api.campaign.econ.MarketAPI;
13import com.fs.starfarer.api.impl.campaign.DebugFlags;
14import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript;
15import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript.MilitaryResponseParams;
16import com.fs.starfarer.api.impl.campaign.command.WarSimScript;
17import com.fs.starfarer.api.impl.campaign.econ.impl.OrbitalStation;
18import com.fs.starfarer.api.impl.campaign.fleets.RouteManager;
19import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
20import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteSegment;
21import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
22import com.fs.starfarer.api.impl.campaign.intel.punitive.PunitiveExpeditionIntel.PunExOutcome;
23import com.fs.starfarer.api.impl.campaign.intel.punitive.PunitiveExpeditionManager.PunExGoal;
24import com.fs.starfarer.api.impl.campaign.intel.raid.ActionStage;
25import com.fs.starfarer.api.impl.campaign.intel.raid.RaidIntel.RaidStageStatus;
26import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseAssignmentAI.FleetActionDelegate;
27import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD;
28import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.BombardType;
29import com.fs.starfarer.api.ui.TooltipMakerAPI;
30import com.fs.starfarer.api.util.Misc;
31
32public class PEActionStage extends ActionStage implements FleetActionDelegate {
33
34 protected MarketAPI target;
35 protected boolean playerTargeted = false;
36 protected List<MilitaryResponseScript> scripts = new ArrayList<MilitaryResponseScript>();
37 protected boolean gaveOrders = true; // will be set to false in updateRoutes()
38 protected float untilAutoresolve = 30f;
39
41 super(raid);
42 this.target = target;
44
45 untilAutoresolve = 15f + 5f * (float) Math.random();
46 }
47
48
49 @Override
50 public void advance(float amount) {
51 super.advance(amount);
52
53 float days = Misc.getDays(amount);
54 untilAutoresolve -= days;
56 untilAutoresolve -= days * 100f;
57 }
58
59 if (!gaveOrders) {
60 gaveOrders = true;
61
63
64 // getMaxDays() is always 1 here
65 // scripts get removed anyway so we don't care about when they expire naturally
66 // just make sure they're around for long enough
67 float duration = 100f;
68
69 MilitaryResponseParams params = new MilitaryResponseParams(ActionType.HOSTILE,
70 "PE_" + Misc.genUID() + target.getId(),
73 1f,
74 duration);
77 scripts.add(script);
78
79 MilitaryResponseParams defParams = new MilitaryResponseParams(ActionType.HOSTILE,
80 "defPE_" + Misc.genUID() + target.getId(),
83 1f,
84 duration);
85 MilitaryResponseScript defScript = new MilitaryResponseScript(defParams);
87 scripts.add(defScript);
88 }
89 }
90
91 protected void removeMilScripts() {
92 if (scripts != null) {
94 s.forceDone();
95 }
96 }
97 }
98
99 @Override
100 protected void updateStatus() {
101// if (true) {
102// status = RaidStageStatus.SUCCESS;
103// return;
104// }
105
107 if (status != RaidStageStatus.ONGOING) return;
108
110 if (!inSpawnRange && untilAutoresolve <= 0){
111 autoresolve();
112 return;
113 }
114
115 if (!target.isInEconomy() || !target.isPlayerOwned()) {
116 status = RaidStageStatus.FAILURE;
119 return;
120 }
121
122 }
123
124 public String getRaidActionText(CampaignFleetAPI fleet, MarketAPI market) {
126 PunExGoal goal = intel.getGoal();
127 if (goal == PunExGoal.BOMBARD) {
128 return "bombarding " + market.getName();
129 }
130 return "raiding " + market.getName();
131 }
132
133 public String getRaidApproachText(CampaignFleetAPI fleet, MarketAPI market) {
135 PunExGoal goal = intel.getGoal();
136 if (goal == PunExGoal.BOMBARD) {
137 return "moving in to bombard " + market.getName();
138 }
139 return "moving in to raid " + market.getName();
140 }
141
142 public void performRaid(CampaignFleetAPI fleet, MarketAPI market) {
144
146 PunExGoal goal = intel.getGoal();
147
148 status = RaidStageStatus.SUCCESS;
149
150 if (goal == PunExGoal.BOMBARD) {
151 float cost = MarketCMD.getBombardmentCost(market, fleet);
152 //float maxCost = intel.getAssembleStage().getOrigSpawnFP() * Misc.FP_TO_BOMBARD_COST_APPROX_MULT;
154 if (fleet != null) {
155 maxCost = fleet.getCargo().getMaxFuel() * 0.25f;
156 }
157
158 if (cost <= maxCost) {
159 new MarketCMD(market.getPrimaryEntity()).doBombardment(intel.getFaction(), BombardType.SATURATION);
160 intel.setOutcome(PunExOutcome.SUCCESS);
161 } else {
162 intel.setOutcome(PunExOutcome.BOMBARD_FAIL);
163 status = RaidStageStatus.FAILURE;
164
166 intel.getFaction().getId(), true, 30f);
167 }
168 } else {
169 //float str = intel.getAssembleStage().getOrigSpawnFP() * Misc.FP_TO_GROUND_RAID_STR_APPROX_MULT;
171
172 if (fleet != null) str = MarketCMD.getRaidStr(fleet);
173 //float re = MarketCMD.getRaidEffectiveness(target, str);
174
175 //str = 10f;
176
177 float durMult = Global.getSettings().getFloat("punitiveExpeditionDisruptDurationMult");
178 boolean raidSuccess = new MarketCMD(market.getPrimaryEntity()).doIndustryRaid(intel.getFaction(), str, intel.targetIndustry, durMult);
179
180 if (raidSuccess) {
181 intel.setOutcome(PunExOutcome.SUCCESS);
182 } else {
183 intel.setOutcome(PunExOutcome.RAID_FAIL);
184 status = RaidStageStatus.FAILURE;
185
187 intel.getFaction().getId(), true, 30f);
188 Misc.setRaidedTimestamp(market);
189 }
190 }
191
192// // so it doesn't keep trying to raid/bombard
193// if (fleet != null) {
194// fleet.getMemoryWithoutUpdate().unset(MemFlags.MEMORY_KEY_RAIDER);
195// }
196
197 // when FAILURE, gets sent by RaidIntel
198 if (intel.getOutcome() != null) {
199 if (status == RaidStageStatus.SUCCESS) {
200 intel.sendOutcomeUpdate();
201 } else {
204 }
205 }
206 }
207
208
209 protected void autoresolve() {
212
213 float defensiveStr = enemyStr + WarSimScript.getStationStrength(target.getFaction(),
215 if (defensiveStr >= str) {
216 status = RaidStageStatus.FAILURE;
219
220 // not strictly necessary, I think, but shouldn't hurt
221 // otherwise would get set in PunitiveExpeditionIntel.notifyRaidEnded()
223 intel.setOutcome(PunExOutcome.TASK_FORCE_DEFEATED);
224 return;
225 }
226
228 if (station != null) {
229 OrbitalStation.disrupt(station);
230 }
231
232 performRaid(null, target);
233 }
234
235
236 protected void updateRoutes() {
237 resetRoutes();
238
239 gaveOrders = false;
240
241 ((PunitiveExpeditionIntel)intel).sendEnteredSystemUpdate();
242
244 for (RouteData route : routes) {
245 if (target.getStarSystem() != null) { // so that fleet may spawn NOT at the target
246 route.addSegment(new RouteSegment(Math.min(5f, untilAutoresolve), target.getStarSystem().getCenter()));
247 }
248 route.addSegment(new RouteSegment(1000f, target.getPrimaryEntity()));
249 }
250 }
251
252
253 public void showStageInfo(TooltipMakerAPI info) {
254 int curr = intel.getCurrentStage();
255 int index = intel.getStageIndex(this);
256
257 Color h = Misc.getHighlightColor();
258 Color g = Misc.getGrayColor();
259 Color tc = Misc.getTextColor();
260 float pad = 3f;
261 float opad = 10f;
262
263 if (curr < index) return;
264
265 if (status == RaidStageStatus.ONGOING && curr == index) {
266 info.addPara("The expedition forces are currently in-system.", opad);
267 return;
268 }
269
271 if (intel.getOutcome() != null) {
272 switch (intel.getOutcome()) {
273 case BOMBARD_FAIL:
274 info.addPara("The ground defenses of " + target.getName() + " were sufficient to prevent bombardment.", opad);
275 break;
276 case RAID_FAIL:
277 info.addPara("The raiding forces have been repelled by the ground defenses of " + target.getName() + ".", opad);
278 break;
279 case SUCCESS:
280 if (intel.goal == PunExGoal.BOMBARD) {
281 if (!target.isInEconomy()) {
282 info.addPara("The expeditionary force has successfully bombarded " + target.getName() + ", destroying the colony outright.", opad);
283 } else {
284 info.addPara("The expeditionary force has successfully bombarded " + target.getName() + ".", opad);
285 }
286 } else if (intel.getTargetIndustry() != null) {
287 info.addPara("The expeditionary force has disrupted " +
288 intel.getTargetIndustry().getCurrentName() + " operations for %s days.",
289 opad, h, "" + (int)Math.round(intel.getTargetIndustry().getDisruptedDays()));
290 }
291 break;
292 case TASK_FORCE_DEFEATED:
293 info.addPara("The expeditionary force has been defeated by the defenders of " +
294 target.getName() + ".", opad);
295 break;
296 case COLONY_NO_LONGER_EXISTS:
297 info.addPara("The expedition has been aborted.", opad);
298 break;
299
300 }
301 } else if (status == RaidStageStatus.SUCCESS) {
302 info.addPara("The expeditionary force has succeeded.", opad); // shouldn't happen?
303 } else {
304 info.addPara("The expeditionary force has failed.", opad); // shouldn't happen?
305 }
306 }
307
308 public boolean canRaid(CampaignFleetAPI fleet, MarketAPI market) {
310 if (intel.getOutcome() != null) return false;
311 return market == target;
312 }
313
315 return "orbiting " + from.getName();
316 }
317
319 return "traveling";
320 }
321
323 return "traveling";
324 }
325
326 @Override
327 public boolean isPlayerTargeted() {
328 return playerTargeted;
329 }
330}
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
static SettingsAPI getSettings()
Definition Global.java:57
static float getFactionStrength(String factionId, StarSystemAPI system)
static float getStationStrength(FactionAPI faction, StarSystemAPI system, SectorEntityToken from)
static boolean isPlayerInSpawnRange(SectorEntityToken from)
String getRaidApproachText(CampaignFleetAPI fleet, MarketAPI market)
String getRaidPrepText(CampaignFleetAPI fleet, SectorEntityToken from)
void performRaid(CampaignFleetAPI fleet, MarketAPI market)
PEActionStage(PunitiveExpeditionIntel raid, MarketAPI target)
String getRaidActionText(CampaignFleetAPI fleet, MarketAPI market)
boolean canRaid(CampaignFleetAPI fleet, MarketAPI market)
void giveReturnOrdersToStragglers(List< RouteData > stragglers)
boolean doIndustryRaid(FactionAPI faction, float attackerStr, Industry industry, float durMult)
void doBombardment(FactionAPI faction, BombardType type)
static int getBombardmentCost(MarketAPI market, CampaignFleetAPI fleet)
static Color getTextColor()
Definition Misc.java:839
static float FP_TO_GROUND_RAID_STR_APPROX_MULT
Definition Misc.java:227
static Color getGrayColor()
Definition Misc.java:826
static float getDays(float amount)
Definition Misc.java:4663
static Color getHighlightColor()
Definition Misc.java:792
static boolean setFlagWithReason(MemoryAPI memory, String flagKey, String reason, boolean value, float expire)
Definition Misc.java:1439
static Industry getStationIndustry(MarketAPI market)
Definition Misc.java:4617
static float FP_TO_BOMBARD_COST_APPROX_MULT
Definition Misc.java:226
static void setRaidedTimestamp(MarketAPI market)
Definition Misc.java:5816
void addScript(EveryFrameScript script)
LabelAPI addPara(String format, float pad, Color hl, String... highlights)