1package com.fs.starfarer.api.impl;
3import java.io.IOException;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.Comparator;
7import java.util.LinkedHashSet;
10import java.util.Random;
13import org.json.JSONArray;
14import org.json.JSONException;
15import org.json.JSONObject;
17import com.fs.starfarer.api.Global;
18import com.fs.starfarer.api.campaign.BattleAPI;
19import com.fs.starfarer.api.campaign.CampaignFleetAPI;
20import com.fs.starfarer.api.campaign.CargoAPI;
21import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
22import com.fs.starfarer.api.campaign.FactionAPI;
23import com.fs.starfarer.api.campaign.FactionAPI.ShipPickMode;
24import com.fs.starfarer.api.campaign.FactionDoctrineAPI;
25import com.fs.starfarer.api.campaign.FactionSpecAPI;
26import com.fs.starfarer.api.campaign.econ.MarketAPI;
27import com.fs.starfarer.api.characters.PersonAPI;
28import com.fs.starfarer.api.characters.SkillSpecAPI;
29import com.fs.starfarer.api.combat.BaseEveryFrameCombatPlugin;
30import com.fs.starfarer.api.combat.DeployedFleetMemberAPI;
31import com.fs.starfarer.api.combat.ShipAPI;
32import com.fs.starfarer.api.combat.ShipAPI.HullSize;
33import com.fs.starfarer.api.combat.ShipCommand;
34import com.fs.starfarer.api.combat.ShipHullSpecAPI.ShipTypeHints;
35import com.fs.starfarer.api.combat.ShipSystemSpecAPI;
36import com.fs.starfarer.api.combat.ShipVariantAPI;
37import com.fs.starfarer.api.fleet.FleetMemberAPI;
38import com.fs.starfarer.api.impl.campaign.DModManager;
39import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflater;
40import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflaterParams;
41import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
42import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
43import com.fs.starfarer.api.impl.campaign.ids.Commodities;
44import com.fs.starfarer.api.impl.campaign.ids.Factions;
45import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
46import com.fs.starfarer.api.impl.campaign.ids.Personalities;
47import com.fs.starfarer.api.impl.campaign.ids.ShipRoles;
48import com.fs.starfarer.api.impl.campaign.ids.Skills;
49import com.fs.starfarer.api.impl.campaign.ids.Tags;
50import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
51import com.fs.starfarer.api.impl.campaign.intel.misc.SimUpdateIntel;
52import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerQuality;
53import com.fs.starfarer.api.impl.campaign.procgen.themes.RemnantOfficerGeneratorPlugin;
54import com.fs.starfarer.api.input.InputEventAPI;
55import com.fs.starfarer.api.loading.FighterWingSpecAPI;
56import com.fs.starfarer.api.loading.HullModSpecAPI;
57import com.fs.starfarer.api.loading.VariantSource;
58import com.fs.starfarer.api.loading.WeaponSlotAPI;
59import com.fs.starfarer.api.loading.WeaponSpecAPI;
60import com.fs.starfarer.api.mission.FleetSide;
61import com.fs.starfarer.api.plugins.AutofitPlugin.AutofitPluginDelegate;
62import com.fs.starfarer.api.plugins.AutofitPlugin.AvailableFighter;
63import com.fs.starfarer.api.plugins.AutofitPlugin.AvailableWeapon;
64import com.fs.starfarer.api.plugins.SimulatorPlugin;
65import com.fs.starfarer.api.plugins.impl.CoreAutofitPlugin;
66import com.fs.starfarer.api.ui.Alignment;
67import com.fs.starfarer.api.ui.TooltipMakerAPI;
68import com.fs.starfarer.api.util.CountingMap;
69import com.fs.starfarer.api.util.Misc;
70import com.fs.starfarer.api.util.WeightedRandomPicker;
150 public static class SimUnlocksData {
151 public LinkedHashSet<String> factions =
new LinkedHashSet<String>();
152 public LinkedHashSet<String> variants =
new LinkedHashSet<String>();
154 public void fromJSON(JSONObject json) {
155 factions =
new LinkedHashSet<String>();
156 JSONArray arr = json.optJSONArray(
"factions");
158 for (
int i = 0; i < arr.length(); i++) {
159 String value = arr.optString(i);
165 variants =
new LinkedHashSet<String>();
166 arr = json.optJSONArray(
"variants");
168 for (
int i = 0; i < arr.length(); i++) {
169 String value = arr.optString(i);
177 public JSONObject toJSON() throws JSONException {
178 JSONObject json =
new JSONObject();
180 JSONArray arr1 =
new JSONArray();
181 for (String value : factions) {
184 JSONArray arr2 =
new JSONArray();
185 for (String value : variants) {
189 json.put(
"factions", arr1);
190 json.put(
"variants", arr2);
243 JSONArray arr = json.optJSONArray(
"opponents");
245 for (
int i = 0; i < arr.length(); i++) {
246 String variantId = arr.getString(i);
254 }
catch (IOException e) {
256 }
catch (JSONException e) {
263 JSONObject json =
new JSONObject();
264 JSONArray arr =
new JSONArray();
268 json.put(
"opponents", arr);
270 }
catch (JSONException e) {
272 }
catch (IOException e) {
288 uiStateData.groupSize = 0;
301 uiStateData.showAdvanced =
false;
304 }
catch (IOException e) {
306 }
catch (JSONException e) {
315 }
catch (JSONException e) {
317 }
catch (IOException e) {
339 }
catch (IOException e) {
341 }
catch (JSONException e) {
350 }
catch (JSONException e) {
352 }
catch (IOException e) {
362 List<AdvancedSimOption> result =
new ArrayList<AdvancedSimOption>();
369 boolean customFaction = custom || civ || dev || defaultCat || other;
371 JSONObject json = category.faction.
getCustom().optJSONObject(
"simulatorData");
372 boolean standardAICores = json !=
null && json.optBoolean(
"standardAICores");
373 boolean derelictAICores = json !=
null && json.optBoolean(
"derelictAICores");
374 boolean omegaAICores = json !=
null && json.optBoolean(
"omegaAICores");
375 boolean noOfficers = json !=
null && json.optBoolean(
"noOfficers");
377 boolean showOfficers = !standardAICores && !derelictAICores && !omegaAICores && !noOfficers;
378 boolean integrateCores = standardAICores || derelictAICores || dev || custom || other;
380 if (custom || defaultCat || other) {
382 standardAICores =
true;
383 integrateCores =
true;
386 String aggroExtra =
"";
388 if (custom || defaultCat || dev || other) {
389 aggroExtra =
"\n\nDoes not affect AI cores or automated ships.";
390 aiExtra =
"\n\nOnly affects automated ships.";
393 String aggroTitle =
"Aggression / behavior";
396 aggroTitle =
"Behavior";
400 SimOptionSelectorData aggro =
new SimOptionSelectorData(aggroId, aggroTitle,
true);
402 if (custom || defaultCat || civ || dev || other) {
403 aggro.options.add(
new SimOptionData(
AGGRO_DEFAULT,
"Default (steady)",
406 aggro.options.add(
new SimOptionData(
AGGRO_DEFAULT,
"Faction default",
407 "Default aggression level for the selected faction." + aggroExtra,
"behavior_default"));
411 aggro.options.add(
new SimOptionData(
AGGRO_STEADY,
"Steady",
418 aggro.options.add(
new SimOptionData(
AGGRO_NORMAL,
"Normal",
"Opposing ships will behave normally.",
"behavior_default"));
421 aggro.options.add(
new SimOptionData(
AGGRO_DO_NOTHING,
"Do nothing",
"Opposing ships will not move, use shields, fire weapons, or take any other actions.",
"behavior_passive"));
423 aggro.options.get(aggro.options.size() - 1).extraPad = 10f;
425 aggro.options.add(
new SimOptionData(
AGGRO_DEFENSES,
"Stationary, defenses only",
"Opposing ships will not move, but will use shields/phase cloak/other defenses and defensive ship systems, if any.",
"behavior_defensive"));
426 aggro.options.add(
new SimOptionData(
AGGRO_STATIONARY,
"Stationary",
"Opposing ships will not move, but will otherwise behave normally.",
"behavior_stationary"));
427 aggro.compact =
false;
433 SimOptionSelectorData officers =
new SimOptionSelectorData(
OFFICERS_CUSTOM_ID,
"Officers",
true);
434 officers.options.add(
new SimOptionData(
OFFICERS_CUSTOM_NONE,
"None",
"No officers on any opposing ships.",
"officers_none"));
435 officers.options.add(
new SimOptionData(
OFFICERS_CUSTOM_SOME,
"Some",
"Some officers, up to level 5.",
"officers_some"));
436 officers.options.add(
new SimOptionData(
OFFICERS_CUSTOM_5,
"All ships, level 5",
"Level 5 officers on all opposing ships.",
"officers_all"));
437 officers.options.add(
new SimOptionData(
OFFICERS_CUSTOM_6,
"All ships, level 6",
"Level 6 officers on all opposing ships.",
"officers_high"));
438 result.add(officers);
440 SimOptionSelectorData officers =
new SimOptionSelectorData(
OFFICERS_ID,
"Officers",
true);
441 officers.options.add(
new SimOptionData(
OFFICERS_NONE,
"None",
"No officers on any opposing ships.",
"officers_none"));
442 officers.options.add(
new SimOptionData(
OFFICERS_DEFAULT,
"Faction default",
"Default number and level of officers for the selected faction.",
"officers_some"));
443 officers.options.add(
new SimOptionData(
OFFICERS_ALL,
"All ships",
"Maximum level officers on all opposing ships.",
"officers_high"));
444 result.add(officers);
448 if (standardAICores || derelictAICores || omegaAICores || custom || defaultCat || dev || other) {
452 }
else if (omegaAICores) {
454 }
else if (derelictAICores) {
457 SimOptionSelectorData cores =
new SimOptionSelectorData(coresId,
"AI cores",
false);
458 cores.options.add(
new SimOptionData(
AI_CORES_NONE,
"None",
"No AI cores on any opposing ships.",
"cores_none"));
463 boolean enableMixed = enableAlpha || (derelictAICores && enableGamma);
465 String reqGamma =
null;
466 if (!enableGamma) reqGamma =
"Requires a Gamma Core or better in your cargo.";
467 String reqBeta =
null;
468 if (!enableBeta) reqBeta =
"Requires a Beta Core or better in your cargo.";
469 String reqAlpha =
null;
470 if (!enableAlpha) reqAlpha =
"Requires an Alpha Core in your cargo.";
471 String reqMixed =
null;
473 if (derelictAICores) {
474 reqMixed =
"Requires a Gamma Core or better in your cargo.";
476 reqMixed =
"Requires an Alpha Core in your cargo.";
480 String coresCargoNote =
"";
481 String ifPossible =
"";
483 coresCargoNote =
" The AI cores used are limited to the total number and type "
484 +
"of cores in your cargo (and storage, if docked).";
485 ifPossible =
", if possible";
486 boolean canUseCores = enableGamma || enableBeta || enableAlpha || enableMixed;
488 enableGamma = enableBeta = enableAlpha = enableMixed =
true;
489 reqGamma = reqBeta = reqAlpha = reqMixed =
null;
491 enableGamma = enableBeta = enableAlpha = enableMixed =
false;
492 reqGamma = reqBeta = reqAlpha = reqMixed =
"No AI cores in cargo (or storage, if docked).";
496 if (standardAICores || derelictAICores || dev) {
497 cores.options.add(
new SimOptionData(
AI_CORES_SOME,
"Mixed",
"A mix of AI cores on some of the opposing ships, based on the number and size of opponents deployed." + coresCargoNote + aiExtra, enableMixed, reqMixed,
"cores_mixed"));
498 cores.options.add(
new SimOptionData(
AI_CORES_GAMMA,
"Gamma cores on all ships",
"A gamma core on every opposing ship" + ifPossible +
"." + coresCargoNote + aiExtra, enableGamma, reqGamma,
"cores_gamma"));
499 if (standardAICores || dev) {
500 cores.options.add(
new SimOptionData(
AI_CORES_BETA,
"Beta cores on all ships",
"A beta core on every opposing ship" + ifPossible +
"." + coresCargoNote + aiExtra, enableBeta, reqBeta,
"cores_beta"));
501 cores.options.add(
new SimOptionData(
AI_CORES_ALPHA,
"Alpha cores on all ships",
"An alpha core on every opposing ship" + ifPossible +
"." + coresCargoNote + aiExtra, enableAlpha, reqAlpha,
"cores_alpha"));
504 if (dev || omegaAICores) {
505 cores.options.add(
new SimOptionData(
AI_CORES_OMEGA,
"Omega cores on all ships",
"An omega core on every opposing ship." + aiExtra,
"cores_omega"));
508 cores.padAfter = 10f;
513 if (integrateCores) {
514 String iTooltipExtra =
"";
516 iTooltipExtra =
"\n\nDoes not affect omega cores.";
518 SimOptionCheckboxData integrate =
new SimOptionCheckboxData(
INTEGRATE_CORES_ID,
"Integrate AI cores",
519 "AI cores will be integrated into opposing ships, increasing each core's level by 1." + iTooltipExtra);
524 result.add(integrate);
528 SimOptionSelectorData quality =
new SimOptionSelectorData(
QUALITY_ID,
"Ship quality",
true);
529 quality.options.add(
new SimOptionData(
QUALITY_MAX_DMODS,
"Maximum d-mods",
"Five d-mods on all opposing ships.",
"quality_lowest"));
530 quality.options.add(
new SimOptionData(
QUALITY_SOME_DMODS,
"Some d-mods",
"Two to four d-mods on all opposing ships.",
"quality_low"));
531 quality.options.add(
new SimOptionData(
QUALITY_NO_DMODS,
"No d-mods",
"No d-mods on any opposing ships.",
"quality_no_dmods"));
532 quality.options.add(
new SimOptionData(
QUALITY_SOME_SDMODS,
"Some s-mods",
"One or two s-mods on all opposing ships.",
"quality_high"));
533 quality.options.add(
new SimOptionData(
QUALITY_MANY_SMODS,
"Many s-mods",
"Two or three s-mods on all opposing ships.",
"quality_highest"));
542 String rTooltipExtra =
"";
544 rTooltipExtra =
"\n\nFor the selected category, uses a broader set of weapons than is available to most factions.";
546 SimOptionCheckboxData loadouts =
new SimOptionCheckboxData(
RANDOMIZE_VARIANTS_ID,
"Randomized loadouts",
547 "Opposing ships have randomized loadouts when this setting is enabled." + rTooltipExtra);
548 result.add(loadouts);
559 boolean customFaction = custom || civ || dev || defaultCat;
561 if (civ)
return false;
567 SimCategoryData custom =
new SimCategoryData();
569 custom.name =
"Custom";
570 custom.custom =
true;
571 custom.nonFactionCategory =
true;
592 Set<String> civilian =
new LinkedHashSet<String>();
594 Set<String> other =
new LinkedHashSet<String>(
unlocksData.variants);
603 if (variants ==
null)
continue;
604 other.addAll(variants);
610 if (spec ==
null || spec.getCustom() ==
null)
continue;
612 JSONObject json = spec.getCustom().optJSONObject(
"simulatorData");
613 if (json ==
null)
continue;
615 boolean show = json.optBoolean(
"showInSimulator");
618 show &= fullUnlock ||
unlocksData.factions.contains(spec.getId());
622 boolean includeCiv = json.optBoolean(
"includeCivShipsWithFaction");
624 SimCategoryData data =
new SimCategoryData();
625 data.id = spec.getId();
627 data.nameColor = spec.getBaseUIColor();
628 data.iconName = spec.getCrest();
630 data.variants =
getVariants(spec, includeCiv,
false,
false);
631 data.maxVariants =
getVariants(spec, includeCiv,
false,
true).size();
635 civilian.addAll(
getVariants(spec,
true,
true,
false));
638 if (data.variants ==
null || data.variants.isEmpty())
continue;
640 other.removeAll(data.variants);
645 other.removeAll(civilian);
647 Collections.sort(result,
new Comparator<SimCategoryData>() {
648 public int compare(SimCategoryData o1, SimCategoryData o2) {
649 return o1.name.compareTo(o2.name);
654 result.add(0, custom);
656 SimCategoryData def =
new SimCategoryData();
658 def.name =
"Default";
659 def.nonFactionCategory =
true;
668 other.removeAll(def.variants);
670 if (!other.isEmpty()) {
671 SimCategoryData otherCat =
new SimCategoryData();
673 otherCat.name =
"Other";
674 otherCat.nonFactionCategory =
true;
677 otherCat.data =
null;
681 if (!otherCat.variants.isEmpty()) {
682 result.add(otherCat);
686 if (!civilian.isEmpty()) {
688 SimCategoryData civ =
new SimCategoryData();
690 civ.name =
"Civilian ships";
691 civ.nonFactionCategory =
true;
697 if (!civ.variants.isEmpty()) {
703 SimCategoryData dev =
new SimCategoryData();
705 dev.name =
"DevMode stuff";
706 dev.nonFactionCategory =
true;
720 if (spec ==
null)
return new ArrayList<String>();
727 Set<String> seen =
new LinkedHashSet<String>();
728 List<ShipVariantAPI> variantList =
new ArrayList<ShipVariantAPI>();
731 if (variants ==
null)
continue;
732 for (String variantId : variants) {
733 if (seen.contains(variantId))
continue;
738 if (!fullUnlock && !
unlocksData.variants.contains(variantId) &&
755 if (civ && !withCiv)
continue;
756 if (!civ && onlyCiv)
continue;
769 List<ShipVariantAPI> variantList =
new ArrayList<ShipVariantAPI>();
770 for (String
id : variants) {
778 List<String> variants =
new ArrayList<String>();
780 variants.add(v.getHullVariantId());
785 public static List<ShipVariantAPI>
sortVariantList(List<ShipVariantAPI> variantList) {
786 Collections.sort(variantList,
new Comparator<ShipVariantAPI>() {
795 if (diff != 0)
return (
int) Math.signum(-diff);
805 List<String> result =
new ArrayList<String>();
847 SimCategoryData category, Map<String, String> settings) {
853 boolean customFaction = custom || civ || dev || defaultCat;
860 if (officers !=
null) {
871 params.officerNumberBonus = 1000;
872 params.officerLevelBonus = 10;
875 params.officerNumberBonus = 1000;
876 params.officerLevelBonus = 10;
877 params.officerLevelLimit = 5;
880 params.officerNumberBonus = 1000;
881 params.officerLevelBonus = 10;
884 params.officerLevelLimit = 6;
892 boolean derelict =
false;
895 if (cores !=
null) derelict =
true;
908 params.doNotIntegrateAICores =
true;
910 boolean omega =
false;
913 params.aiCores = OfficerQuality.AI_GAMMA;
915 params.aiCores = OfficerQuality.AI_MIXED;
918 params.officerNumberBonus = 1000;
919 params.aiCores = OfficerQuality.AI_GAMMA;
922 params.officerNumberBonus = 1000;
923 params.aiCores = OfficerQuality.AI_BETA;
926 params.officerNumberBonus = 1000;
927 params.aiCores = OfficerQuality.AI_ALPHA;
930 params.officerNumberBonus = 1000;
931 params.aiCores = OfficerQuality.AI_OMEGA;
953 String personality =
null;
955 String aggro = (String) settings.get(
AGGRO_ID);
968 if (personality !=
null) {
974 member.setPersonalityOverride(personality);
995 if (member.getVariant().isStockVariant()) {
998 member.setVariant(copy,
false,
false);
1002 String quality = (String) settings.get(
QUALITY_ID);
1010 Random random =
new Random();
1012 int num = 2 + random.nextInt(3);
1016 Random random =
new Random();
1019 int num = 1 + random.nextInt(2);
1020 plugin.
addSMods(member, num,
this);
1023 Random random =
new Random();
1026 int num = 2 + random.nextInt(2);
1027 plugin.
addSMods(member, num,
this);
1047 String aggro = (String) settings.get(
AGGRO_ID);
1049 final String aggro2 = aggro;
1052 final ShipAPI ship = member.getShip();
1053 if (ship ==
null)
continue;
1055 if (ship.
getOwner() == 0)
continue;
1061 protected float elapsed = 0f;
1063 public void advance(
float amount, List<InputEventAPI> events) {
1068 if (elapsed > 0.1f) {
1070 elapsed = -10000000f;
1085 final ShipAPI ship = member.getShip();
1086 if (ship ==
null)
continue;
1088 if (ship.
getOwner() == 0)
continue;
1092 protected float elapsed = 0f;
1094 public void advance(
float amount, List<InputEventAPI> events) {
1099 if (elapsed > 0.1f) {
1101 elapsed = -10000000f;
1109 curr.setHoldFire(
true);
1125 if (curr.getSystem() !=
null && curr.getSystem().getSpecAPI() !=
null) {
1134 if (curr.getSystem() !=
null && curr.getSystem().getSpecAPI() !=
null) {
1195 PersonAPI captain = member.getCaptain();
1196 if (!member.isFlagship() && !captain.
isDefault()) {
1201 if (member.isFlagship()) {
1202 PersonAPI captain = member.getCaptain();
1203 member.setFlagship(
false,
false);
1218 List<String> result =
new ArrayList<String>();
1219 if (category.variants.isEmpty())
return result;
1232 for (String variantId : category.variants) {
1244 deploymentPoints * 1f,
1252 params.maxNumShips = 100;
1253 params.factionOverride = faction;
1254 params.ignoreMarketFleetSizeMult =
true;
1255 params.withOfficers =
false;
1256 params.modeOverride = ShipPickMode.PRIORITY_THEN_ALL;
1298 List<String> ids =
new ArrayList<String>();
1300 ids.add(mod.getId());
1307 float currDP =
getDP(fleet);
1308 if (currDP > targetDP) {
1311 float fpRem = currDP - targetDP;
1317 counts.
add(curr.getHullSpec().getHullSize());
1321 float dp = curr.getDeploymentPointsCost();
1323 int count = counts.
getCount(curr.getHullSpec().getHullSize());
1330 picker.
add(curr, dp * mult);
1334 if (pick ==
null)
break;
1346 total += member.getDeploymentPointsCost();
1364 LinkedHashSet<String> addedFactions =
new LinkedHashSet<String>();
1365 LinkedHashSet<String> addedVariants =
new LinkedHashSet<String>();
1368 if (fleet.getFaction() ==
null ||
1369 fleet.getFaction().getFactionSpec() ==
null ||
1370 fleet.getFaction().getFactionSpec().getCustom() ==
null)
continue;
1371 JSONObject json = fleet.getFaction().getFactionSpec().getCustom().optJSONObject(
"simulatorData");
1372 if (json ==
null)
continue;
1373 boolean show = json.optBoolean(
"showInSimulator");
1374 if (!show)
continue;
1381 addedFactions.add(fid);
1396 addedVariants.add(vid);
1402 if (!addedVariants.isEmpty()) {
1404 new LinkedHashSet<String>(addedVariants)))));
1407 if (!addedFactions.isEmpty() || !addedVariants.isEmpty()) {
1416 if (v ==
null)
return false;
1442 float bestScore = 0f;
1445 if (spec ==
null || spec.getCustom() ==
null)
continue;
1447 JSONObject json = spec.getCustom().optJSONObject(
"simulatorData");
1448 if (json ==
null)
continue;
1450 boolean show = json.optBoolean(
"showInSimulator");
1451 if (!show)
continue;
1455 Set<String> allVariants =
new LinkedHashSet<String>();
1456 for (String roleId : roles) {
1464 if (vid ==
null)
continue;
1466 if (allVariants.contains(vid)) {
1471 total = Math.max(total, 1f);
1472 float score = matches / total;
1473 if (faction.
getId().equals(fleetFactionId)) {
1476 if (score > bestScore) {
1482 if (best ==
null || bestScore <= 0)
return fleetFactionId;
1483 return best.
getId();
1494 if (coreId ==
null)
continue;
1496 current.
add(coreId, 1);
1500 remove.putAll(current);
1501 for (String
id : availableCores.keySet()) {
1502 remove.sub(
id, availableCores.
getCount(
id));
1505 if (
remove.isEmpty())
return;
1510 if (coreId ==
null)
continue;
1512 if (
remove.getCount(coreId) > 0) {
1513 picker.
add(member, member.getDeploymentPointsCost());
1517 while (!
remove.isEmpty() && !picker.
isEmpty()) {
1521 if (
remove.getCount(coreId) > 0) {
1522 remove.sub(coreId, 1);
1529 if (member ==
null)
return null;
1531 if (captain ==
null || captain.
isDefault() || !captain.
isAICore())
return null;;
1540 availableCores.putAll(cargoCores);
1541 for (String
id : deployedCores.keySet()) {
1542 availableCores.
sub(
id, deployedCores.
getCount(
id));
1544 return availableCores;
1551 if (member.getShip() ==
null)
continue;
1552 PersonAPI captain = member.getShip().getCaptain();
1555 if (coreId ==
null)
continue;
1575 if (cargo !=
null) {
1586 if (option.getId().equals(
AI_CORES_ID) && extra !=
null) {
1593 for (String
id : cores.keySet()) {
1607 for (String
id : cores.keySet()) {
1621 for (String
id : cores.keySet()) {
static SettingsAPI getSettings()
static FactoryAPI getFactory()
static CombatEngineAPI getCombatEngine()
static SectorAPI getSector()
static String AI_CORES_SOME
SimUIStateData uiStateData
static boolean isShowDevCategories()
static String AI_CORES_GAMMA
static boolean REQUIRE_AI_CORES
static String OFFICERS_ALL
boolean isRequireAICoresInCargo()
static String OFFICERS_CUSTOM_5
static String QUALITY_MAX_DMODS
List< AvailableWeapon > getAvailableWeapons()
List< String > generateSelection(SimCategoryData category, int deploymentPoints)
static String OFFICERS_DEFAULT
static String AGGRO_DEFENSES
String getCoreId(FleetMemberAPI member)
Set< String > defaultOpponents
static String AI_CORES_DEV_ID
static String AGGRO_CAUTIOUS
CountingMap< String > getAvailableAICores()
static boolean isAllStandardStuffUnlocked()
static boolean isSimFullyUnlocked()
static String AI_CORES_BETA
static String INTEGRATE_CORES_ID
static String AGGRO_STEADY
boolean canAddRemoveHullmodInPlayerCampaignRefit(String modId)
static String AGGRO_ID_CORES_ONLY
static String AI_CORES_OMEGA
static void pruneFleetDownToDP(CampaignFleetAPI fleet, float targetDP, Random random)
void applySettingsToFleetMembers(List< FleetMemberAPI > members, SimCategoryData category, Map< String, String > settings)
void clearFighterSlot(int index, ShipVariantAPI variant)
static String OFFICERS_ID
static boolean REQUIRE_AI_CORES_IN_CARGO
void syncUIWithVariant(ShipVariantAPI variant)
static String CUSTOM_OPPONENTS_FILE
void addCustomOpponents(List< String > variants)
static String OFFICERS_CUSTOM_ID
void saveCustomOpponents()
void fitFighterInSlot(int index, AvailableFighter fighter, ShipVariantAPI variant)
List< String > getAvailableHullmods()
static String AI_CORES_DERELICT_ID
static String QUALITY_SOME_SDMODS
static String AGGRO_DO_NOTHING
List< AdvancedSimOption > getSimOptions(SimCategoryData category)
SimUnlocksData unlocksData
static String AGGRO_DEFAULT
static String AI_CORES_ALPHA
static String OTHER_CAT_ID
CountingMap< String > getDeployedAICores()
void appendToTooltip(TooltipMakerAPI info, float initPad, float width, AdvancedSimOption option, Object extra)
static String CUSTOM_CAT_ID
void removeCustomOpponents(List< String > variants)
CountingMap< String > getAvailableMinusDeployedAICores()
void clearCustomOpponents()
boolean showGroupDeploymentWidget(SimCategoryData category)
static String OFFICERS_CUSTOM_SOME
static List< String > getVariantIDList(List< ShipVariantAPI > variantList)
static String DEFAULT_CAT_ID
SimUIStateData getUIStateData()
static String QUALITY_SOME_DMODS
void pruneAICoresToAvailable(List< FleetMemberAPI > members)
Set< String > customOpponents
void clearWeaponSlot(WeaponSlotAPI slot, ShipVariantAPI variant)
static String OFFICERS_CUSTOM_6
static List< String > getAllRoles()
void loadCustomOpponents()
static String UNLOCKS_DATA_FILE
void resetToDefaults(boolean withSave)
FleetMemberAPI getFleetMember()
static String OFFICERS_NONE
static String OFFICERS_CUSTOM_NONE
void reportPlayerBattleOccurred(CampaignFleetAPI primaryWinner, BattleAPI battle)
static String AI_CORES_NONE
static String AGGRO_AGGRESSIVE
static String QUALITY_MANY_SMODS
static List< ShipVariantAPI > getVariantList(Set< String > variants)
boolean isPriority(FighterWingSpecAPI wing)
static List< ShipVariantAPI > sortVariantList(List< ShipVariantAPI > variantList)
static void makeFleetCommanderNormalOfficer(List< FleetMemberAPI > members)
boolean coreReqsMet(String coreId)
List< String > getVariants(FactionSpecAPI spec, boolean withCiv, boolean onlyCiv, boolean forceFullUnlock)
List< SimCategoryData > getCategories()
static String AI_CORES_ID
void applySettingsToDeployed(List< DeployedFleetMemberAPI > deployed, Map< String, String > settings)
boolean isAllowSlightRandomization()
static boolean INCLUDE_PLAYER_BLUEPRINTS
static String AGGRO_NORMAL
String getStockVariantId(FleetMemberAPI member)
SimUnlocksData getUnlocksData()
static String UI_STATE_DATA_FILE
boolean isPlayerCampaignRefit()
void fitWeaponInSlot(WeaponSlotAPI slot, AvailableWeapon weapon, ShipVariantAPI variant)
static String QUALITY_NO_DMODS
static String AGGRO_RECKLESS
static FactionAPI createCustomFaction()
static String AI_CORES_OMEGA_ID
static String AGGRO_STATIONARY
List< AvailableFighter > getAvailableFighters()
boolean isAcceptableSimVariant(ShipVariantAPI v, boolean forLearning)
SimCategoryData getCustomCategory()
boolean isPriority(WeaponSpecAPI weapon)
String findBestMatchingFaction(String fleetFactionId, List< FleetMemberAPI > members)
static float getDP(CampaignFleetAPI fleet)
static String RANDOMIZE_VARIANTS_ID
static void addDMods(FleetMemberData data, boolean own, CampaignFleetAPI recoverer, Random random)
void inflate(CampaignFleetAPI fleet)
static void addCommanderAndOfficersV2(CampaignFleetAPI fleet, FleetParamsV3 params, Random random)
static CampaignFleetAPI createFleet(FleetParamsV3 params)
static final String ALPHA_CORE
static final String BETA_CORE
static final String GAMMA_CORE
static final String NEUTRAL
static final String MERCENARY
static final String INDEPENDENT
static final String PATROL_LARGE
static final String RECKLESS
static final String STEADY
static final String AGGRESSIVE
static final String CAUTIOUS
static final String UTILITY
static final String TANKER_LARGE
static final String COMBAT_CAPITAL
static final String COMBAT_LARGE
static final String PERSONNEL_LARGE
static final String TANKER_SMALL
static final String PHASE_MEDIUM
static final String LINER_SMALL
static final String COMBAT_SMALL
static final String CARRIER_LARGE
static final String CIV_RANDOM
static final String COMBAT_FREIGHTER_MEDIUM
static final String FREIGHTER_MEDIUM
static final String COMBAT_MEDIUM
static final String PHASE_LARGE
static final String COMBAT_FREIGHTER_SMALL
static final String PERSONNEL_MEDIUM
static final String PHASE_CAPITAL
static final String COMBAT_FREIGHTER_LARGE
static final String FREIGHTER_LARGE
static final String TANKER_MEDIUM
static final String CARRIER_SMALL
static final String LINER_MEDIUM
static final String FREIGHTER_SMALL
static final String PHASE_SMALL
static final String CARRIER_MEDIUM
static final String LINER_LARGE
static final String PERSONNEL_SMALL
static final String OFFICER_TRAINING
static final String INDENT
void setPutCoresOnCivShips(boolean putCoresOnCivShips)
void setForceNoCommander(boolean forceNoCommander)
void addCommanderAndOfficers(CampaignFleetAPI fleet, FleetParamsV3 params, Random random)
void setForceIntegrateCores(boolean forceIntegrateCores)
void addSMods(FleetMemberAPI member, int numSmods, AutofitPluginDelegate delegate)
void add(K key, int quantity)
static List< FleetMemberAPI > getSnapshotMembersLost(CampaignFleetAPI fleet)
static String ucFirst(String str)
static CargoAPI getStorageCargo(MarketAPI market)
static boolean isAutomated(MutableShipStatsAPI stats)
static Color getBasePlayerColor()
CargoAPI createCargo(boolean unlimitedStacks)
CampaignFleetAPI createEmptyFleet(String factionId, String name, boolean aiMode)
List< String > getSimOpponentsDev()
List< String > getSimOpponents()
List< FactionSpecAPI > getAllFactionSpecs()
String getSpriteName(String category, String id)
FactionSpecAPI getFactionSpec(String id)
ShipVariantAPI getVariant(String variantId)
SkillSpecAPI getSkillSpec(String skillId)
List< HullModSpecAPI > getAllHullModSpecs()
boolean getBoolean(String key)
boolean fileExistsInCommon(String filename)
float getFloat(String key)
void writeJSONToCommon(String filename, JSONObject json, boolean onlyIfChanged)
FactionAPI createBaseFaction(String factionId)
PersonalityAPI getPersonaltySpec(String id)
List< String > getSkillIds()
JSONObject readJSONFromCommon(String filename, boolean putInWriteCache)
List< CampaignFleetAPI > getNonPlayerSideSnapshot()
void setCommander(PersonAPI commander)
FleetDataAPI getFleetData()
float getQuantity(CargoAPI.CargoItemType type, Object data)
float getCommodityQuantity(String id)
void addCommodity(String commodityId, float quantity)
void clearShipRoleCache()
void addKnownShip(String hullId, boolean setTimestamp)
void addKnownFighter(String wingId, boolean setTimestamp)
Set< String > getVariantsForRole(String roleId)
void addKnownWeapon(String weaponId, boolean setTimestamp)
Set< String > getKnownFighters()
Set< String > getKnownWeapons()
Set< String > getPriorityWeapons()
LinkedHashSet< String > getRestrictToVariants()
Set< String > getKnownShips()
Set< String > getKnownHullMods()
Map< String, Float > getHullFrequency()
void addKnownHullMod(String modId)
FactionDoctrineAPI getDoctrine()
Set< String > getPriorityFighters()
void setOfficerQuality(int officerQuality)
void copyToDoctrine(FactionDoctrineAPI other)
void setCarriers(int carriers)
void setPhaseShips(int phaseShips)
void setWarships(int warships)
void setAutofitRandomizeProbability(float autofitRandomizeProbability)
void setNumShips(int numShips)
void setAggression(int aggression)
void setShipSize(int shipSize)
void addFleetMember(FleetMemberAPI member)
void removeFleetMember(FleetMemberAPI member)
List< FleetMemberAPI > getMembersListCopy()
CampaignFleetAPI getPlayerFleet()
MarketAPI getCurrentlyOpenMarket()
FactionAPI getPlayerFaction()
FactionAPI getFaction(String factionId)
void setSkillLevel(String id, float level)
MutableCharacterStatsAPI getStats()
void setPersonality(String personality)
CombatFleetManagerAPI getFleetManager(FleetSide side)
boolean isInCampaignSim()
void removePlugin(EveryFrameCombatPlugin plugin)
void addPlugin(EveryFrameCombatPlugin plugin)
List< DeployedFleetMemberAPI > getDeployedCopyDFM()
List< ShipAPI > getChildModulesCopy()
void setHoldFire(boolean holdFire)
void setShipAI(ShipAIPlugin ai)
ShipSystemAPI getTravelDrive()
void giveCommand(ShipCommand command, Object param, int groupNumber)
boolean hasTag(String tag)
EnumSet< ShipTypeHints > getHints()
float getSuppliesToRecover()
boolean hasTag(String tag)
boolean hasTag(String tag)
String getOriginalVariant()
ShipAPI.HullSize getHullSize()
String getHullVariantId()
ShipHullSpecAPI getHullSpec()
void setSource(VariantSource source)
ShipVariantAPI getVariant()
float getDeploymentPointsCost()
void setCaptain(PersonAPI commander)