51 public static class SDMParams {
52 public SectorEntityToken entity;
53 public String factionId;
59 public static interface SalvageDefenderModificationPlugin
extends GenericPlugin {
60 float getStrength(SDMParams p,
float strength, Random random,
boolean withOverride);
61 float getProbability(SDMParams p,
float probability, Random random,
boolean withOverride);
62 float getQuality(SDMParams p,
float quality, Random random,
boolean withOverride);
63 float getMaxSize(SDMParams p,
float maxSize, Random random,
boolean withOverride);
64 float getMinSize(SDMParams p,
float minSize, Random random,
boolean withOverride);
66 void modifyFleet(SDMParams p, CampaignFleetAPI fleet, Random random,
boolean withOverride);
67 void reportDefeated(SDMParams p, SectorEntityToken entity, CampaignFleetAPI fleet);
74 public static class SalvageDefenderModificationPluginImpl
extends BaseGenericPlugin implements SalvageDefenderModificationPlugin {
75 public float getStrength(SDMParams p,
float strength, Random random,
boolean withOverride) {
76 if (withOverride)
return strength;
77 if (Factions.DERELICT.equals(p.factionId)) {
79 if (p.entity.getMemoryWithoutUpdate().getBoolean(
"$limboWormholeCache") ||
80 p.entity.getMemoryWithoutUpdate().getBoolean(
"$limboMiningStation")) {
87 String type = p.entity.getCustomEntityType();
89 if (Entities.DERELICT_SURVEY_PROBE.equals(type)) {
91 }
else if (Entities.DERELICT_SURVEY_SHIP.equals(type)) {
93 }
else if (Entities.DERELICT_MOTHERSHIP.equals(type) || Entities.DERELICT_CRYOSLEEPER.equals(type)) {
101 if (bonus > limit) bonus = limit;
102 return strength + (int) bonus;
106 public float getMinSize(SDMParams p,
float minSize, Random random,
boolean withOverride) {
107 if (withOverride)
return minSize;
110 public float getMaxSize(SDMParams p,
float maxSize, Random random,
boolean withOverride) {
111 if (withOverride)
return maxSize;
112 if (Factions.DERELICT.equals(p.factionId)) {
114 String type = p.entity.getCustomEntityType();
116 if (Entities.DERELICT_SURVEY_PROBE.equals(type)) {
117 if (bonus >= 5) bonusSize = 2;
120 return Math.max(maxSize, bonusSize);
124 public float getProbability(SDMParams p,
float probability, Random random,
boolean withOverride) {
125 if (withOverride)
return probability;
126 if (Factions.DERELICT.equals(p.factionId)) {
127 String type = p.entity.getCustomEntityType();
129 if (Entities.DERELICT_SURVEY_PROBE.equals(type)) {
131 }
else if (Entities.DERELICT_SURVEY_SHIP.equals(type)) {
134 if (limit <= 0 || probability >= 1f)
return probability;
137 if (bonus > limit) bonus = limit;
139 return probability * (1f - 0.5f * bonus / limit);
143 public void reportDefeated(SDMParams p, SectorEntityToken entity, CampaignFleetAPI fleet) {
144 if (Factions.DERELICT.equals(p.factionId)) {
146 for (FleetMemberAPI member : Misc.getSnapshotMembersLost(fleet)) {
148 total += member.getFleetPointCost();
153 public void modifyFleet(SDMParams p, CampaignFleetAPI fleet, Random random,
boolean withOverride) {
154 if (Factions.OMEGA.equals(fleet.getFaction().getId())) {
155 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
156 ShipVariantAPI copy = member.getVariant().clone();
157 member.setVariant(copy,
false,
false);
158 copy.addTag(Tags.SHIP_LIMITED_TOOLTIP);
165 d.group =
"omega_weapons_small";
166 fleet.addDropRandom(d);
171 d.group =
"omega_weapons_medium";
172 fleet.addDropRandom(d);
174 long seed = Misc.getSalvageSeed(p.entity);
175 fleet.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SEED, Misc.getRandom(seed, 11).nextLong());
177 if (Entities.ALPHA_SITE_WEAPONS_CACHE.equals(p.entity.getCustomEntityType())) {
178 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE);
179 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
180 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random);
181 member.setCaptain(person);
182 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(member);
183 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR());
185 if (fleet.getInflater() instanceof DefaultFleetInflater) {
186 DefaultFleetInflater dfi = (DefaultFleetInflater) fleet.getInflater();
187 ((DefaultFleetInflaterParams)dfi.getParams()).allWeapons =
true;
190 if (p.entity !=
null && p.entity.getMemoryWithoutUpdate().contains(MiscellaneousThemeGenerator.PLANETARY_SHIELD_PLANET)) {
191 FleetMemberAPI flagship =
null;
192 for (ShipRolePick pick : fleet.getFaction().pickShip(ShipRoles.COMBAT_CAPITAL, ShipPickParams.all(),
null, random)) {
193 FleetMemberAPI member = fleet.getFleetData().addFleetMember(pick.variantId);
196 member.setShipName(fleet.getFaction().pickRandomShipName(random));
199 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE);
201 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
202 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR());
203 member.setFlagship(member == flagship);
206 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random);
207 member.setCaptain(person);
208 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(member);
212 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random);
213 fleet.setCommander(person);
214 fleet.getFlagship().setCaptain(person);
215 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(fleet.getFlagship());
217 if (fleet.getInflater() instanceof DefaultFleetInflater) {
218 DefaultFleetInflater dfi = (DefaultFleetInflater) fleet.getInflater();
219 ((DefaultFleetInflaterParams)dfi.getParams()).allWeapons =
true;
223 if (Entities.DERELICT_CRYOSLEEPER.equals(p.entity.getCustomEntityType())) {
224 fleet.getFleetData().clear();
225 for (ShipRolePick pick : fleet.getFaction().pickShip(ShipRoles.COMBAT_CAPITAL, ShipPickParams.all(),
null, random)) {
226 fleet.getFleetData().addFleetMember(pick.variantId);
228 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE);
230 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random);
232 person.setPortraitSprite(fleet.getFaction().createRandomPerson().getPortraitSprite());
233 fleet.setCommander(person);
234 fleet.getFlagship().setCaptain(person);
235 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(fleet.getFlagship());
237 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
238 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR());
241 if (Entities.SPEC_LIMBO_WORMHOLE_CACHE.equals(p.entity.getCustomDescriptionId())) {
243 for (ShipRolePick pick : fleet.getFaction().pickShip(ShipRoles.COMBAT_CAPITAL, ShipPickParams.all(),
null, random)) {
244 fleet.getFleetData().addFleetMember(pick.variantId);
246 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.GAMMA_CORE);
248 PersonAPI person = plugin.createPerson(Commodities.GAMMA_CORE, fleet.getFaction().getId(), random);
251 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
252 if (member.isCapital()) {
253 fleet.getFleetData().setFlagship(member);
257 fleet.setCommander(person);
258 fleet.getFlagship().setCaptain(person);
259 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(fleet.getFlagship());
261 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
262 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR());
265 if (Entities.DERELICT_MOTHERSHIP.equals(p.entity.getCustomEntityType()) ||
266 Entities.DERELICT_SURVEY_SHIP.equals(p.entity.getCustomEntityType()) ||
267 Entities.DERELICT_SURVEY_PROBE.equals(p.entity.getCustomEntityType())
271 float coreMult = Math.max(0f, (bonus / 100f) - 0.1f);
272 if (coreMult > 1f) coreMult = 1f;
275 RemnantOfficerGeneratorPlugin gen =
new RemnantOfficerGeneratorPlugin(
true, coreMult);
276 if (coreMult >= 1f) {
277 gen.setForceIntegrateCores(
true);
279 gen.addCommanderAndOfficers(fleet,
null, random);
281 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
282 if (member.isStation()) {
283 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE);
284 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random);
286 person.setPortraitSprite(fleet.getFaction().createRandomPerson().getPortraitSprite());
287 member.setCaptain(person);
288 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(member);
290 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR());
296 public int getHandlingPriority(Object params) {
297 if (!(params instanceof SDMParams))
return 0;
298 SDMParams p = (SDMParams) params;
300 if (p.entity !=
null && p.entity.getMemoryWithoutUpdate().contains(MiscellaneousThemeGenerator.PLANETARY_SHIELD_PLANET)) {
303 if (Factions.DERELICT.equals(p.factionId)) {
306 if (Factions.OMEGA.equals(p.factionId)) {
309 if (Factions.REMNANTS.equals(p.factionId)) {
315 public float getQuality(SDMParams p,
float quality, Random random,
boolean withOverride) {
316 if (withOverride)
return quality;
317 if (Factions.DERELICT.equals(p.factionId)) {
319 return quality + bonus;
325 public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params,
final Map<String, MemoryAPI> memoryMap) {
326 if (dialog ==
null)
return false;
328 SectorEntityToken entity = dialog.getInteractionTarget();
329 String specId = entity.getCustomEntityType();
330 if (specId ==
null || entity.getMemoryWithoutUpdate().contains(MemFlags.SALVAGE_SPEC_ID_OVERRIDE)) {
331 specId = entity.getMemoryWithoutUpdate().getString(MemFlags.SALVAGE_SPEC_ID_OVERRIDE);
333 SalvageEntityGenDataSpec spec = SalvageEntityGeneratorOld.getSalvageSpec(specId);
335 MemoryAPI memory = memoryMap.get(MemKeys.LOCAL);
336 if (memoryMap.containsKey(MemKeys.ENTITY)) {
337 memory = memoryMap.get(MemKeys.ENTITY);
340 long seed = memory.getLong(MemFlags.SALVAGE_SEED);
347 Random random = Misc.getRandom(seed, 0);
349 DefenderDataOverride override =
null;
350 if (memory.contains(MemFlags.SALVAGE_DEFENDER_OVERRIDE)) {
351 override = (DefenderDataOverride) memory.get(MemFlags.SALVAGE_DEFENDER_OVERRIDE);
354 Random fleetRandom = Misc.getRandom(seed, 1);
360 float strength = spec.getMinStr() + Math.round((spec.getMaxStr() - spec.getMinStr()) * fleetRandom.nextFloat());
361 float prob = spec.getProbDefenders();
363 if (override !=
null) {
364 strength = override.minStr + Math.round((override.maxStr - override.minStr) * fleetRandom.nextFloat());
365 prob = override.probDefenders;
368 String factionId = entity.getFaction().getId();
369 if (spec.getDefFaction() !=
null) {
370 factionId = spec.getDefFaction();
372 if (override !=
null && override.defFaction !=
null) {
373 factionId = override.defFaction;
376 SDMParams p =
new SDMParams();
378 p.factionId = factionId;
380 SalvageDefenderModificationPlugin plugin =
Global.
getSector().getGenericPlugins().pickPlugin(
381 SalvageDefenderModificationPlugin.class, p);
383 if (plugin !=
null) {
384 strength = plugin.getStrength(p, strength, random, override !=
null);
385 prob = plugin.getProbability(p, prob, random, override !=
null);
388 float probStation = spec.getProbStation();
389 if (override !=
null) {
390 probStation = override.probStation;
392 String stationRole =
null;
393 if (fleetRandom.nextFloat() < probStation) {
394 stationRole = spec.getStationRole();
395 if (override !=
null && override.stationRole !=
null) {
396 stationRole = override.stationRole;
403 if (((
int) strength > 0 || stationRole !=
null) &&
404 random.nextFloat() < prob &&
405 !memory.getBoolean(
"$defenderFleetDefeated")) {
406 memory.set(
"$hasDefenders",
true, 0);
409 float quality = spec.getDefQuality();
410 if (plugin !=
null) {
411 quality = plugin.getQuality(p, quality, fleetRandom, override !=
null);
414 FleetParamsV3 fParams =
new FleetParamsV3(
null,
null,
417 FleetTypes.PATROL_SMALL,
420 fParams.random = fleetRandom;
423 fParams.withOfficers = faction.getCustomBoolean(Factions.CUSTOM_OFFICERS_ON_AUTOMATED_DEFENSES);
425 fParams.maxShipSize = (int) spec.getMaxDefenderSize();
426 if (override !=
null) {
427 fParams.maxShipSize = override.maxDefenderSize;
430 if (plugin !=
null) {
431 fParams.maxShipSize = (int) (plugin.getMaxSize(p, fParams.maxShipSize, random, override !=
null));
434 fParams.minShipSize = (int) spec.getMinDefenderSize();
435 if (override !=
null) {
436 fParams.minShipSize = override.minDefenderSize;
438 if (plugin !=
null) {
439 fParams.minShipSize = (int) (plugin.getMinSize(p, fParams.minShipSize, random, override !=
null));
444 CampaignFleetAPI defenders = FleetFactoryV3.createFleet(fParams);
446 if (!defenders.isEmpty()) {
447 defenders.getInflater().setRemoveAfterInflating(
false);
450 defenders.setName(
"Automated Defenses");
452 if (stationRole !=
null) {
453 defenders.getFaction().pickShipAndAddToFleet(stationRole, ShipPickParams.all(), defenders, fleetRandom);
454 defenders.getFleetData().sort();
457 defenders.clearAbilities();
459 if (plugin !=
null) {
461 plugin.modifyFleet(p, defenders, fleetRandom, override !=
null);
464 defenders.getFleetData().sort();
466 memory.set(
"$defenderFleet", defenders, 0);
469 memory.set(
"$hasDefenders",
false, 0);
474 CampaignFleetAPI defenders = memory.getFleet(
"$defenderFleet");
475 if (defenders !=
null) {
476 boolean hasStation =
false;
477 boolean hasNonStation =
false;
478 for (FleetMemberAPI member : defenders.getFleetData().getMembersListCopy()) {
479 if (member.isStation()) {
482 hasNonStation =
true;
485 memory.set(
"$hasStation", hasStation, 0);
486 memory.set(
"$hasNonStation", hasNonStation, 0);
488 defenders.setLocation(entity.getLocation().x, entity.getLocation().y);
491 memory.set(
"$hasDefenders",
false, 0);
492 memory.set(
"$hasStation",
false, 0);