Starsector API
Loading...
Searching...
No Matches
RemnantSeededFleetManager.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.procgen.themes;
2
3import java.util.Random;
4
5import org.lwjgl.util.vector.Vector2f;
6
7import com.fs.starfarer.api.campaign.CampaignFleetAPI;
8import com.fs.starfarer.api.campaign.InteractionDialogAPI;
9import com.fs.starfarer.api.campaign.SectorEntityToken;
10import com.fs.starfarer.api.campaign.StarSystemAPI;
11import com.fs.starfarer.api.combat.BattleCreationContext;
12import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.BaseFIDDelegate;
13import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfig;
14import com.fs.starfarer.api.impl.campaign.FleetInteractionDialogPluginImpl.FIDConfigGen;
15import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
16import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
17import com.fs.starfarer.api.impl.campaign.fleets.SeededFleetManager;
18import com.fs.starfarer.api.impl.campaign.ids.Abilities;
19import com.fs.starfarer.api.impl.campaign.ids.Factions;
20import com.fs.starfarer.api.impl.campaign.ids.FleetTypes;
21import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
22import com.fs.starfarer.api.impl.campaign.ids.Tags;
23import com.fs.starfarer.api.impl.campaign.procgen.StarSystemGenerator;
24import com.fs.starfarer.api.util.Misc;
25import com.fs.starfarer.api.util.WeightedRandomPicker;
26
27public class RemnantSeededFleetManager extends SeededFleetManager {
28
29// public static class DerelictFleetInteractionConfigGen implements FIDConfigGen {
30// public FIDConfig createConfig() {
31// FIDConfig config = new FIDConfig();
32// config.showTransponderStatus = false;
33// config.delegate = new BaseFIDDelegate() {
34// public void postPlayerSalvageGeneration(InteractionDialogAPI dialog, FleetEncounterContext context, CargoAPI salvage) {
35// if (!(dialog.getInteractionTarget() instanceof CampaignFleetAPI)) return;
36//
37// CampaignFleetAPI fleet = (CampaignFleetAPI) dialog.getInteractionTarget();
38//
39// DataForEncounterSide data = context.getDataFor(fleet);
40// List<FleetMemberAPI> losses = new ArrayList<FleetMemberAPI>();
41// for (FleetMemberData fmd : data.getOwnCasualties()) {
42// losses.add(fmd.getMember());
43// }
44//
45// List<DropData> dropRandom = new ArrayList<DropData>();
46//
47// int [] counts = new int[5];
48// String [] groups = new String [] {Drops.REM_FRIGATE, Drops.REM_DESTROYER,
49// Drops.REM_CRUISER, Drops.REM_CAPITAL,
50// Drops.GUARANTEED_ALPHA};
51//
52// //for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
53// for (FleetMemberAPI member : losses) {
54// if (member.isStation()) {
55// counts[4] += 1;
56// counts[3] += 1;
57// } else if (member.isCapital()) {
58// counts[3] += 1;
59// } else if (member.isCruiser()) {
60// counts[2] += 1;
61// } else if (member.isDestroyer()) {
62// counts[1] += 1;
63// } else if (member.isFrigate()) {
64// counts[0] += 1;
65// }
66// }
67//
71//
72// for (int i = 0; i < counts.length; i++) {
73// int count = counts[i];
74// if (count <= 0) continue;
75//
76// DropData d = new DropData();
77// d.group = groups[i];
78// d.chances = (int) Math.ceil(count * 1f);
79// dropRandom.add(d);
80// }
81//
82// Random salvageRandom = new Random(Misc.getSalvageSeed(fleet));
83// //salvageRandom = new Random();
84// CargoAPI extra = SalvageEntity.generateSalvage(salvageRandom, 1f, 1f, 1f, 1f, null, dropRandom);
85// for (CargoStackAPI stack : extra.getStacksCopy()) {
86// salvage.addFromStack(stack);
87// }
88// }
89// public void battleContextCreated(InteractionDialogAPI dialog, BattleCreationContext bcc) {
90// bcc.aiRetreatAllowed = false;
91// bcc.objectivesAllowed = false;
92// }
93// };
94// return config;
95// }
96// }
97
98
99 public static class RemnantFleetInteractionConfigGen implements FIDConfigGen {
100 public FIDConfig createConfig() {
101 FIDConfig config = new FIDConfig();
102 config.showTransponderStatus = false;
103 config.delegate = new BaseFIDDelegate() {
104// public void postPlayerSalvageGeneration(InteractionDialogAPI dialog, FleetEncounterContext context, CargoAPI salvage) {
105// if (!(dialog.getInteractionTarget() instanceof CampaignFleetAPI)) return;
106//
107// CampaignFleetAPI fleet = (CampaignFleetAPI) dialog.getInteractionTarget();
108//
109// DataForEncounterSide data = context.getDataFor(fleet);
110// List<FleetMemberAPI> losses = new ArrayList<FleetMemberAPI>();
111// for (FleetMemberData fmd : data.getOwnCasualties()) {
112// losses.add(fmd.getMember());
113// }
114//
115// List<DropData> dropRandom = new ArrayList<DropData>();
116//
117// int [] counts = new int[5];
118// String [] groups = new String [] {Drops.REM_FRIGATE, Drops.REM_DESTROYER,
119// Drops.REM_CRUISER, Drops.REM_CAPITAL,
120// Drops.GUARANTEED_ALPHA};
121//
122// //for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
123// for (FleetMemberAPI member : losses) {
124// if (member.isStation()) {
125// counts[4] += 1;
126// counts[3] += 1;
127// } else if (member.isCapital()) {
128// counts[3] += 1;
129// } else if (member.isCruiser()) {
130// counts[2] += 1;
131// } else if (member.isDestroyer()) {
132// counts[1] += 1;
133// } else if (member.isFrigate()) {
134// counts[0] += 1;
135// }
136// }
137//
141//
142// for (int i = 0; i < counts.length; i++) {
143// int count = counts[i];
144// if (count <= 0) continue;
145//
146// DropData d = new DropData();
147// d.group = groups[i];
148// d.chances = (int) Math.ceil(count * 1f);
149// dropRandom.add(d);
150// }
151//
152// Random salvageRandom = new Random(Misc.getSalvageSeed(fleet));
153// //salvageRandom = new Random();
154// CargoAPI extra = SalvageEntity.generateSalvage(salvageRandom, 1f, 1f, 1f, 1f, null, dropRandom);
155// for (CargoStackAPI stack : extra.getStacksCopy()) {
156// salvage.addFromStack(stack);
157// }
158// }
159 public void battleContextCreated(InteractionDialogAPI dialog, BattleCreationContext bcc) {
160 bcc.aiRetreatAllowed = false;
161 //bcc.objectivesAllowed = false;
162 }
163 };
164 return config;
165 }
166 }
167
168
169 protected int minPts;
170 protected int maxPts;
171 protected float activeChance;
172
173 public RemnantSeededFleetManager(StarSystemAPI system, int minFleets, int maxFleets, int minPts, int maxPts, float activeChance) {
174 super(system, 1f);
175 this.minPts = minPts;
176 this.maxPts = maxPts;
177 this.activeChance = activeChance;
178
179 int num = minFleets + StarSystemGenerator.random.nextInt(maxFleets - minFleets + 1);
180 for (int i = 0; i < num; i++) {
181 long seed = StarSystemGenerator.random.nextLong();
182 addSeed(seed);
183 }
184 }
185
186 @Override
187 protected CampaignFleetAPI spawnFleet(long seed) {
188 Random random = new Random(seed);
189
190 int combatPoints = minPts + random.nextInt(maxPts - minPts + 1);
191
192 String type = FleetTypes.PATROL_SMALL;
193 if (combatPoints > 8) type = FleetTypes.PATROL_MEDIUM;
194 if (combatPoints > 16) type = FleetTypes.PATROL_LARGE;
195
196 combatPoints *= 8f; // 8 is fp cost of remnant frigate
197
198 FleetParamsV3 params = new FleetParamsV3(
199 system.getLocation(),
200 Factions.REMNANTS,
201 1f,
202 type,
203 combatPoints, // combatPts
204 0f, // freighterPts
205 0f, // tankerPts
206 0f, // transportPts
207 0f, // linerPts
208 0f, // utilityPts
209 0f // qualityMod
210 );
211 params.withOfficers = false;
212 params.random = random;
213
214 CampaignFleetAPI fleet = FleetFactoryV3.createFleet(params);
215 if (fleet == null) return null;
216
217 system.addEntity(fleet);
218 fleet.setFacing(random.nextFloat() * 360f);
219
220
221 boolean dormant = random.nextFloat() >= activeChance;
222 //dormant = false;
223 int numActive = 0;
224 for (SeededFleet f : fleets) {
225 if (f.fleet != null) numActive++;
226 }
227 if (numActive == 0 && activeChance > 0) { // first fleet is not dormant, to ensure one active fleet always
228 dormant = false;
229 }
230 initRemnantFleetProperties(random, fleet, dormant);
231
232 if (dormant) {
233 SectorEntityToken target = pickEntityToGuard(random, system, fleet);
234 if (target != null) {
235// Vector2f loc = Misc.getPointAtRadius(target.getLocation(), 300f, random);
236// fleet.setLocation(loc.x, loc.y);
237
238 fleet.setCircularOrbit(target,
239 random.nextFloat() * 360f,
240 fleet.getRadius() + target.getRadius() + 100f + 100f * random.nextFloat(),
241 25f + 5f * random.nextFloat());
242 } else {
243 Vector2f loc = Misc.getPointAtRadius(new Vector2f(), 4000f, random);
244 fleet.setLocation(loc.x, loc.y);
245 }
246 } else {
247 fleet.addScript(new RemnantAssignmentAI(fleet, system, null));
248 }
249
250 return fleet;
251 }
252
253
254 public static SectorEntityToken pickEntityToGuard(Random random, StarSystemAPI system, CampaignFleetAPI fleet) {
255 WeightedRandomPicker<SectorEntityToken> picker = new WeightedRandomPicker<SectorEntityToken>(random);
256
257 for (SectorEntityToken entity : system.getEntitiesWithTag(Tags.SALVAGEABLE)) {
258 float w = 1f;
259 if (entity.hasTag(Tags.NEUTRINO_HIGH)) w = 3f;
260 if (entity.hasTag(Tags.NEUTRINO_LOW)) w = 0.33f;
261 picker.add(entity, w);
262 }
263
264 for (SectorEntityToken entity : system.getJumpPoints()) {
265 picker.add(entity, 1f);
266 }
267
268 return picker.pick();
269 }
270
271
272
273 public static void initRemnantFleetProperties(Random random, CampaignFleetAPI fleet, boolean dormant) {
274 if (random == null) random = new Random();
275
276 fleet.removeAbility(Abilities.EMERGENCY_BURN);
277 fleet.removeAbility(Abilities.SENSOR_BURST);
278 fleet.removeAbility(Abilities.GO_DARK);
279
280 // to make sure they attack the player on sight when player's transponder is off
281 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_SAW_PLAYER_WITH_TRANSPONDER_ON, true);
282 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PATROL_FLEET, true);
283 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_ALLOW_LONG_PURSUIT, true);
284 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_HOLD_VS_STRONGER, true);
285
286 // to make dormant fleets not try to retreat and get harried repeatedly for CR loss
287 if (dormant) {
288 //fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_AGGRESSIVE, true);
289 }
290
291 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_NO_JUMP, true);
292
293 if (dormant) {
294 fleet.setTransponderOn(false);
295// fleet.getMemoryWithoutUpdate().unset(MemFlags.MEMORY_KEY_PATROL_FLEET);
296// fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PIRATE, true); // so they don't turn transponder on
297// fleet.addAssignment(FleetAssignment.HOLD, null, 1000000f, "dormant");
298 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_ALLOW_DISENGAGE, true);
299 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_MAKE_AGGRESSIVE, true);
300 fleet.setAI(null);
301 fleet.setNullAIActionText("dormant");
302 }
303
305 //addRemnantAICoreDrops(random, fleet, 1f);
306
307 long salvageSeed = random.nextLong();
308 fleet.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SEED, salvageSeed);
309 }
310
311 public static void addRemnantInteractionConfig(CampaignFleetAPI fleet) {
312 fleet.getMemoryWithoutUpdate().set(MemFlags.FLEET_INTERACTION_DIALOG_CONFIG_OVERRIDE_GEN,
313 new RemnantFleetInteractionConfigGen());
314 }
315
316// public static void addRemnantAICoreDrops(Random random, CampaignFleetAPI fleet, float mult) {
317// if (random == null) random = new Random();
318// long salvageSeed = random.nextLong();
319// fleet.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SEED, salvageSeed);
320//
321// int [] counts = new int[3];
322// String [] groups = new String [] {Drops.AI_CORES1, Drops.AI_CORES2, Drops.AI_CORES3};
323// for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
324// if (member.isCapital()) {
325// counts[2] += 2;
326// } else if (member.isCruiser()) {
327// counts[2] += 1;
328// } else if (member.isDestroyer()) {
329// counts[1] += 1;
330// } else if (member.isFrigate()) {
331// counts[0] += 1;
332// }
333// }
334//
335// if (fleet.isStationMode()) {
336// counts[2] += 10;
337// }
338//
339// for (int i = 0; i < counts.length; i++) {
340// int count = counts[i];
341// if (count <= 0) continue;
342//
343// DropData d = new DropData();
344// d.group = groups[i];
345// d.chances = (int) Math.ceil(count * mult);
346// fleet.addDropRandom(d);
347// }
348//
349// }
350
351}
352
353
354
355
356
357
358
static void initRemnantFleetProperties(Random random, CampaignFleetAPI fleet, boolean dormant)
static SectorEntityToken pickEntityToGuard(Random random, StarSystemAPI system, CampaignFleetAPI fleet)
RemnantSeededFleetManager(StarSystemAPI system, int minFleets, int maxFleets, int minPts, int maxPts, float activeChance)