1package com.fs.starfarer.api.impl.campaign.rulecmd.salvage;
4import java.util.ArrayList;
7import java.util.Random;
9import org.lwjgl.input.Keyboard;
10import org.lwjgl.util.vector.Vector2f;
12import com.fs.starfarer.api.EveryFrameScript;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.BattleAPI;
15import com.fs.starfarer.api.campaign.BattleAPI.BattleSide;
16import com.fs.starfarer.api.campaign.CampaignFleetAPI;
17import com.fs.starfarer.api.campaign.CargoAPI;
18import com.fs.starfarer.api.campaign.CoreInteractionListener;
19import com.fs.starfarer.api.campaign.FactionAPI;
20import com.fs.starfarer.api.campaign.GroundRaidTargetPickerDelegate;
21import com.fs.starfarer.api.campaign.InteractionDialogAPI;
22import com.fs.starfarer.api.campaign.InteractionDialogPlugin;
23import com.fs.starfarer.api.campaign.OptionPanelAPI;
24import com.fs.starfarer.api.campaign.RepLevel;
25import com.fs.starfarer.api.campaign.RuleBasedDialog;
26import com.fs.starfarer.api.campaign.SectorEntityToken;
27import com.fs.starfarer.api.campaign.TextPanelAPI;
28import com.fs.starfarer.api.campaign.ai.CampaignFleetAIAPI.ActionType;
29import com.fs.starfarer.api.campaign.econ.Industry;
30import com.fs.starfarer.api.campaign.econ.MarketAPI;
31import com.fs.starfarer.api.campaign.econ.MonthlyReport;
32import com.fs.starfarer.api.campaign.listeners.GroundRaidObjectivesListener.RaidResultData;
33import com.fs.starfarer.api.campaign.listeners.ListenerUtil;
34import com.fs.starfarer.api.campaign.rules.MemoryAPI;
35import com.fs.starfarer.api.characters.OfficerDataAPI;
36import com.fs.starfarer.api.characters.PersonAPI;
37import com.fs.starfarer.api.combat.BattleCreationContext;
38import com.fs.starfarer.api.combat.MutableStat;
39import com.fs.starfarer.api.combat.MutableStat.StatMod;
40import com.fs.starfarer.api.combat.StatBonus;
41import com.fs.starfarer.api.fleet.FleetMemberAPI;
42import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
43import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
44import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
45import com.fs.starfarer.api.impl.campaign.DebugFlags;
46import com.fs.starfarer.api.impl.campaign.FleetEncounterContext;
47import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl;
48import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.BaseFIDDelegate;
49import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfig;
50import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript;
51import com.fs.starfarer.api.impl.campaign.MilitaryResponseScript.MilitaryResponseParams;
52import com.fs.starfarer.api.impl.campaign.RuleBasedInteractionDialogPluginImpl;
53import com.fs.starfarer.api.impl.campaign.econ.RecentUnrest;
54import com.fs.starfarer.api.impl.campaign.econ.impl.PopulationAndInfrastructure;
55import com.fs.starfarer.api.impl.campaign.graid.DisruptIndustryRaidObjectivePluginImpl;
56import com.fs.starfarer.api.impl.campaign.graid.GroundRaidObjectivePlugin;
57import com.fs.starfarer.api.impl.campaign.ids.Commodities;
58import com.fs.starfarer.api.impl.campaign.ids.Conditions;
59import com.fs.starfarer.api.impl.campaign.ids.Factions;
60import com.fs.starfarer.api.impl.campaign.ids.Industries;
61import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
62import com.fs.starfarer.api.impl.campaign.ids.Sounds;
63import com.fs.starfarer.api.impl.campaign.ids.Stats;
64import com.fs.starfarer.api.impl.campaign.ids.Strings;
65import com.fs.starfarer.api.impl.campaign.ids.Tags;
66import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
67import com.fs.starfarer.api.impl.campaign.intel.deciv.DecivTracker;
68import com.fs.starfarer.api.impl.campaign.population.CoreImmigrationPluginImpl;
69import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
70import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
71import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin;
72import com.fs.starfarer.api.impl.campaign.rulecmd.FireAll;
73import com.fs.starfarer.api.impl.campaign.rulecmd.FireBest;
74import com.fs.starfarer.api.impl.campaign.rulecmd.SetStoryOption;
75import com.fs.starfarer.api.impl.campaign.rulecmd.SetStoryOption.BaseOptionStoryPointActionDelegate;
76import com.fs.starfarer.api.impl.campaign.rulecmd.SetStoryOption.StoryOptionParams;
77import com.fs.starfarer.api.impl.campaign.rulecmd.ShowDefaultVisual;
78import com.fs.starfarer.api.impl.campaign.shared.SharedData;
79import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin;
80import com.fs.starfarer.api.ui.LabelAPI;
81import com.fs.starfarer.api.ui.TooltipMakerAPI;
82import com.fs.starfarer.api.ui.TooltipMakerAPI.StatModValueGetter;
83import com.fs.starfarer.api.util.Misc;
84import com.fs.starfarer.api.util.Misc.Token;
91 public static enum RaidType {
97 public static enum BombardType {
102 public static enum RaidDangerLevel {
110 private static RaidDangerLevel [] vals = values();
113 public String lossesName;
115 public float marineLossesMult;
116 public int marineTokens;
117 public float disruptionDays;
118 private RaidDangerLevel(String name, String lossesName, Color color,
float marineLossesMult,
float disruptionDays,
int marineTokens) {
120 this.lossesName = lossesName;
122 this.marineLossesMult = marineLossesMult;
123 this.disruptionDays = disruptionDays;
124 this.marineTokens = marineTokens;
127 public RaidDangerLevel next() {
128 int index = this.ordinal() + 1;
129 if (index >= vals.length) index = vals.length - 1;
132 public RaidDangerLevel prev() {
133 int index = this.ordinal() - 1;
134 if (index < 0) index = 0;
139 public static class TempData {
142 public boolean canRaid;
143 public boolean canBombard;
145 public int bombardCost;
147 public int marinesLost;
152 public float raidMult;
154 public float attackerStr;
155 public float defenderStr;
157 public boolean nonMarket =
false;
158 public boolean secret =
false;
160 public RaidType raidType =
null;
161 public BombardType bombardType =
null;
165 public List<FactionAPI> willBecomeHostile =
new ArrayList<FactionAPI>();
166 public List<Industry> bombardmentTargets =
new ArrayList<Industry>();
167 public List<GroundRaidObjectivePlugin> objectives =
new ArrayList<GroundRaidObjectivePlugin>();
168 public String contText;
169 public String raidGoBackTrigger;
170 public String raidContinueTrigger;
196 public static String
ENGAGE =
"mktEngage";
198 public static String
RAID =
"mktRaid";
212 public static String
INVADE =
"mktInvade";
243 protected TempData
temp =
new TempData();
252 temp.raidType =
null;
253 temp.bombardType =
null;
254 temp.raidLoot =
null;
256 temp.willBecomeHostile.clear();
257 temp.bombardmentTargets.clear();
258 temp.objectives.clear();
259 temp.contText =
null;
260 temp.raidGoBackTrigger =
null;
261 temp.raidContinueTrigger =
null;
288 String key =
"$MarketCMD_temp";
296 temp = (TempData) mem.
get(key);
306 String command = params.get(0).getString(
memoryMap);
307 if (command ==
null)
return false;
317 if (command.equals(
"showDefenses")) {
321 }
else if (command.equals(
"goBackToDefenses")) {
322 if (
temp.nonMarket) {
323 String trigger =
temp.raidGoBackTrigger;
324 if (trigger ==
null || trigger.isEmpty()) trigger =
"PopulateOptions";
333 }
else if (command.equals(
"engage")) {
335 }
else if (command.equals(
"raidMenu")) {
341 }
else if (command.equals(
"raidNonMarket")) {
343 }
else if (command.equals(
"raidValuable")) {
345 }
else if (command.equals(
"raidDisrupt")) {
347 }
else if (command.equals(
"raidConfirm")) {
349 }
else if (command.equals(
"raidConfirmContinue")) {
351 }
else if (command.equals(
"raidNeverMind")) {
353 }
else if (command.equals(
"addContinueToRaidResultOption")) {
355 }
else if (command.equals(
"raidResult")) {
357 }
else if (command.equals(
"bombardMenu")) {
359 }
else if (command.equals(
"bombardTactical")) {
361 }
else if (command.equals(
"bombardSaturation")) {
363 }
else if (command.equals(
"bombardConfirm")) {
365 }
else if (command.equals(
"bombardNeverMind")) {
367 }
else if (command.equals(
"bombardResult")) {
369 }
else if (command.equals(
"checkDebtEffect")) {
371 }
else if (command.equals(
"applyDebtEffect")) {
373 }
else if (command.equals(
"checkMercsLeaving")) {
375 }
else if (command.equals(
"convinceMercToStay")) {
377 }
else if (command.equals(
"mercLeaves")) {
379 }
else if (command.equals(
"assistVolturnInsurgents"))
382 RecentUnrest.
get(volturn).
add(2,
"The Luddic insurgency acquired unusually heavy weaponry somehow");
392 boolean hasNonStation =
false;
393 boolean hasOtherButInsignificant =
true;
394 boolean hasStation = station !=
null;
395 boolean otherWantsToFight =
false;
400 boolean ongoingBattle =
false;
402 boolean playerOnDefenderSide =
false;
403 boolean playerCanNotJoin =
false;
405 String stationType =
"station";
406 if (station !=
null) {
408 if (flagship !=
null && flagship.
getVariant() !=
null) {
420 if (primary ==
null) {
421 if (state == StationState.NONE) {
422 text.
addPara(
"The colony has no orbital station or nearby fleets to defend it.");
425 text.
addPara(
"There are no nearby fleets to defend the colony.");
428 ongoingBattle = primary.
getBattle() !=
null;
439 FIDConfig params =
new FIDConfig();
440 params.justShowFleets =
true;
441 params.showPullInText = withText;
456 if (playerSide != BattleSide.NO_JOIN) {
458 playerSide = BattleSide.NO_JOIN;
461 playerCanNotJoin = playerSide == BattleSide.NO_JOIN;
462 if (!playerCanNotJoin) {
465 if (!ongoingBattle) {
466 playerOnDefenderSide =
false;
469 boolean otherHasStation =
false;
470 if (playerSide != BattleSide.NO_JOIN) {
472 if (station !=
null) {
474 if (!fleet.isStationMode()) {
475 hasNonStation =
true;
482 if (!fleet.isStationMode()) {
483 hasNonStation =
true;
488 hasNonStation =
true;
493 if (!fleet.isStationMode()) {
496 otherHasStation =
true;
501 if (!hasNonStation) hasOtherButInsignificant =
false;
511 String name =
"An orbital station";
512 if (station !=
null) {
514 if (flagship !=
null) {
521 text.
addPara(name +
" dominates the orbit and prevents any " +
522 "hostile action, aside from a quick raid, unless it is dealt with.");
527 text.
addPara(
"There are defending ships present, but they are currently involved in a battle, "
528 +
"and you could take advantage of the distraction to launch a raid.");
530 if (hasOtherButInsignificant) {
531 text.
addPara(
"Defending ships are present, but not in sufficient strength " +
532 "to want to give battle or prevent any hostile action you might take.");
534 text.
addPara(
"The defending ships present are, with the support of the station, sufficient to prevent " +
539 }
else if (hasNonStation && otherWantsToFight) {
541 text.
addPara(
"Defending ships are present in sufficient strength to prevent any hostile action " +
542 "until they are dealt with.");
543 }
else if (hasNonStation && !otherWantsToFight) {
545 text.
addPara(
"Defending ships are present, but not in sufficient strength " +
546 "to want to give battle or prevent any hostile action you might take.");
553 if (!hasNonStation) hasOtherButInsignificant =
false;
557 String engageText =
"Engage the defenders";
559 if (playerCanNotJoin) {
560 engageText =
"Engage the defenders";
561 }
else if (playerOnDefenderSide) {
562 if (hasStation && hasNonStation) {
563 engageText =
"Aid the " + stationType +
" and its defenders";
564 }
else if (hasStation) {
565 engageText =
"Aid the " + stationType +
"";
567 engageText =
"Aid the defenders";
571 engageText =
"Aid the attacking forces";
573 if (hasStation && hasNonStation) {
574 engageText =
"Engage the " + stationType +
" and its defenders";
575 }
else if (hasStation) {
576 engageText =
"Engage the " + stationType +
"";
578 engageText =
"Engage the defenders";
587 temp.canRaid = ongoingBattle || hasOtherButInsignificant || (hasNonStation && !otherWantsToFight) || !hasNonStation;
588 temp.canBombard = (hasOtherButInsignificant || (hasNonStation && !otherWantsToFight) || !hasNonStation) && !hasStation;
591 boolean couldRaidIfNotDebug =
temp.canRaid;
593 if (!
temp.canRaid || !
temp.canBombard) {
594 text.
addPara(
"(DEBUG mode: can raid and bombard anyway)");
597 temp.canBombard =
true;
610 options.
setTooltip(
RAID,
"The presence of enemy fleets that are willing to offer battle makes a raid impossible.");
628 if (!
temp.canBombard) {
638 text.
addPara(
"Your forces will be able to organize another raid within a day or so.");
639 temp.canRaid =
false;
641 text.
addPara(
"Your forces will be able to organize another raid within a day or so.");
650 if (context !=
null && otherWantsToFight && !playerCanNotJoin) {
660 " not currently hostile, and you have been positively identified. " +
661 "Are you sure you want to engage in open hostilities?",
"Yes",
"Never mind");
663 }
else if (context ==
null || playerCanNotJoin || !otherWantsToFight) {
665 if (!otherWantsToFight) {
666 if (ongoingBattle && playerOnDefenderSide && !otherWantsToFight) {
667 options.
setTooltip(
ENGAGE,
"The attackers are in disarray and not currently attempting to engage the station.");
669 if (playerCanNotJoin) {
671 }
else if (primary ==
null) {
684 if (plugin !=
null) {
693 attackerStr += Math.min(support, attackerStr);
709 defenderStr += added;
715 defenderStr += cargo.
getMarines() * marineDefenseValueMult;
719 defenderStr += cargo.
getMarines() * marineDefenseValueMult;
731 return attackerStr / Math.max(1f, (attackerStr + defenderStr));
767 temp.nonMarket =
true;
777 if (support > marines) support = marines;
785 attackerBase.
modifyFlatAlways(
"core_support", support,
"Fleet capability for ground support");
791 defender.
modifyFlat(
"difficulty", difficulty,
"Expected resistance");
793 String surpriseKey =
"core_surprise";
799 String increasedDefensesKey =
"core_addedDefStr";
803 defender.
modifyFlat(increasedDefensesKey, added,
"Increased defender preparedness");
809 temp.attackerStr = attackerStr;
810 temp.defenderStr = defenderStr;
824 " not currently hostile. Your fleet's transponder is on, and carrying out a raid " +
825 "will result in open hostilities.",
829 " not currently hostile. Your fleet's transponder is off, and carrying out a raid " +
830 "will only result in a minor penalty to your standing.",
838 info.
addPara(
"Raid strength: %s", initPad, h,
"" + (
int)attackerStr);
845 info.
addPara(
"Operation difficulty: %s", opad, h,
"" + (
int)defenderStr);
857 boolean hasForces =
true;
858 temp.raidMult = attackerStr / Math.max(1f, (attackerStr + defenderStr));
859 temp.raidMult = Math.round(
temp.raidMult * 100f) / 100f;
868 "" + (
int)(
temp.raidMult * 100f) +
"%");
871 text.
addPara(
"You do not have the forces to carry out an effective raid.");
905 temp.nonMarket =
false;
913 if (support > marines) support = marines;
921 attackerBase.
modifyFlatAlways(
"core_support", support,
"Fleet capability for ground support");
926 String surpriseKey =
"core_surprise";
932 String increasedDefensesKey =
"core_addedDefStr";
935 defender.
modifyFlat(increasedDefensesKey, added,
"Increased defender preparedness");
941 temp.attackerStr = attackerStr;
942 temp.defenderStr = defenderStr;
956 " not currently hostile. Your fleet's transponder is on, and carrying out a raid " +
957 "will result in open hostilities.",
961 " not currently hostile. Your fleet's transponder is off, and carrying out a raid " +
962 "will only result in a minor penalty to your standing.",
970 info.
addPara(
"Raid strength: %s", initPad, h,
"" + (
int)attackerStr);
977 info.
addPara(
"Ground defense strength: %s", opad, h,
"" + (
int)defenderStr);
989 boolean hasForces =
true;
990 boolean canDisrupt =
true;
991 temp.raidMult = attackerStr / Math.max(1f, (attackerStr + defenderStr));
992 temp.raidMult = Math.round(
temp.raidMult * 100f) / 100f;
1008 }
else if (
temp.raidMult >= 0.7f) {
1018 "" + (
int)(
temp.raidMult * 100f) +
"%");
1021 text.
addPara(
"The ground defenses are too strong for your forces to be able to cause long-term disruption.");
1024 text.
addPara(
"You do not have the forces to carry out an effective raid to acquire valuables or achieve other objectives.");
1053 if (!hasForces || !canDisrupt) {
1072 temp.raidType = RaidType.VALUABLE;
1074 List<GroundRaidObjectivePlugin> obj =
new ArrayList<GroundRaidObjectivePlugin>();
1077 final RaidType useType = !temp.nonMarket ? temp.raidType : RaidType.CUSTOM_ONLY;
1079 for (
int i = 0; i < 10; i++) {
1083 if (obj.isEmpty()) {
1084 text.
addPara(
"After careful consideration, there do not appear to be any targets " +
1085 "likely to yield anything of value.");
1093 public void pickedGroundRaidTargets(List<GroundRaidObjectivePlugin> data) {
1096 value += curr.getProjectedCreditsValue();
1099 List<String> names =
new ArrayList<String>();
1101 names.add(curr.getNameOverride() !=
null ? curr.getNameOverride() : curr.getName());
1104 String item =
"objective";
1105 if (names.size() > 1) {
1106 item =
"objectives";
1109 String isOrAre =
"are";
1110 String marinesStr =
"marines";
1113 marinesStr =
"marine";
1116 LabelAPI label =
text.
addPara(
"Your marine commander submits a plan for your approval. Losses during this " +
1117 "operation are projected to be %s. There " + isOrAre +
" a total of %s " +
1118 marinesStr +
" in your fleet.",
1119 getMarineLossesColor(data), getProjectedMarineLosses(data).toLowerCase(),
1123 names.toArray(
new String[0]));
1125 text.
addPara(
"The estimated value of the items obtained is projected to be around %s.",
1131 text.
addPara(
"The marines are ready to go, awaiting your final confirmation.");
1132 temp.objectives = data;
1136 public boolean isDisruptIndustryMode() {
1140 public boolean isCustomOnlyMode() {
1141 return useType == RaidType.CUSTOM_ONLY;
1144 public void cancelledGroundRaidTargetPicking() {
1148 public int getCargoSpaceNeeded(List<GroundRaidObjectivePlugin> data) {
1151 total += curr.getCargoSpaceNeeded();
1156 public int getFuelSpaceNeeded(List<GroundRaidObjectivePlugin> data) {
1159 total += curr.getFuelSpaceNeeded();
1164 public int getProjectedCreditsValue(List<GroundRaidObjectivePlugin> data) {
1167 total += curr.getProjectedCreditsValue();
1180 public String getProjectedMarineLosses(List<GroundRaidObjectivePlugin> data) {
1185 float f = losses / Math.max(1f, marines);
1187 for (RaidDangerLevel level : RaidDangerLevel.values()) {
1188 float test = level.marineLossesMult + (level.next().marineLossesMult - level.marineLossesMult) * 0.5f;
1189 if (level == RaidDangerLevel.NONE) test = RaidDangerLevel.NONE.marineLossesMult;
1191 return level.lossesName;
1194 return RaidDangerLevel.EXTREME.lossesName;
1201 public Color getMarineLossesColor(List<GroundRaidObjectivePlugin> data) {
1206 float f = losses / Math.max(1f, marines);
1209 for (RaidDangerLevel level : RaidDangerLevel.values()) {
1210 float test = level.marineLossesMult + (level.next().marineLossesMult - level.marineLossesMult) * 0.5f;
1215 return RaidDangerLevel.EXTREME.color;
1218 return "" + (int)(
temp.raidMult * 100f) +
"%";
1229 List<FactionAPI> nonHostile =
new ArrayList<FactionAPI>();
1237 if (nonHostile.size() == 1) {
1242 " not currently hostile, and will become hostile if you carry out the bombardment. " +
1243 "Are you sure?",
"Yes",
"Never mind");
1244 }
else if (nonHostile.size() > 1) {
1246 "Multiple factions that are not currently hostile " +
1247 "will become hostile if you carry out the bombardment. " +
1248 "Are you sure?",
"Yes",
"Never mind");
1253 temp.raidType = RaidType.DISRUPT;
1256 List<GroundRaidObjectivePlugin> obj =
new ArrayList<GroundRaidObjectivePlugin>();
1257 for (
int i = 0; i < 10; i++) {
1261 if (obj.isEmpty()) {
1262 text.
addPara(
"There are no industries or facilities present that could be disrupted by a raid.");
1270 public void pickedGroundRaidTargets(List<GroundRaidObjectivePlugin> data) {
1273 value += curr.getProjectedCreditsValue();
1276 List<String> names =
new ArrayList<String>();
1278 names.add(curr.getNameOverride() !=
null ? curr.getNameOverride() : curr.getName());
1281 String item =
"objective";
1282 if (names.size() > 1) {
1283 item =
"objectives";
1288 text.
addPara(
"Your marine commander submits a plan for your approval. Losses during this " +
1289 "operation are projected to be %s.",
1290 getMarineLossesColor(data), getProjectedMarineLosses(data).toLowerCase());
1292 names.toArray(
new String[0]));
1295 text.
addPara(
"The estimated value of the items obtained is projected to be around %s.",
1299 text.
addPara(
"The marines are ready to go, awaiting your final confirmation. There are a total of %s " +
1301 temp.objectives = data;
1305 public boolean isDisruptIndustryMode() {
1309 public void cancelledGroundRaidTargetPicking() {
1313 public int getCargoSpaceNeeded(List<GroundRaidObjectivePlugin> data) {
1316 total += curr.getCargoSpaceNeeded();
1321 public int getFuelSpaceNeeded(List<GroundRaidObjectivePlugin> data) {
1324 total += curr.getFuelSpaceNeeded();
1329 public int getProjectedCreditsValue(List<GroundRaidObjectivePlugin> data) {
1332 total += curr.getProjectedCreditsValue();
1345 public String getProjectedMarineLosses(List<GroundRaidObjectivePlugin> data) {
1350 float f = losses / Math.max(1f, marines);
1352 for (RaidDangerLevel level : RaidDangerLevel.values()) {
1353 float test = level.marineLossesMult + (level.next().marineLossesMult - level.marineLossesMult) * 0.5f;
1354 if (level == RaidDangerLevel.NONE) test = RaidDangerLevel.NONE.marineLossesMult;
1356 return level.lossesName;
1359 return RaidDangerLevel.EXTREME.lossesName;
1366 public Color getMarineLossesColor(List<GroundRaidObjectivePlugin> data) {
1371 float f = losses / Math.max(1f, marines);
1374 for (RaidDangerLevel level : RaidDangerLevel.values()) {
1375 float test = level.marineLossesMult + (level.next().marineLossesMult - level.marineLossesMult) * 0.5f;
1380 return RaidDangerLevel.EXTREME.color;
1383 return "" + (int)(
temp.raidMult * 100f) +
"%";
1386 public boolean isCustomOnlyMode() {
1419 temp.target = target;
1432 text.
addPara(
"Your ground forces commander estimates that given the relative force strengths, " +
1433 " the raid should disrupt all " + target.
getCurrentName() +
" operations for at least %s days.",
1436 text.
addPara(
"Your forces are ready to go, awaiting your final confirmation.");
1460 if (
text ==
null)
text =
"Continue";
1468 if (
market ==
null)
return 0f;
1479 if (e > max) e = max;
1491 float incr = Math.max(base * f, min);
1495 return (
int)(incr * e / per);
1517 String key =
"$raid_cooldown";
1522 String key =
"$raid_cooldown";
1527 String key =
"$raid_random";
1537 Random random =
null;
1539 random = (Random) mem.
get(key);
1545 random =
new Random(seed);
1547 random =
new Random();
1550 mem.
set(key, random, 30f);
1568 float assignedTokens = 0f;
1570 RaidDangerLevel danger = curr.getDangerLevel();
1571 total += danger.marineLossesMult * (float) curr.getMarinesAssigned();
1572 assignedTokens += curr.getMarinesAssigned();
1575 float danger = total / Math.max(1f, assignedTokens);
1592 if (
market !=
null && reMult < 1f) {
1593 float minMarinesForAssignedTokens =
getMarinesFor(
market, (
int) Math.round(assignedTokens));
1595 if (actualMarines > minMarinesForAssignedTokens && actualMarines > 0) {
1596 reMult *= 0.5f + (0.5f * minMarinesForAssignedTokens / actualMarines);
1600 float reservesMult = 1f;
1602 if (maxTokens > assignedTokens) {
1604 reservesMult = Math.max(0.5f, reservesMult);
1612 stat.
modifyMult(
"hazard", hazard,
"Colony hazard rating");
1615 }
else if (reMult > 1f) {
1619 if (reservesMult < 1f && assignedTokens > 0) {
1620 stat.
modifyMultAlways(
"reservesMult", reservesMult,
"Forces held in reserve");
1626 stat.
modifyMult(
"prep", 1f + prep,
"Increased defender preparedness");
1645 return marines * mult;
1649 if (
market ==
null)
return;
1652 MilitaryResponseParams params =
new MilitaryResponseParams(ActionType.HOSTILE,
1663 MemoryAPI mem = other.getMemoryWithoutUpdate();
1670 if (
temp.raidType ==
null) {
1675 temp.secret = secret;
1701 int stabilityPenalty = 0;
1702 if (!
temp.nonMarket) {
1703 String reason =
"Recently raided";
1707 float raidMultForStabilityPenalty =
temp.raidMult;
1708 if (
temp.objectives !=
null) {
1709 float assignedTokens = 0f;
1713 raidMultForStabilityPenalty = assignedTokens * 0.1f;
1723 float probOfLosses = 1f;
1726 if (random.nextFloat() < probOfLosses) {
1728 float variance = averageLosses / 4f;
1732 random, averageLosses - variance, averageLosses + variance);
1733 if (randomizedLosses < 1f) {
1734 randomizedLosses = random.nextFloat() < randomizedLosses ? 1f : 0f;
1736 randomizedLosses = Math.round(randomizedLosses);
1737 losses = (int) randomizedLosses;
1739 if (losses < 0) losses = 0;
1740 if (losses > marines) losses = marines;
1746 text.
addPara(
"Your forces have not suffered any casualties.");
1747 temp.marinesLost = 0;
1751 temp.marinesLost = losses;
1759 CustomRepImpact impact =
new CustomRepImpact();
1763 impact.delta = -0.01f;
1765 if (!hostile && tOn) {
1770 new RepActionEnvelope(RepActions.CUSTOM,
1771 impact,
null,
text,
true,
true),
1776 if (stabilityPenalty > 0) {
1794 temp.raidLoot = result;
1805 if (
temp.xpGained > 0) {
1808 if (
temp.raidType == RaidType.VALUABLE) {
1814 }
else if (
temp.raidType == RaidType.DISRUPT) {
1818 boolean withContinue =
false;
1822 withContinue =
true;
1844 String contText =
null;
1845 if (
temp.raidType == RaidType.VALUABLE ||
true) {
1846 if (!
temp.nonMarket) {
1847 if (
temp.raidType == RaidType.VALUABLE ||
true) {
1861 if (raidCredits < 0) raidCredits = 0;
1864 if (raidCredits > 0) {
1874 contText =
"Pick through the spoils";
1876 temp.contText = contText;
1878 float assignedTokens = 0f;
1879 List<Industry> disrupted =
new ArrayList<Industry>();
1887 RaidResultData data =
new RaidResultData();
1890 data.objectives =
temp.objectives;
1891 data.type =
temp.raidType;
1892 data.raidEffectiveness =
temp.raidMult;
1893 data.xpGained =
temp.xpGained;
1894 data.marinesTokensInReserve = (int) Math.round(
getNumMarineTokens() - assignedTokens);
1896 data.marinesLost =
temp.marinesLost;
1900 if (
temp.raidType == RaidType.VALUABLE) {
1902 }
else if (
temp.raidType == RaidType.DISRUPT) {
1918 float leftoverRE = (int)Math.round(raidEffectiveness * 100f) % (int)Math.round(
RE_PER_MARINE_TOKEN * 100f);
1925 long baseSeed = random.nextLong();
1931 Random curr =
new Random(
Misc.seedUniquifier() ^ (baseSeed * plugin.getClass().
getName().hashCode()));
1942 if (
temp.nonMarket) {
1952 public void coreUIDismissed() {
1962 if (state == StationState.REPAIRS || state == StationState.UNDER_CONSTRUCTION) {
1964 String name =
"orbital station";
1965 if (fleet !=
null) {
1967 if (flagship !=
null) {
1971 if (state == StationState.REPAIRS) {
1972 text.
addPara(
"The " + name +
" has suffered extensive damage and is not currently combat-capable.");
1974 text.
addPara(
"The " + name +
" is under construction and is not currently combat-capable.");
1988 final FIDConfig config =
new FIDConfig();
1989 config.leaveAlwaysAvailable =
true;
1990 config.showCommLinkOption =
false;
1991 config.showEngageText =
false;
1992 config.showFleetAttitude =
false;
1993 config.showTransponderStatus =
false;
1995 config.alwaysAttackVsAttack =
true;
1996 config.impactsAllyReputation =
true;
2004 config.noSalvageLeaveOptionText =
"Continue";
2006 config.dismissOnLeave =
false;
2007 config.printXPToDialog =
true;
2009 config.straightToEngage =
true;
2012 config.playerAttackingStation = station !=
null;
2017 config.delegate =
new BaseFIDDelegate() {
2072 bcc.objectivesAllowed =
false;
2087 if (station ==
null)
return null;
2096 if (primary ==
null) {
2098 float minDist = Float.MAX_VALUE;
2100 if (fleet.getBattle() !=
null)
continue;
2103 if (fleet.getFleetData().getNumMembers() <= 0)
continue;
2107 dist -= fleet.getRadius();
2110 if (dist < minDist) {
2123 public static enum StationState {
2132 boolean destroyed =
false;
2133 if (fleet ==
null) {
2135 if (fleet !=
null) {
2140 if (fleet ==
null)
return StationState.NONE;
2146 if (ind.isBuilding() && !ind.isDisrupted() && !ind.isUpgrading()) {
2147 return StationState.UNDER_CONSTRUCTION;
2153 if (destroyed)
return StationState.REPAIRS;
2155 return StationState.OPERATIONAL;
2161 if (re >= 0.79f) penalty = 3;
2162 else if (re >= 0.59f) penalty = 2;
2163 else if (re >= 0.29f) penalty = 1;
2171 int penalty = Math.round((0.45f + maxPenalty) * re);
2181 public String getPercentValue(StatMod mod) {
2182 String prefix = mod.getValue() > 0 ?
"+" :
"";
2183 return prefix + (int)(mod.getValue()) +
"%";
2185 public String getMultValue(StatMod mod) {
2188 public String getFlatValue(StatMod mod) {
2189 String prefix = mod.getValue() > 0 ?
"+" :
"";
2190 return prefix + (int)(mod.getValue()) +
"";
2192 public Color getModColor(StatMod mod) {
2203 if (result < 2) result = 2;
2204 if (fleet !=
null) {
2206 result -= bomardBonus;
2207 if (result < 0) result = 0;
2233 String increasedBombardKey =
"core_addedBombard";
2235 if (bomardBonus > 0) {
2236 bombardBonusStat.
modifyFlat(increasedBombardKey, -bomardBonus,
"Specialized fleet bombardment capability");
2240 defenderStr -= bomardBonus;
2241 if (defenderStr < 0) defenderStr = 0;
2243 temp.defenderStr = defenderStr;
2256 " not currently hostile. A bombardment is a major enough hostile action that it can't be concealed, " +
2257 "regardless of transponder status.",
2262 info.
addPara(
"Starship fuel can be easily destabilized, unlocking the destructive " +
2263 "potential of the antimatter it contains. Ground defenses can counter " +
2264 "a bombardment, though in practice it only means that more fuel is required to achieve " +
2265 "the same result.", initPad);
2268 if (bomardBonus > 0) {
2269 info.
addPara(
"Effective ground defense strength: %s", opad, h,
"" + (
int)defenderStr);
2271 info.
addPara(
"Ground defense strength: %s", opad, h,
"" + (
int)defenderStr);
2287 boolean canBombard = fuel >=
temp.bombardCost;
2290 "You have %s fuel.",
2291 h,
"" +
temp.bombardCost,
"" + fuel);
2331 req =
"\n\nRequires transponder to be turned off";
2335 "Will not help if forced to turn your transponder on by patrols arriving to investigate the raid." + req);
2341 new BaseOptionStoryPointActionDelegate(
dialog, params) {
2343 public void confirm() {
2359 " not currently hostile, and you have been positively identified. " +
2360 "Are you sure you want to engage in open hostilities?",
"Yes",
"Never mind");
2366 List<Industry> targets =
new ArrayList<Industry>();
2369 if (ind.getDisruptedDays() >= dur * 0.8f)
continue;
2378 temp.bombardType = BombardType.TACTICAL;
2381 temp.willBecomeHostile.clear();
2394 temp.bombardmentTargets.clear();
2395 temp.bombardmentTargets.addAll(targets);
2397 if (targets.isEmpty()) {
2398 text.
addPara(
market.
getName() +
" does not have any undisrupted military targets that would be affected by a tactical bombardment.");
2405 text.
addPara(
"A tactical bombardment will destabilize the colony, and will also disrupt the " +
2406 "following military targets for approximately %s days:",
2418 info.
addPara(ind.getCurrentName(), initPad);
2425 text.
addPara(
"The bombardment requires %s fuel. " +
2426 "You have %s fuel.",
2427 h,
"" +
temp.bombardCost,
"" + fuel);
2434 temp.bombardType = BombardType.SATURATION;
2436 temp.willBecomeHostile.clear();
2439 List<FactionAPI> nonHostile =
new ArrayList<FactionAPI>();
2442 if (
temp.willBecomeHostile.contains(
faction))
continue;
2462 List<Industry> targets =
new ArrayList<Industry>();
2465 if (ind.getDisruptedDays() >= dur * 0.8f)
continue;
2469 temp.bombardmentTargets.clear();
2470 temp.bombardmentTargets.addAll(targets);
2477 text.
addPara(
"A saturation bombardment of a colony this size will destroy it utterly.");
2479 text.
addPara(
"A saturation bombardment will destabilize the colony, reduce its population, " +
2480 "and disrupt all operations for a long time.");
2499 if (nonHostile.isEmpty()) {
2500 text.
addPara(
"An atrocity of this scale can not be hidden, but any factions that would " +
2501 "be dismayed by such actions are already hostile to you.");
2503 text.
addPara(
"An atrocity of this scale can not be hidden, " +
2504 "and will make the following factions hostile:");
2507 if (!nonHostile.isEmpty()) {
2522 text.
addPara(
"The bombardment requires %s fuel. " +
2523 "You have %s fuel.",
2524 h,
"" +
temp.bombardCost,
"" + fuel);
2531 if (
temp.bombardType ==
null) {
2536 if (
temp.bombardType == BombardType.TACTICAL) {
2546 if (
temp.bombardType == BombardType.SATURATION) {
2554 if (curr ==
market)
continue;
2556 cares &= temp.bombardType == BombardType.SATURATION;
2558 if (curr.getFaction().isNeutralFaction())
continue;
2559 if (curr.getFaction().isPlayerFaction())
continue;
2560 if (curr.getFaction().isHostileTo(
market.
getFaction()) && !cares)
continue;
2572 CustomRepImpact impact =
new CustomRepImpact();
2575 if (
temp.bombardType == BombardType.SATURATION) {
2582 new RepActionEnvelope(RepActions.CUSTOM,
2583 impact,
null,
text,
true,
true),
2587 if (
temp.bombardType == BombardType.SATURATION) {
2602 if (
temp.bombardType == BombardType.SATURATION) {
2608 if (stabilityPenalty > 0 && !destroy) {
2609 String reason =
"Recently bombarded";
2632 if (
temp.bombardType == BombardType.TACTICAL) {
2636 }
else if (
temp.bombardType == BombardType.SATURATION) {
2646 text.
addPara(
"All operations disrupted. Colony size reduced to %s.",
2687 if (
temp.raidLoot !=
null) {
2725 if (
temp.nonMarket) {
2726 String trigger =
temp.raidContinueTrigger;
2727 if (trigger ==
null || trigger.isEmpty()) trigger =
"OpenInteractionDialog";
2740 if (
text ==
null)
text =
"Continue";
2747 String key =
"$debt_effectTimeout";
2763 float income = report.
getRoot().totalIncome;
2764 if (income < 1) income = 1;
2766 float f = debt / income;
2770 if (f < 0.1f)
return false;
2775 if (crew <= 10 && marines <= 10)
return false;
2784 float income = report.
getRoot().totalIncome;
2785 if (income < 1) income = 1;
2787 float f = debt / income;
2794 float maxLossFraction = 0.03f + Math.min(f + 0.05f, 0.2f) * (float) Math.random();
2795 float marineLossFraction = 0.03f + Math.min(f + 0.05f, 0.2f) * (float) Math.random();
2798 int crewLoss = (int) (crew * maxLossFraction);
2799 if (crewLoss < 2) crewLoss = 2;
2801 int marineLoss = (int) (marines * marineLossFraction);
2802 if (marineLoss < 2) marineLoss = 2;
2806 text.
addPara(
"The lack of consistent pay over the last few months has caused discontent among your crew. " +
2807 "A number take this opportunity to leave your employment.");
2809 if (crewLoss < crew) {
2813 if (marineLoss <= marines) {
2818 String key =
"$debt_effectTimeout";
2842 if (maxPenalty == 3) {
2855 temp.raidType = RaidType.DISRUPT;
2856 temp.target = industry;
2861 String increasedDefensesKey =
"core_addedDefStr";
2864 defender.
modifyFlat(increasedDefensesKey, added,
"Increased defender preparedness");
2869 temp.attackerStr = attackerStr;
2870 temp.defenderStr = defenderStr;
2872 boolean hasForces =
true;
2873 boolean canDisrupt =
true;
2874 temp.raidMult = attackerStr / Math.max(1f, (attackerStr + defenderStr));
2875 temp.raidMult = Math.round(
temp.raidMult * 100f) / 100f;
2883 if (!canDisrupt)
return false;
2900 if (
temp.target !=
null) {
2904 if (dur < 2) dur = 2;
2914 temp.bombardType = type;
2921 if (
temp.bombardType == BombardType.SATURATION) {
2924 List<Industry> targets =
new ArrayList<Industry>();
2927 if (ind.getDisruptedDays() >= dur * 0.8f)
continue;
2931 temp.bombardmentTargets.clear();
2932 temp.bombardmentTargets.addAll(targets);
2934 List<Industry> targets =
new ArrayList<Industry>();
2937 if (ind.getDisruptedDays() >= dur * 0.8f)
continue;
2941 temp.bombardmentTargets.clear();
2942 temp.bombardmentTargets.addAll(targets);
2946 if (stabilityPenalty > 0) {
2948 String reason =
"Saturation bombardment";
2949 if (
temp.bombardType == BombardType.TACTICAL) {
2950 reason =
"Tactical bombardment";
2966 if (
temp.bombardType == BombardType.TACTICAL) {
2967 }
else if (
temp.bombardType == BombardType.SATURATION) {
2989 if (num > 150) num = 150;
2990 if (num < 10) num = 10;
2991 target.
addScript(
new BombardmentAnimation(num, target));
2998 this.target = target;
3004 public boolean runWhilePaused() {
3007 public boolean isDone() {
3008 return added >= num;
3010 public void advance(
float amount) {
3011 elapsed += amount * (float) Math.random();
3012 if (elapsed < 0.03f)
return;
3016 int curr = (int) Math.round(Math.random() * 4);
3017 if (curr < 1) curr = 0;
3019 Color color =
new Color(255, 165, 100, 255);
3021 Vector2f vel =
new Vector2f();
3035 for (
int i = 0; i < curr; i++) {
3036 float glowSize = 50f + 50f * (float) Math.random();
3037 float angle = (float) Math.random() * 360f;
3038 float dist = (float) Math.sqrt(Math.random()) * target.
getRadius();
3040 float factor = 0.5f + 0.5f * (1f - (float)Math.sqrt(dist / target.
getRadius()));;
3042 Vector2f loc = Misc.getUnitVectorAtDegreeAngle(angle);
3046 Color c2 = Misc.scaleColor(color, factor);
3053 if (dist < HyperspaceTerrainPlugin.STORM_STRIKE_SOUND_RANGE) {
3054 float volumeMult = 1f - (dist / HyperspaceTerrainPlugin.STORM_STRIKE_SOUND_RANGE);
3055 volumeMult = (float) Math.sqrt(volumeMult);
3056 volumeMult *= 0.1f * factor;
3057 if (volumeMult > 0) {
3068 String key =
"$mercs_leaveTimeout";
3075 if (mercs.isEmpty())
return false;
3078 boolean debt = report.
getDebt() > 0;
3083 if (debt && od.getPerson().getMemoryWithoutUpdate().contains(key)) {
3088 if (elapsed > contractDur || (debt && elapsed > 45f)) {
3106 String key =
"$mercs_leaveTimeout";
3119 if (member !=
null) {
3126 String key =
"$mercs_leaveTimeout";
static SettingsAPI getSettings()
static SoundPlayerAPI getSoundPlayer()
static FactoryAPI getFactory()
static SectorAPI getSector()
static void reportRaidObjectivesAchieved(RaidResultData data, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
static void modifyMarineLossesStatPreRaid(MarketAPI market, List< GroundRaidObjectivePlugin > objectives, MutableStat stat)
static void reportRaidForValuablesFinishedBeforeCargoShown(InteractionDialogAPI dialog, MarketAPI market, TempData actionData, CargoAPI cargo)
static void modifyRaidObjectives(MarketAPI market, SectorEntityToken entity, List< GroundRaidObjectivePlugin > objectives, RaidType type, int marineTokens, int priority)
static void reportSaturationBombardmentFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData)
static void reportRaidToDisruptFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData, Industry industry)
static void reportTacticalBombardmentFinished(InteractionDialogAPI dialog, MarketAPI market, TempData actionData)
void applyMods(MutableStat other)
void modifyMult(String source, float value)
void modifyMultAlways(String source, float value, String desc)
void unmodifyMult(String source)
void modifyFlatAlways(String source, float value, String desc)
void modifyFlat(String source, float value)
float computeEffective(float baseValue)
void unmodifyFlat(String source)
static boolean MARKET_HOSTILITIES_DEBUG
boolean didPlayerWinMostRecentBattleOfEncounter()
boolean isEngagedInHostilities()
void init(InteractionDialogAPI dialog)
FactionAPI getNonHostileOtherFaction()
void printOngoingBattleInfo()
boolean otherFleetWantsToFight()
static RecentUnrest get(MarketAPI market)
void add(int stability, String reason)
static float getBaseGroundDefenses(int marketSize)
float getBaseDisruptDuration(int marines)
static final String MARINES
static final String POLLUTION
static final String HABITABLE
static final String CUSTOM_NO_WAR_SIM
static final String CUSTOM_CARES_ABOUT_ATROCITIES
static final String PLAYER
static final String TAG_STATION
static final String TAG_TACTICAL_BOMBARDMENT
static final String TAG_NO_SATURATION_BOMBARDMENT
static final String MEMORY_KEY_MAKE_HOSTILE_WHILE_TOFF
static final String RECENTLY_RAIDED
static final String RECENTLY_BOMBARDED
static final String FACTION_SATURATION_BOMBARED_BY_PLAYER
static final String PLAYER_ATROCITIES
static String STORY_POINT_SPEND_LEADERSHIP
static final String PLANETARY_OPERATIONS_MOD
static final String FLEET_GROUND_SUPPORT
static final String FLEET_BOMBARD_COST_REDUCTION
static final String PLANETARY_OPERATIONS_CASUALTIES_MULT
static final String GROUND_DEFENSES_MOD
static final String INDENT
static void decivilize(MarketAPI market, boolean fullDestroy)
static void reduceMarketSize(MarketAPI market)
static float getNormalRandom(float min, float max)
static void addCommodityLossText(String commodityId, int quantity, TextPanelAPI text)
static void addCreditsGainText(int credits, TextPanelAPI text)
static void addOfficerLossText(PersonAPI officer, TextPanelAPI text)
static MemoryAPI getEntityMemory(Map< String, MemoryAPI > memoryMap)
static boolean fire(String ruleId, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap, String params)
static boolean fire(String ruleId, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap, String params)
static boolean set(String ruleId, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap, String params)
boolean execute(String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
static float getRaidDefenderIncreaseMax()
void addContinueOption(String text)
static int getBombardDisruptDuration()
void raidConfirm(boolean secret)
static String RAID_VALUABLE
boolean doIndustryRaid(FactionAPI faction, float attackerStr, Industry industry, float durMult)
static float getRaidDefenderIncreaseMin()
void setRaidCooldown(float cooldown)
static float getDefenderStr(MarketAPI market)
static float RE_PER_MARINE_TOKEN
static int MIN_MARINE_TOKENS
InteractionDialogAPI dialog
boolean checkDebtEffect()
static StatModValueGetter statPrinter(final boolean withNegative)
void doBombardment(FactionAPI faction, BombardType type)
CampaignFleetAPI getStationFleet()
static float getDefenderStr(MarketAPI market, boolean forBombard)
static String RAID_CONFIRM
static String RAID_RESULT
static float getRaidEffectiveness(MarketAPI market, CampaignFleetAPI fleet)
static int applyRaidStabiltyPenalty(MarketAPI target, String desc, float re)
static int getSaturationBombardmentStabilityPenalty()
void doGenericRaid(FactionAPI faction, float attackerStr)
void showDefenses(boolean withText)
CampaignFleetAPI getInteractionTargetForFIDPI()
void raidConfirmContinue()
static int getBombardDestroyThreshold()
static String RAID_DISRUPT
static float getDefenderIncreaseRaw(MarketAPI market)
static final String DEFENDER_INCREASE_KEY
void addNeverMindOption()
static String BOMBARD_TACTICAL
void addBombardConfirmOptions()
void finishedRaidOrBombard()
static float MAX_MARINE_LOSS_REDUCTION_MULT
static String RAID_NEVER_MIND
CargoAPI performRaid(Random random, float raidEffectiveness)
static String BOMBARD_NEVERMIND
static String DEBT_RESULT_CONTINUE
static String BOMBARD_SATURATION
static String RAID_GO_BACK
void init(SectorEntityToken entity)
static float DISRUPTION_THRESHOLD
StationState getStationState()
static float getDefenderIncreaseValue(MarketAPI market)
static int HOSTILE_ACTIONS_TIMEOUT_DAYS
static float QUANTITY_MULT_EXCESS
static int applyRaidStabiltyPenalty(MarketAPI target, String desc, float re, float maxPenalty)
static int TACTICAL_BOMBARD_TIMEOUT_DAYS
static int getTacticalBombardmentStabilityPenalty()
static void applyDefenderIncreaseFromRaid(MarketAPI market)
static int getMarinesFor(int defenderStrength, int tokens)
void doGenericRaid(FactionAPI faction, float attackerStr, float maxPenalty)
void addBombardContinueOption(String text)
static int getBombardmentCost(MarketAPI market, CampaignFleetAPI fleet)
static float VALUABLES_THRESHOLD
static String BOMBARD_CONFIRM
float computeBaseDisruptDuration(Industry ind)
static float QUANTITY_MULT_OVERALL
static int MAX_MARINE_TOKENS
static int getDisruptDaysPerToken(MarketAPI market, Industry industry)
static float LOSS_INCREASE_PER_RAID
static float LOSS_REDUCTION_PER_RESERVE_TOKEN
CampaignFleetAPI playerFleet
static String RAID_NON_MARKET
static float ECON_IMPACT_MULT
static int getMarinesFor(MarketAPI market, int tokens)
static float getRaidStr(CampaignFleetAPI fleet)
static List< Industry > getTacticalBombardmentTargets(MarketAPI market)
static float MIN_RE_TO_REDUCE_MARINE_LOSSES
float getRaidCooldownMax()
boolean checkMercsLeaving()
Map< String, MemoryAPI > memoryMap
static float MAX_MARINE_LOSSES
static String BOMBARD_RESULT
static float getRaidDefenderIncreaseFraction()
static float getRaidDefenderIncreasePerRaid()
void addBombardContinueOption()
boolean execute(String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
static String RAID_CONFIRM_STORY
void doGenericRaid(FactionAPI faction, float attackerStr, float maxPenalty, boolean allowedRepeat)
MarketCMD(SectorEntityToken entity)
float getAverageMarineLosses(List< GroundRaidObjectivePlugin > data)
static float MARINES_IN_MARKET_CARGO_DEFENSE_BONUS
void raidDisruptIndustryPicked(Industry target)
void addMilitaryResponse()
static void addBombardVisual(SectorEntityToken target)
static float QUANTITY_MULT_DEFICIT
MutableStat getMarineLossesStat(List< GroundRaidObjectivePlugin > data)
static int SATURATION_BOMBARD_TIMEOUT_DAYS
static float QUANTITY_MULT_NORMAL
static String RAID_CONFIRM_CONTINUE
void addBombardNeverMindOption()
static float getRaidEffectiveness(MarketAPI market, float attackerStr)
void convinceMercToStay()
MonthlyReport getPreviousReport()
static SharedData getData()
static boolean isStoryCritical(MarketAPI market)
static String getDGSCredits(float num)
static String getWithDGS(float num)
static float getMercDaysSinceHired(PersonAPI person)
static Vector2f getUnitVectorAtDegreeAngle(float degrees)
static List< CampaignFleetAPI > getNearbyFleets(SectorEntityToken from, float maxDist)
static String ucFirst(String str)
static Color getNegativeHighlightColor()
static CargoAPI getStorageCargo(MarketAPI market)
static void increaseMarketHostileTimeout(MarketAPI market, float days)
static float getFleetwideTotalMod(CampaignFleetAPI fleet, String dynamicMemberStatId, float base)
static CampaignFleetAPI getStationBaseFleet(MarketAPI market)
static CargoAPI getLocalResourcesCargo(MarketAPI market)
static Color getGrayColor()
static List< OfficerDataAPI > getMercs(CampaignFleetAPI fleet)
static float getDistance(SectorEntityToken from, SectorEntityToken to)
static long getSalvageSeed(SectorEntityToken entity)
static List< Token > tokenize(String string)
static boolean flagHasReason(MemoryAPI memory, String flagKey, String reason)
static MarketAPI getStationMarket(CampaignFleetAPI station)
static Color getHighlightColor()
static boolean isInsignificant(CampaignFleetAPI fleet)
static String getAndJoined(List< String > strings)
static void setMercHiredNow(PersonAPI person)
static float getRounded(float in)
static boolean setFlagWithReason(MemoryAPI memory, String flagKey, String reason, boolean value, float expire)
static CampaignFleetAPI getStationFleet(MarketAPI market)
static boolean isPlayerFactionSetUp()
static float getBattleJoinRange()
static void setRaidedTimestamp(MarketAPI market)
static Color getPositiveHighlightColor()
static float getAngleInDegrees(Vector2f v)
static String getRoundedValue(float value)
CargoAPI createCargo(boolean unlimitedStacks)
float getFloat(String key)
Color getColor(String id)
SoundAPI playUISound(String id, float pitch, float volume)
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)
CampaignFleetAPI getPrimary(List< CampaignFleetAPI > side)
List< CampaignFleetAPI > getSideFor(CampaignFleetAPI participantOrCombined)
List< CampaignFleetAPI > getOtherSide(BattleSide side)
List< CampaignFleetAPI > getSide(BattleSide side)
BattleSide pickSide(CampaignFleetAPI fleet)
CampaignFleetAPI getOtherSideCombined(BattleSide side)
boolean knowsWhoPlayerIs(List< CampaignFleetAPI > side)
List< CampaignFleetAPI > getNonPlayerSide()
FleetMemberAPI getFlagship()
FleetDataAPI getFleetData()
MutableFleetStatsAPI getStats()
boolean isValidPlayerFleet()
void removeFuel(float quantity)
void removeMarines(int quantity)
MutableValue getCredits()
void removeCrew(int quantity)
MemoryAPI getMemoryWithoutUpdate()
String getDisplayNameHasOrHave()
MemoryAPI getMemoryWithoutUpdate()
String getPersonNamePrefixAOrAn()
String getDisplayNameWithArticleWithoutArticle()
String getDisplayNameWithArticle()
boolean getCustomBoolean(String key)
String getPersonNamePrefix()
boolean isHostileTo(FactionAPI other)
String getDisplayNameIsOrAre()
boolean isNeutralFaction()
String getDisplayNameLong()
FleetMemberAPI getMemberWithCaptain(PersonAPI captain)
void removeOfficer(PersonAPI person)
List< FleetMemberAPI > getMembersListCopy()
void setInteractionTarget(SectorEntityToken interactionTarget)
void setPlugin(InteractionDialogPlugin plugin)
TextPanelAPI getTextPanel()
VisualPanelAPI getVisualPanel()
InteractionDialogPlugin getPlugin()
void showGroundRaidTargetPicker(String title, String okText, MarketAPI market, List< GroundRaidObjectivePlugin > data, GroundRaidTargetPickerDelegate listener)
SectorEntityToken getInteractionTarget()
void setPromptText(String promptText)
OptionPanelAPI getOptionPanel()
void addScript(EveryFrameScript script)
List< CampaignFleetAPI > getFleets()
void setTooltip(Object data, String tooltipText)
void setTooltipHighlightColors(Object data, Color ... colors)
void addOptionConfirmation(Object optionId, String text, String yes, String no)
void setTooltipHighlights(Object data, String ... highlights)
void addOption(String text, Object data)
void setEnabled(Object data, boolean enabled)
void setShortcut(Object data, int code, boolean ctrl, boolean alt, boolean shift, boolean putLast)
CampaignFleetAPI getPlayerFleet()
ReputationAdjustmentResult adjustPlayerReputation(Object action, String factionId)
CampaignClockAPI getClock()
List< FactionAPI > getAllFactions()
FactionAPI getPlayerFaction()
void setPaused(boolean paused)
MutableCharacterStatsAPI getPlayerStats()
MemoryAPI getMemoryWithoutUpdate()
CharacterDataAPI getCharacterData()
LocationAPI getContainingLocation()
boolean isInCurrentLocation()
void addScript(EveryFrameScript script)
PersonAPI getActivePerson()
void setActivePerson(PersonAPI activePerson)
SectorEntityToken getOrbitFocus()
boolean hasTag(String tag)
float getCircularOrbitRadius()
MemoryAPI getMemoryWithoutUpdate()
float getCircularOrbitPeriod()
boolean isTransponderOn()
LabelAPI addPara(String text)
LabelAPI addParagraph(String text)
TooltipMakerAPI beginTooltip()
void showImagePortion(String category, String id, float x, float y, float w, float h, float xOffset, float yOffset, float displayWidth, float displayHeight)
void showLoot(String title, CargoAPI otherCargo, boolean generatePods, CoreInteractionListener listener)
MarketAPI getMarket(String id)
List< MarketAPI > getMarkets(LocationAPI loc)
void setDisrupted(float days)
String getNameForModifier()
IndustrySpecAPI getSpec()
LocationAPI getContainingLocation()
boolean isPlanetConditionMarketOnly()
MutableMarketStatsAPI getStats()
MemoryAPI getMemoryWithoutUpdate()
String addCondition(String id)
List< Industry > getIndustries()
boolean hasCondition(String id)
SectorEntityToken getPrimaryEntity()
float getFloat(String key)
void advance(float amount)
String getString(String key)
float getExpire(String key)
void expire(String key, float days)
boolean contains(String key)
void set(String key, Object value)
void addXP(long xp, TextPanelAPI textPanel, boolean withMessage, boolean allowBonusXP, boolean withLevelUp)
MemoryAPI getMemoryWithoutUpdate()
ShipVariantAPI getVariant()
void setCaptain(PersonAPI commander)
DynamicStatsAPI getDynamic()
DynamicStatsAPI getDynamic()
boolean withContinueBeforeResult()
int performRaid(CargoAPI loot, Random random, float lootMult, TextPanelAPI text)
RaidDangerLevel getDisruptDanger()
void setHighlight(int start, int end)
void setHighlightColors(Color ... colors)
MutableStat getStat(String id)
StatBonus getMod(String id)