Starsector API
Loading...
Searching...
No Matches
CargoPods.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.rulecmd.salvage;
2
3import java.util.ArrayList;
4import java.util.List;
5import java.util.Map;
6import java.util.Random;
7
8import org.lwjgl.util.vector.Vector2f;
9
10import com.fs.starfarer.api.Global;
11import com.fs.starfarer.api.campaign.CampaignFleetAPI;
12import com.fs.starfarer.api.campaign.CargoAPI;
13import com.fs.starfarer.api.campaign.CargoStackAPI;
14import com.fs.starfarer.api.campaign.CoreInteractionListener;
15import com.fs.starfarer.api.campaign.FactionAPI;
16import com.fs.starfarer.api.campaign.InteractionDialogAPI;
17import com.fs.starfarer.api.campaign.OptionPanelAPI;
18import com.fs.starfarer.api.campaign.PlanetAPI;
19import com.fs.starfarer.api.campaign.SectorEntityToken;
20import com.fs.starfarer.api.campaign.StarSystemAPI;
21import com.fs.starfarer.api.campaign.TextPanelAPI;
22import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
23import com.fs.starfarer.api.campaign.rules.MemoryAPI;
24import com.fs.starfarer.api.impl.campaign.CargoPodsEntityPlugin;
25import com.fs.starfarer.api.impl.campaign.ids.Commodities;
26import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
27import com.fs.starfarer.api.impl.campaign.intel.misc.CargoPodsIntel;
28import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity;
29import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin;
30import com.fs.starfarer.api.impl.campaign.rulecmd.FireAll;
31import com.fs.starfarer.api.util.Misc;
32import com.fs.starfarer.api.util.Misc.Token;
33
38public class CargoPods extends BaseCommandPlugin {
39
40 public static final String TRAPPED = "$trapped";
41 public static final String LOCKED = "$locked";
42 public static final String CAN_UNLOCK = "$canUnlock";
43
44
45 public static final float BREAK_KEEP_FRACTION = 0.5f;
46
47
48 protected CampaignFleetAPI playerFleet;
49 protected SectorEntityToken entity;
50 protected FactionAPI playerFaction;
51 protected FactionAPI entityFaction;
52 protected TextPanelAPI text;
53 protected OptionPanelAPI options;
54 protected CargoAPI playerCargo;
55 protected CargoAPI podsCargo;
56 protected MemoryAPI memory;
57 protected InteractionDialogAPI dialog;
59 protected Map<String, MemoryAPI> memoryMap;
60
61
62 protected boolean isLocked() {
63 return memory.getBoolean(LOCKED);
64 }
65 protected boolean isTrapped() {
66 return memory.getBoolean(TRAPPED);
67 }
68 protected boolean canUnlock() {
69 return memory.getBoolean(CAN_UNLOCK);
70 }
71
72
73 public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) {
74
75 this.dialog = dialog;
76 this.memoryMap = memoryMap;
77
78 String command = params.get(0).getString(memoryMap);
79 if (command == null) return false;
80
82
83 entity = dialog.getInteractionTarget();
84 text = dialog.getTextPanel();
85 options = dialog.getOptionPanel();
86
87 playerFleet = Global.getSector().getPlayerFleet();
88 playerCargo = playerFleet.getCargo();
89 podsCargo = entity.getCargo();
90
91 playerFaction = Global.getSector().getPlayerFaction();
92 entityFaction = entity.getFaction();
93
94 plugin = (CargoPodsEntityPlugin) entity.getCustomPlugin();
95
96 if (command.equals("printDesc")) {
98 }
99 else if (command.equals("openCargo")) {
100 openCargo();
101 }
102 else if (command.equals("breakLocks")) {
103 breakLocks();
104 }
105 else if (command.equals("destroy")) {
106 destroy();
107 }
108 else if (command.equals("stabilize")) {
109 stabilize();
110 }
111 else if (command.equals("computeStabilizeData")) {
113 }
114
115 return true;
116 }
117
118 protected void computeStabilizeData() {
119 float total = podsCargo.getTotalPersonnel() + podsCargo.getSpaceUsed() + podsCargo.getFuel();
120 float stabilizeSupplies = Math.max((int) total / 200, 2);
121
122 memory.set("$stabilizeSupplies", (int) stabilizeSupplies, 0f);
123
124 float stabilizeDays = 400;
125 memory.set("$stabilizeDays", (int) stabilizeDays, 0f);
126 }
127
128
129 public static SectorEntityToken findOrbitFocus(SectorEntityToken entity) {
130 if (entity.isInHyperspace()) return null;
131
132 SectorEntityToken target = null;
133 float minDist = Float.MAX_VALUE;
134 List<SectorEntityToken> potential = new ArrayList<SectorEntityToken>(entity.getContainingLocation().getPlanets());
135 SectorEntityToken center = ((StarSystemAPI)entity.getContainingLocation()).getCenter();
136 potential.add(center);
137 potential.addAll(entity.getContainingLocation().getJumpPoints());
138 for (SectorEntityToken curr : potential) {
139 float dist = Misc.getDistance(entity.getLocation(), curr.getLocation());
140 dist -= curr.getRadius();
141
142 float maxDist = 400f;
143 if ((curr instanceof PlanetAPI && ((PlanetAPI)curr).isStar()) || curr == center) {
144 maxDist = 100000000000f;
145 }
146
147 if (dist < maxDist && dist < minDist) {
148 target = curr;
149 minDist = dist;
150 }
151 }
152 return target;
153 }
154
155 public static void stabilizeOrbit(SectorEntityToken entity, boolean makeDiscovered) {
156 SectorEntityToken focus = findOrbitFocus(entity);
157 if (focus != null) {
158 float radius = Misc.getDistance(focus.getLocation(), entity.getLocation());
159 float orbitDays = radius / (5f + Misc.random.nextFloat() * 20f);
160 float angle = Misc.getAngleInDegreesStrict(focus.getLocation(), entity.getLocation());
161 entity.setCircularOrbit(focus, angle, radius, orbitDays);
162 } else {
163 entity.getVelocity().set(0, 0);
164 }
165
166 if (makeDiscovered) {
167 entity.setDiscoverable(null);
168 entity.setSensorProfile(null);
169 }
170
171 entity.getMemoryWithoutUpdate().set("$stabilized", true);
172 }
173
174 protected void stabilize() {
175 stabilizeOrbit(entity, true);
176
177 float stabilizeSupplies = memory.getFloat("$stabilizeSupplies");
178 float stabilizeDays = memory.getFloat("$stabilizeDays");
179
180 playerCargo.removeSupplies(stabilizeSupplies);
181
183 plugin.setExtraDays(stabilizeDays);
185
187 AddRemoveCommodity.addCommodityLossText(Commodities.SUPPLIES, (int) stabilizeSupplies, text);
188
189 text.addParagraph("Your crew busy themselves attaching micro-thrusters and carefully " +
190 "sealing, balancing, and interconnecting the pods to make sure they remain in a stable orbit.");
191// text.addParagraph("Your crew busy themselves attaching micro-thrusters and performing " +
192// "the requisite calculations to make sure the pods remain in a stable orbit.");
193 float daysLeft = plugin.getDaysLeft();
194// String atLeastTime = Misc.getAtLeastStringForDays((int) daysLeft);
195// text.addParagraph("When the work is done, your systems estimate they'll be able to predict the location of the pods for " + atLeastTime + ".");
196
197 memory.set("$stabilized", true);
198 memory.set("$daysLeft", (int) daysLeft, 0f);
199
200
201 CargoPodsIntel intel = null;
202 for (IntelInfoPlugin iip : Global.getSector().getIntelManager().getIntel(CargoPodsIntel.class)) {
203 CargoPodsIntel curr = (CargoPodsIntel) iip;
204 if (curr.getPods() == entity) {
205 intel = curr;
206 break;
207 }
208 }
209 if (intel == null) {
210 intel = new CargoPodsIntel(entity);
211 Global.getSector().getIntelManager().addIntel(intel, true);
212 }
213
214 Global.getSector().getIntelManager().addIntelToTextPanel(intel, text);
215
216 }
217
218 protected void destabilize() {
219 if (!memory.getBoolean("$stabilized")) return;
220
221 entity.setOrbit(null);
222
223 Vector2f vel = Misc.getUnitVectorAtDegreeAngle((float) Math.random() * 360f);
224 vel.scale(5f + 10f * (float) Math.random());
225 entity.getVelocity().set(vel);
226
227 entity.setDiscoverable(null);
228 entity.setSensorProfile(1f);
229
233
234 float daysLeft = plugin.getDaysLeft();
235 String atLeastTime = Misc.getAtLeastStringForDays((int) daysLeft);
236 text.addParagraph("Working with the cargo has destablized the orbit, but the pods should still be trackable for " + atLeastTime + ".");
237
238 memory.unset("$stabilized");
239 }
240
241
242 protected void breakLocks() {
244 openCargo();
245 }
246
247
248 protected void pruneCargo(float fractionKeep) {
249 CargoAPI keep = Global.getFactory().createCargo(true);
250
251 Random random = new Random();
252 if (memory.contains(MemFlags.SALVAGE_SEED)) {
253 long seed = memory.getLong(MemFlags.SALVAGE_SEED);
254 random = new Random(seed);
255 }
256
257 for (CargoStackAPI stack : podsCargo.getStacksCopy()) {
258 int qty = (int) stack.getSize();
259 for (int i = 0; i < qty; i++) {
260 if (random.nextFloat() < fractionKeep) {
261 keep.addItems(stack.getType(), stack.getData(), 1);
262 }
263 }
264 }
265 podsCargo.clear();
266 podsCargo.addAll(keep);
267 }
268
269
270 protected void destroy() {
271 podsCargo.clear();
272 Misc.fadeAndExpire(entity, 1f);
273 }
274
275 protected void showDescription() {
276 float daysLeft = plugin.getDaysLeft();
277 memory.set("$daysLeft", (int) daysLeft, 0f);
278
279 boolean stabilized = memory.getBoolean("$stabilized");
280
281 if (daysLeft >= 5000) {
282 text.addParagraph("The cargo pods are in a stable orbit and are unlikely to drift apart any time soon.");
283 } else {
284 String atLeastTime = Misc.getAtLeastStringForDays((int) daysLeft);
285 if (stabilized && daysLeft > 20) {
286 text.addParagraph("The cargo pods are in a stabilized orbit, and your systems should be able to keep track of them for " + atLeastTime + ".");
287 } else {
288 float depth = Misc.getAbyssalDepth(entity);
289 if (depth >= 1f) {
290 text.addParagraph("This deep in abyssal hyperspace, the cargo pods are likely to be lost forever as soon as they're out of sensor range.");
291 } else {
292 text.addParagraph("The cargo pods are in an unstable orbit, but should not drift apart and be lost for " + atLeastTime + ".");
293 }
294 }
295 }
296
297 if (podsCargo.getTotalPersonnel() > 0) {
298 String crewText = "Sensor readings are indicative of the presence of active life support and cryosleep equipment.";
299 text.addParagraph(crewText);
300 }
301
302 if (isLocked()) {
303 if (canUnlock()) {
304 text.addParagraph("The pods are locked, but you are in posession of the keycode.");
305 } else {
306 text.addParagraph("The pods are locked, and you don't have the keycode. " +
307 "It's possible to force the locks, but this carries a risk to the cargo. " +
308 "Some pods are also fitted with a self-destruct mechanism, " +
309 "ensuring the total loss of all cargo in the event of a breach attempt.");
310 }
311 } else {
312 //text.addParagraph("The pods are not locked.");
313 }
314
315 }
316
317 public void openCargo() {
318 final CargoAPI preOpen = Global.getFactory().createCargo(true);
319 preOpen.addAll(podsCargo);
320
321 dialog.getVisualPanel().showLoot("Cargo Pods", podsCargo, true, false, false, new CoreInteractionListener() {
322 public void coreUIDismissed() {
324
325 if (podsCargo.isEmpty()) {
326 Misc.fadeAndExpire(entity, 1f);
327
328 dialog.dismiss();
329 dialog.hideTextPanel();
330 dialog.hideVisualPanel();
331 } else {
332 if (!Misc.isSameCargo(preOpen, podsCargo)) {
333 destabilize();
334 }
335 }
336 dialog.setPromptText("You decide to...");
337 FireAll.fire(null, dialog, memoryMap, "CargoPodsOptions");
338 FireAll.fire(null, dialog, memoryMap, "CargoPodsOptionsUpdate");
339 }
340 });
341 options.clearOptions();
342 dialog.setPromptText("");
343 }
344
345}
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
static FactoryAPI getFactory()
Definition Global.java:35
static SectorAPI getSector()
Definition Global.java:59
static void addCommodityLossText(String commodityId, int quantity, TextPanelAPI text)
static MemoryAPI getEntityMemory(Map< String, MemoryAPI > memoryMap)
static boolean fire(String ruleId, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap, String params)
Definition FireAll.java:55
static void stabilizeOrbit(SectorEntityToken entity, boolean makeDiscovered)
static SectorEntityToken findOrbitFocus(SectorEntityToken entity)
boolean execute(String ruleId, InteractionDialogAPI dialog, List< Token > params, Map< String, MemoryAPI > memoryMap)
CargoAPI createCargo(boolean unlimitedStacks)