Starsector API
Loading...
Searching...
No Matches
PlayerFleetPersonnelTracker.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.Iterator;
6import java.util.List;
7import java.util.Map;
8
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.campaign.CampaignFleetAPI;
11import com.fs.starfarer.api.campaign.CargoAPI;
12import com.fs.starfarer.api.campaign.CargoStackAPI;
13import com.fs.starfarer.api.campaign.GenericPluginManagerAPI;
14import com.fs.starfarer.api.campaign.InteractionDialogAPI;
15import com.fs.starfarer.api.campaign.PlayerMarketTransaction;
16import com.fs.starfarer.api.campaign.SectorEntityToken;
17import com.fs.starfarer.api.campaign.econ.MarketAPI;
18import com.fs.starfarer.api.campaign.econ.SubmarketAPI;
19import com.fs.starfarer.api.campaign.listeners.CargoScreenListener;
20import com.fs.starfarer.api.campaign.listeners.ColonyInteractionListener;
21import com.fs.starfarer.api.campaign.listeners.CommodityIconProvider;
22import com.fs.starfarer.api.campaign.listeners.CommodityTooltipModifier;
23import com.fs.starfarer.api.campaign.listeners.GroundRaidObjectivesListener;
24import com.fs.starfarer.api.campaign.rules.MemoryAPI;
25import com.fs.starfarer.api.combat.MutableStat;
26import com.fs.starfarer.api.fleet.MutableFleetStatsAPI;
27import com.fs.starfarer.api.impl.campaign.CargoPodsEntityPlugin;
28import com.fs.starfarer.api.impl.campaign.graid.GroundRaidObjectivePlugin;
29import com.fs.starfarer.api.impl.campaign.ids.Commodities;
30import com.fs.starfarer.api.impl.campaign.ids.Stats;
31import com.fs.starfarer.api.impl.campaign.ids.Submarkets;
32import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.RaidType;
33import com.fs.starfarer.api.ui.Alignment;
34import com.fs.starfarer.api.ui.LabelAPI;
35import com.fs.starfarer.api.ui.PositionAPI;
36import com.fs.starfarer.api.ui.TooltipMakerAPI;
37import com.fs.starfarer.api.util.Misc;
38
39public class PlayerFleetPersonnelTracker implements ColonyInteractionListener,
40 GroundRaidObjectivesListener,
41 CommodityTooltipModifier,
42 CommodityIconProvider,
43 CargoScreenListener {
44
45 public static float XP_PER_RAID_MULT = 0.2f;
46 public static float MAX_EFFECTIVENESS_PERCENT = 100f;
47 public static float MAX_LOSS_REDUCTION_PERCENT = 50f;
48
49 public static boolean KEEP_XP_DURING_TRANSFERS = true;
50
51 public static enum PersonnelRank {
52 REGULAR("Regular", "icon_crew_green", 0.25f),
53 EXPERIENCED("Experienced", "icon_crew_regular", 0.5f),
54 VETERAN("Veteran", "icon_crew_veteran", 0.75f),
55 ELITE("Elite", "icon_crew_elite", 1f),
56 ;
57 public String name;
58 public String iconKey;
59 public float threshold;
60 private PersonnelRank(String name, String iconKey, float threshold) {
61 this.name = name;
62 this.iconKey = iconKey;
63 this.threshold = threshold;
64 }
65
66 public static PersonnelRank getRankForXP(float xp) {
67 //float f = xp /MAX_XP_LEVEL;
68 float f = xp;
69 for (PersonnelRank rank : values()) {
70 if (f < rank.threshold) {
71 return rank;
72 }
73 }
74 return PersonnelRank.ELITE;
75 }
76 }
77
78 public static class CommodityIconProviderWrapper {
79 public CargoStackAPI stack;
80 public CommodityIconProviderWrapper(CargoStackAPI stack) {
81 this.stack = stack;
82 }
83 }
84 public static class CommodityDescriptionProviderWrapper {
85 public CargoStackAPI stack;
86 public CommodityDescriptionProviderWrapper(CargoStackAPI stack) {
87 this.stack = stack;
88 }
89 }
90
91 public static class PersonnelData implements Cloneable {
92 public String id;
93 public float xp;
94 public float num;
95 transient public float savedNum;
96 transient public float savedXP;
97 public PersonnelData(String id) {
98 this.id = id;
99 }
100 @Override
101 protected PersonnelData clone() {
102 try {
103 PersonnelData copy = (PersonnelData) super.clone();
104 copy.savedNum = savedNum;
105 copy.savedXP= savedXP;
106 return copy;
107 } catch (CloneNotSupportedException e) {
108 throw new RuntimeException(e);
109 }
110 }
111
112 public void add(int add) {
113 num += add;
114 }
115
116 public void remove(int remove, boolean removeXP) {
117 if (!KEEP_XP_DURING_TRANSFERS) removeXP = true;
118
119 if (remove > num) remove = (int) num;
120 if (removeXP) xp *= (num - remove) / Math.max(1f, num);
121 num -= remove;
122 if (removeXP) {
123 float maxXP = num;
124 xp = Math.min(xp, maxXP);
125 }
126 }
127
128 public void addXP(float xp) {
129 this.xp += xp;
130 float maxXP = num;
131 this.xp = Math.min(this.xp, maxXP);
132 }
133 public void removeXP(float xp) {
134 this.xp -= xp;
135 if (xp < 0) xp = 0;
136 }
137
138 public float clampXP() {
139 float maxXP = num;
140 float prevXP = xp;
141 this.xp = Math.min(this.xp, maxXP);
142 return Math.max(0f, prevXP - maxXP);
143 }
144
145 public void numMayHaveChanged(float newNum, boolean keepXP) {
146 // if the number was reduced in some way (i.e. picking up a stack, or lost via code, w/e
147 // then adjust XP downwards in same proportion
148 if (num > newNum) {
149 if (keepXP) {
150 clampXP();
151 } else {
152 xp *= newNum / Math.max(1f, num);
153 }
154 }
155 num = newNum;
156 }
157
158 public float getXPLevel() {
159 float f = xp / Math.max(1f, num);
160 if (f < 0) f = 0;
161 if (f > 1f) f = 1f;
162 return f;
163 }
164
165 public PersonnelRank getRank() {
166 PersonnelRank rank = PersonnelRank.getRankForXP(getXPLevel());
167 return rank;
168 }
169
170 public void integrateWithCurrentLocation(PersonnelAtEntity atLocation) {
171 //int numTaken = (int) Math.max(0, num - savedNum);
172 int numTaken = (int) Math.round(num - savedNum);
173 if (atLocation != null) {// && numTaken > 0) {
174 num = savedNum;
175 xp = savedXP;
176 //PersonnelData copy = atLocation.data.clone();
177 PersonnelData copy = atLocation.data;
178 if (numTaken > 0) {
179 transferPersonnel(copy, this, numTaken, this);
180 } else if (numTaken < 0) {
181 transferPersonnel(this, copy, -numTaken, this);
182 }
183 }
184 }
185 }
186
187
188 public static class PersonnelAtEntity implements Cloneable {
189 public PersonnelData data;
190 public SectorEntityToken entity;
191 public String submarketId;
192 public PersonnelAtEntity(SectorEntityToken entity, String commodityId, String submarketId) {
193 this.entity = entity;
194 data = new PersonnelData(commodityId);
195 this.submarketId = submarketId;
196 }
197
198 @Override
199 protected PersonnelAtEntity clone() {
200 try {
201 PersonnelAtEntity copy = (PersonnelAtEntity) super.clone();
202 copy.data = data.clone();
203 return copy;
204 } catch (CloneNotSupportedException e) {
205 throw new RuntimeException(e);
206 }
207 }
208 }
209
210
211 public static final String KEY = "$core_personnelTracker";
212
214 Object test = Global.getSector().getMemoryWithoutUpdate().get(KEY);
215 if (test == null) {// || true) {
216 test = new PlayerFleetPersonnelTracker();
217 Global.getSector().getMemoryWithoutUpdate().set(KEY, test);
218 }
219 return (PlayerFleetPersonnelTracker) test;
220 }
221
222 protected PersonnelData marineData = new PersonnelData(Commodities.MARINES);
223 protected List<PersonnelAtEntity> droppedOff = new ArrayList<PersonnelAtEntity>();
224
225 protected transient SectorEntityToken pods = null;
226 protected transient SubmarketAPI currSubmarket = null;
227
229 super();
230
231 GenericPluginManagerAPI plugins = Global.getSector().getGenericPlugins();
232 //if (!plugins.hasPlugin(PlayerFleetPersonnelTracker.class)) {
233 plugins.addPlugin(this, false);
234 //}
235
236 //Global.getSector().getMemoryWithoutUpdate().set(KEY, this);
237 Global.getSector().getListenerManager().addListener(this);
238
239 //marineData.xp = 2600 * 0.7f;
240 //marineData.num = 2600;
241 update();
242 }
243
245 doCleanup(true);
246 update();
247 currSubmarket = null;
248
249 //marineData.xp = marineData.num * 0.7f;
250 }
251
252 public void reportSubmarketOpened(SubmarketAPI submarket) {
253 doCleanup(false);
254 currSubmarket = submarket;
255 }
256
257 public void reportPlayerLeftCargoPods(SectorEntityToken entity) {
258 pods = entity;
259 }
260
261 public void reportPlayerNonMarketTransaction(PlayerMarketTransaction transaction, InteractionDialogAPI dialog) {
262 if (pods == null && dialog != null) {
263 SectorEntityToken target = dialog.getInteractionTarget();
264 if (target != null && target.getCustomPlugin() instanceof CargoPodsEntityPlugin) {
265 pods = target;
266 }
267 }
268 processTransaction(transaction, pods);
269 }
270
271 public void reportPlayerMarketTransaction(PlayerMarketTransaction transaction) {
272 if (transaction.getMarket() == null ||
273 transaction.getMarket().getPrimaryEntity() == null ||
274 transaction.getSubmarket() == null) return;
275 if (!transaction.getSubmarket().getSpecId().equals(Submarkets.SUBMARKET_STORAGE)) {
276 doCleanup(true);
277 update(false, true, null);
278 return;
279 }
280 processTransaction(transaction, transaction.getMarket().getPrimaryEntity());
281 }
282
283 public void processTransaction(PlayerMarketTransaction transaction, SectorEntityToken entity) {
284 if (entity == null) return;
285
286 SubmarketAPI sub = transaction.getSubmarket();
287
288// // when ejecting cargo, there's a fake "storage" submarket, but when interacting with the pods, there's
289// // no submarket - so for pods to display rank correctly, set the submarket when dropping off pods to null
290// if (pods != null) {
291// sub = null;
292// }
293
294 for (CargoStackAPI stack : transaction.getSold().getStacksCopy()) {
295 if (!stack.isPersonnelStack()) continue;
296 if (stack.isMarineStack()) {
297 PersonnelAtEntity at = getDroppedOffAt(stack.getCommodityId(), entity, sub, true);
298
299 int num = (int) stack.getSize();
301 }
302 }
303
304 for (CargoStackAPI stack : transaction.getBought().getStacksCopy()) {
305 if (!stack.isPersonnelStack()) continue;
306 if (stack.isMarineStack()) {
307 PersonnelAtEntity at = getDroppedOffAt(stack.getCommodityId(), entity, sub, true);
308
309 int num = (int) stack.getSize();
311 }
312 }
313
314 doCleanup(true);
315 update();
316 }
317
318 public static void transferPersonnel(PersonnelData from, PersonnelData to, int num, PersonnelData keepsXP) {
319 if (num > from.num) {
320 num = (int) from.num;
321 }
322 if (num <= 0) return;
323
324 if (KEEP_XP_DURING_TRANSFERS && keepsXP != null) {
325 to.add(num);
326 from.remove(num, false);
327
328 float totalXP = to.xp + from.xp;
329 if (keepsXP == from) {
330 from.xp = Math.min(totalXP, from.num);
331 to.xp = Math.max(0f, totalXP - from.num);
332 } else if (keepsXP == to) {
333 to.xp = Math.min(totalXP, to.num);
334 from.xp = Math.max(0f, totalXP - to.num);
335 }
336 } else {
337 float xp = from.xp * num / from.num;
338
339 to.add(num);
340 to.addXP(xp);
341
342 from.remove(num, true); // also removes XP
343 }
344 }
345
346
347 public void reportRaidObjectivesAchieved(RaidResultData data, InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) {
348 CampaignFleetAPI fleet = Global.getSector().getPlayerFleet();
349 CargoAPI cargo = fleet.getCargo();
350 float marines = cargo.getMarines();
351
352 marineData.remove(data.marinesLost, true);
353
354 float total = marines + data.marinesLost;
355 float xpGain = 1f - data.raidEffectiveness;
356 xpGain *= total;
357 xpGain *= XP_PER_RAID_MULT;
358 if (xpGain < 0) xpGain = 0;
359 marineData.addXP(xpGain);
360
361 update();
362 }
363
364 public void update() {
365 update(false, false, null);
366 }
367 public void update(boolean withIntegrationFromCurrentLocation, boolean keepXP, CargoStackAPI stack) {
368 CampaignFleetAPI fleet = Global.getSector().getPlayerFleet();
369 if (fleet == null) return;
370 CargoAPI cargo = fleet.getCargo();
371
372
373 float marines = cargo.getMarines();
374 marineData.numMayHaveChanged(marines, keepXP);
375
376 if (withIntegrationFromCurrentLocation) {
377 //getDroppedOffAt(Commodities.MARINES, getInteractionEntity(), currSubmarket, true);
378 PersonnelAtEntity atLocation = getPersonnelAtLocation(Commodities.MARINES, currSubmarket);
379 marineData.integrateWithCurrentLocation(atLocation);
380 }
381
382
383 MutableFleetStatsAPI stats = fleet.getStats();
384
385 String id = "marineXP";
386 PersonnelRank rank = marineData.getRank();
387 float effectBonus = getMarineEffectBonus(marineData);
388 float casualtyReduction = getMarineLossesReductionPercent(marineData);
389 if (effectBonus > 0) {
390 //stats.getDynamic().getMod(Stats.PLANETARY_OPERATIONS_MOD).modifyMult(id, 1f + effectBonus * 0.01f, rank.name + " marines");
391 stats.getDynamic().getMod(Stats.PLANETARY_OPERATIONS_MOD).modifyPercent(id, effectBonus, rank.name + " marines");
392 } else {
393 //stats.getDynamic().getMod(Stats.PLANETARY_OPERATIONS_MOD).unmodifyMult(id);
394 stats.getDynamic().getMod(Stats.PLANETARY_OPERATIONS_MOD).unmodifyPercent(id);
395 }
396 if (casualtyReduction > 0) {
397 stats.getDynamic().getStat(Stats.PLANETARY_OPERATIONS_CASUALTIES_MULT).modifyMult(id, 1f - casualtyReduction * 0.01f, rank.name + " marines");
398 } else {
399 stats.getDynamic().getStat(Stats.PLANETARY_OPERATIONS_CASUALTIES_MULT).unmodifyMult(id);
400 }
401 }
402
403
404
405
406 public float getMarineEffectBonus(PersonnelData data) {
407 float f = data.getXPLevel();
408 //if (true) return 30f;
409 return Math.round(f * MAX_EFFECTIVENESS_PERCENT);
410 }
411 public float getMarineLossesReductionPercent(PersonnelData data) {
412 float f = data.getXPLevel();
413 //if (true) return 30f;
414 return Math.round(f * MAX_LOSS_REDUCTION_PERCENT);
415 }
416
417 public void addSectionAfterPrice(TooltipMakerAPI info, float width, boolean expanded, CargoStackAPI stack) {
418 if (Commodities.MARINES.equals(stack.getCommodityId()) && !expanded) {
419 saveData();
420 update(true, true, stack);
421
422 PersonnelData data = marineData;
423 boolean nonPlayer = false;
424 if (!stack.isInPlayerCargo()) {
425 nonPlayer = true;
426 PersonnelAtEntity atLoc = getPersonnelAtLocation(stack.getCommodityId(), getSubmarketFor(stack));
427 if (atLoc != null) {
428 data = atLoc.data;
429 } else {
430 data = null;
431 }
432 }
433 //if (stack.isInPlayerCargo()) {
434 if (data != null) {
435 if (data.num <= 0) {
436 restoreData();
437 return;
438 }
439
440 float opad = 10f;
441 float pad = 3f;
442 Color h = Misc.getHighlightColor();
443
444 PersonnelRank rank = data.getRank();
445
446 LabelAPI heading = info.addSectionHeading(rank.name + " Marines",
447 Misc.getBasePlayerColor(), Misc.getDarkPlayerColor(), Alignment.MID, opad);
448 heading.autoSizeToWidth(info.getTextWidthOverride());
449 PositionAPI p = heading.getPosition();
450 p.setSize(p.getWidth(), p.getHeight() + 3f);
451
452
453 switch (rank) {
454 case REGULAR:
455 if (nonPlayer) {
456 info.addPara("Regular marines - tough, competent, and disciplined.", opad);
457 } else {
458 info.addPara("These marines are mostly regulars and have seen some combat, " +
459 "but are not, overall, accustomed to your style of command.", opad);
460 }
461 break;
462 case EXPERIENCED:
463 if (nonPlayer) {
464 info.addPara("Experienced marines with substantial training and a number of " +
465 "operations under their belts.", opad);
466 } else {
467 info.addPara("You've led these marines on several operations, and " +
468 "the experience gained by both parties is beginning to show concrete benefits.", opad);
469 }
470 break;
471 case VETERAN:
472 if (nonPlayer) {
473 info.addPara("These marines are veterans of many ground operations. " +
474 "Well-motivated and highly effective.", opad);
475 } else {
476 info.addPara("These marines are veterans of many ground operations under your leadership; " +
477 "the command structure is well established and highly effective.", opad);
478 }
479 break;
480 case ELITE:
481 if (nonPlayer) {
482 info.addPara("These marines are an elite force, equipped, led, and motivated well " +
483 "above the standards of even the professional militaries in the Sector.", opad);
484 } else {
485 info.addPara("These marines are an elite force, equipped, led, and motivated well " +
486 "above the standards of even the professional militaries in the Sector.", opad);
487 }
488 break;
489
490 }
491
492 float effectBonus = getMarineEffectBonus(data);
493 float casualtyReduction = getMarineLossesReductionPercent(data);
494 MutableStat fake = new MutableStat(1f);
495 fake.modifyPercentAlways("1", effectBonus, "increased effectiveness of ground operations");
496 fake.modifyPercentAlways("2", -casualtyReduction, "reduction to marine casualties suffered during ground operations");
497 info.addStatModGrid(width, 50f, 10f, opad, fake, true, null);
498
499 }
500 restoreData();
501 }
502 }
503
504
505 public void reportPlayerClosedMarket(MarketAPI market) {
506 update();
507 }
508 public void reportPlayerOpenedMarket(MarketAPI market) {
509 update();
510 }
511
512
513 public String getIconName() {
514 return null;
515 }
516
517
518 public int getHandlingPriority(Object params) {
519 if (params instanceof CommodityIconProviderWrapper) {
520 CargoStackAPI stack = ((CommodityIconProviderWrapper) params).stack;
521 if (Commodities.MARINES.equals(stack.getCommodityId())) {
522 if (stack.isInPlayerCargo()) {
523 return GenericPluginManagerAPI.CORE_GENERAL;
524 }
525
526 SubmarketAPI sub = getSubmarketFor(stack);
527 PersonnelAtEntity atLocation = getPersonnelAtLocation(stack.getCommodityId(), sub);
528 if (atLocation != null) {
529 return GenericPluginManagerAPI.CORE_GENERAL;
530 }
531 }
532 }
533 return -1;
534 }
535
536// public PersonnelRank getFleetMarineRank() {
537// PersonnelAtEntity atLocation = getPersonnelAtLocation(Commodities.MARINES);
538// PersonnelRank rank = marineData.getRank(atLocation);
539// return rank;
540// }
541
542
543 public String getRankIconName(CargoStackAPI stack) {
544 if (stack.isPickedUp()) return null;
545 saveData();
546 update(true, true, stack);
547 PersonnelData data = null;
548
549 if (stack.isMarineStack()) {
550 data = marineData;
551 if (!stack.isInPlayerCargo()) {
552 SubmarketAPI sub = getSubmarketFor(stack);
553 PersonnelAtEntity atLocation = getPersonnelAtLocation(stack.getCommodityId(), sub);
554 if (atLocation != null) {
555 data = atLocation.data;
556 } else {
557 restoreData();
558 return null;
559 }
560 }
561 }
562
563
564 if (data == null || data.num <= 0) {
565 restoreData();
566 return null;
567 }
568
569 PersonnelRank rank = data.getRank();
570 restoreData();
571 return Global.getSettings().getSpriteName("ui", rank.iconKey);
572 }
573
574 public String getIconName(CargoStackAPI stack) {
575 return null;
576 }
577
578
579 protected transient PersonnelData savedMarineData;
580 protected transient List<PersonnelAtEntity> savedPersonnelData = new ArrayList<PersonnelAtEntity>();
581
582 public void saveData() {
584 marineData = marineData.clone();
585
586 savedPersonnelData = new ArrayList<PersonnelAtEntity>();
587 for (PersonnelAtEntity curr : droppedOff) {
588 savedPersonnelData.add(curr.clone());
589 }
590 }
591
592 public void restoreData() {
594 savedMarineData = null;
595
596 droppedOff.clear();
598 savedPersonnelData.clear();
599 }
600
601
602 public void reportPlayerOpenedMarketAndCargoUpdated(MarketAPI market) {
603 }
604
605 public void modifyRaidObjectives(MarketAPI market, SectorEntityToken entity, List<GroundRaidObjectivePlugin> objectives, RaidType type, int marineTokens, int priority) {
606
607 }
608
609 protected void doCleanup(boolean withDroppedOff) {
610 marineData.savedNum = marineData.num;
611 marineData.savedXP = marineData.xp;
612 pods = null;
613
614 if (withDroppedOff) {
615 Iterator<PersonnelAtEntity> iter = droppedOff.iterator();
616 while (iter.hasNext()) {
617 PersonnelAtEntity pae = iter.next();
618 if (!pae.entity.isAlive() || pae.data.num <= 0 || pae.data.xp <= 0) {
619 iter.remove();
620 }
621 }
622 }
623 }
624
625 public SectorEntityToken getInteractionEntity() {
626 InteractionDialogAPI dialog = Global.getSector().getCampaignUI().getCurrentInteractionDialog();
627 SectorEntityToken entity = null;
628 if (dialog != null) {
629 entity = dialog.getInteractionTarget();
630 if (entity != null && entity.getMarket() != null && entity.getMarket().getPrimaryEntity() != null) {
631 entity = entity.getMarket().getPrimaryEntity();
632 }
633 }
634 return entity;
635 }
636
642 public SubmarketAPI getSubmarketFor(CargoStackAPI stack) {
643 if (stack.getCargo() == null) return null;
644 SectorEntityToken entity = getInteractionEntity();
645 if (entity == null || entity.getMarket() == null || entity.getMarket().getSubmarketsCopy() == null) return currSubmarket;
646
647 for (SubmarketAPI sub : entity.getMarket().getSubmarketsCopy()) {
648 if (sub.getCargo() == stack.getCargo()) {
649 return sub;
650 }
651 }
652 return currSubmarket;
653 }
654
655 public PersonnelAtEntity getDroppedOffAt(String commodityId, SectorEntityToken entity, SubmarketAPI sub, boolean createIfNull) {
656 String submarketId = sub == null ? "" : sub.getSpecId();
657 for (PersonnelAtEntity pae : droppedOff) {
658 String otherSubmarketId = pae.submarketId == null ? "" : pae.submarketId;
659 if (entity == pae.entity && commodityId.equals(pae.data.id) && submarketId.equals(otherSubmarketId)) {
660 return pae;
661 }
662 }
663 if (createIfNull) {
664 if (submarketId.isEmpty()) submarketId = null;
665 PersonnelAtEntity pae = new PersonnelAtEntity(entity, commodityId, submarketId);
666 droppedOff.add(pae);
667 return pae;
668 }
669 return null;
670 }
671
672 public PersonnelAtEntity getPersonnelAtLocation(String commodityId, SubmarketAPI sub) {
673 SectorEntityToken entity = getInteractionEntity();
674 PersonnelAtEntity atLocation = entity == null ? null : getDroppedOffAt(commodityId, entity, sub, false);
675 return atLocation;
676 }
677
678 public PersonnelData getMarineData() {
679 return marineData;
680 }
681
682 public List<PersonnelAtEntity> getDroppedOff() {
683 return droppedOff;
684 }
685
686
687}
688
689
690
691
692
693
694
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
void addSectionAfterPrice(TooltipMakerAPI info, float width, boolean expanded, CargoStackAPI stack)
void processTransaction(PlayerMarketTransaction transaction, SectorEntityToken entity)
PersonnelAtEntity getDroppedOffAt(String commodityId, SectorEntityToken entity, SubmarketAPI sub, boolean createIfNull)
void modifyRaidObjectives(MarketAPI market, SectorEntityToken entity, List< GroundRaidObjectivePlugin > objectives, RaidType type, int marineTokens, int priority)
void reportRaidObjectivesAchieved(RaidResultData data, InteractionDialogAPI dialog, Map< String, MemoryAPI > memoryMap)
PersonnelAtEntity getPersonnelAtLocation(String commodityId, SubmarketAPI sub)
void reportPlayerNonMarketTransaction(PlayerMarketTransaction transaction, InteractionDialogAPI dialog)
void update(boolean withIntegrationFromCurrentLocation, boolean keepXP, CargoStackAPI stack)
static void transferPersonnel(PersonnelData from, PersonnelData to, int num, PersonnelData keepsXP)
void reportPlayerMarketTransaction(PlayerMarketTransaction transaction)
String getSpriteName(String category, String id)