Starsector API
Loading...
Searching...
No Matches
BaseIndustry.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.econ.impl;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.HashSet;
6import java.util.Iterator;
7import java.util.LinkedHashMap;
8import java.util.List;
9import java.util.Map;
10import java.util.Random;
11import java.util.Set;
12
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.campaign.CargoAPI;
15import com.fs.starfarer.api.campaign.FactionAPI;
16import com.fs.starfarer.api.campaign.SpecialItemData;
17import com.fs.starfarer.api.campaign.SpecialItemSpecAPI;
18import com.fs.starfarer.api.campaign.comm.CommMessageAPI.MessageClickAction;
19import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
20import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
21import com.fs.starfarer.api.campaign.econ.Industry;
22import com.fs.starfarer.api.campaign.econ.InstallableIndustryItemPlugin;
23import com.fs.starfarer.api.campaign.econ.InstallableIndustryItemPlugin.InstallableItemDescriptionMode;
24import com.fs.starfarer.api.campaign.econ.MarketAPI;
25import com.fs.starfarer.api.campaign.econ.MarketAPI.MarketInteractionMode;
26import com.fs.starfarer.api.campaign.econ.MarketImmigrationModifier;
27import com.fs.starfarer.api.campaign.econ.MutableCommodityQuantity;
28import com.fs.starfarer.api.campaign.impl.items.GenericSpecialItemPlugin;
29import com.fs.starfarer.api.campaign.listeners.ListenerUtil;
30import com.fs.starfarer.api.campaign.rules.MemoryAPI;
31import com.fs.starfarer.api.combat.MutableStat;
32import com.fs.starfarer.api.combat.MutableStat.StatMod;
33import com.fs.starfarer.api.impl.campaign.DebugFlags;
34import com.fs.starfarer.api.impl.campaign.econ.impl.ConstructionQueue.ConstructionQueueItem;
35import com.fs.starfarer.api.impl.campaign.ids.Commodities;
36import com.fs.starfarer.api.impl.campaign.ids.Industries;
37import com.fs.starfarer.api.impl.campaign.ids.Items;
38import com.fs.starfarer.api.impl.campaign.ids.Sounds;
39import com.fs.starfarer.api.impl.campaign.ids.Stats;
40import com.fs.starfarer.api.impl.campaign.ids.Strings;
41import com.fs.starfarer.api.impl.campaign.ids.Tags;
42import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
43import com.fs.starfarer.api.impl.campaign.intel.MessageIntel;
44import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.RaidDangerLevel;
45import com.fs.starfarer.api.loading.IndustrySpecAPI;
46import com.fs.starfarer.api.ui.Alignment;
47import com.fs.starfarer.api.ui.IconRenderMode;
48import com.fs.starfarer.api.ui.LabelAPI;
49import com.fs.starfarer.api.ui.TooltipMakerAPI;
50import com.fs.starfarer.api.ui.TooltipMakerAPI.StatModValueGetter;
51import com.fs.starfarer.api.util.Misc;
52import com.fs.starfarer.api.util.Pair;
53
54public abstract class BaseIndustry implements Industry, Cloneable {
55
56 public static int SIZE_FOR_SMALL_IMAGE = 3;
57 public static int SIZE_FOR_LARGE_IMAGE = 6;
58
59 public static float UPKEEP_MULT = 0.75f;
60 public static int DEMAND_REDUCTION = 1;
61 public static int SUPPLY_BONUS = 1;
62
63 public static int DEFAULT_IMPROVE_SUPPLY_BONUS = 1;
64
65 @Override
66 protected BaseIndustry clone() {
67 BaseIndustry copy = null;
68 try {
69 copy = (BaseIndustry) super.clone();
70 } catch (CloneNotSupportedException e) {
71 e.printStackTrace();
72 }
73 return copy;
74 }
75
76 //public static final float ORBITAL_HAZARD = 1f;
77
78 public static final String BASE_VALUE_TEXT = "Base value for colony size";
79
80 public static String getDeficitText(String commodityId) {
81 if (commodityId == null) {
82 return "Various shortages";
83 }
84 CommoditySpecAPI spec = Global.getSettings().getCommoditySpec(commodityId);
85 return Misc.ucFirst(spec.getName().toLowerCase() + " shortage");
86 }
87
88 // want to have some ability to add random supply/demand to industries
89 // e.g. market condition adding Volturnian Lobster supply to Volturn's Farming/Aquaculture
90 protected Map<String, MutableCommodityQuantity> supply = new LinkedHashMap<String, MutableCommodityQuantity>();
91 protected Map<String, MutableCommodityQuantity> demand = new LinkedHashMap<String, MutableCommodityQuantity>();
92
93 protected MutableStat income = new MutableStat(0f);
94 protected MutableStat upkeep = new MutableStat(0f);
95 protected MarketAPI market;
96
97 protected String id;
98
99 protected float buildProgress = 0f;
100 protected float buildTime = 1f;
101 protected boolean building = false;
102 protected Boolean improved = null;
103 protected String upgradeId = null;
104
105 protected transient IndustrySpecAPI spec = null;
106
107 protected String aiCoreId = null;
108// protected int demandReduction = 0;
109// protected int supplyBonus = 0;
110
111 protected MutableStat demandReduction = new MutableStat(0);
112 protected MutableStat supplyBonus = new MutableStat(0);
113
114 protected transient MutableStat demandReductionFromOther = new MutableStat(0);
115 protected transient MutableStat supplyBonusFromOther = new MutableStat(0);
116
117
118 public BaseIndustry() {
119 //setAICoreId(Commodities.BETA_CORE);
120 }
121
122 public MutableStat getDemandReduction() {
123 return demandReduction;
124 }
125
126 public MutableStat getSupplyBonus() {
127 return supplyBonus;
128 }
129
130 public MutableStat getDemandReductionFromOther() {
131 if (demandReductionFromOther == null) {
132 demandReductionFromOther = new MutableStat(0);
133 }
135 }
136
137 public MutableStat getSupplyBonusFromOther() {
138 if (supplyBonusFromOther == null) {
139 supplyBonusFromOther = new MutableStat(0);
140 }
142 }
143
144 public void init(String id, MarketAPI market) {
145 this.id = id;
146 this.market = market;
147 readResolve();
148 }
149
150 private transient String modId;
151 private transient String [] modIds;
152 protected Object readResolve() {
154
155 if (buildTime < 1f) buildTime = 1f;
156
157 modId = "ind_" + id;
158 modIds = new String[10];
159 for (int i = 0; i < modIds.length; i++) {
160 modIds[i] = modId + "_" + i;
161 }
162
163 if (demandReduction == null) demandReduction = new MutableStat(0);
164 if (supplyBonus == null) supplyBonus = new MutableStat(0);
165
166 if (supply != null) {
167 for (String id : new ArrayList<String>(supply.keySet())) {
168 MutableCommodityQuantity stat = supply.get(id);
169 stat.getQuantity().unmodifyFlat("ind_sb");
170 }
171 }
172 if (demand != null) {
173 for (String id : new ArrayList<String>(demand.keySet())) {
174 MutableCommodityQuantity stat = demand.get(id);
175 stat.getQuantity().unmodifyFlat("ind_dr");
176 }
177 }
178
179 return this;
180 }
181
182 protected Object writeReplace() {
183// BaseIndustry copy = clone();
184// copy.supply = null;
185// copy.demand = null;
186// return copy;
188 return this;
189 }
190
191
192 public void apply(boolean withIncomeUpdate) {
194
195 if (withIncomeUpdate) {
197 }
198
201
202 if (this instanceof MarketImmigrationModifier) {
203 market.addTransientImmigrationModifier((MarketImmigrationModifier) this);
204 }
205
206 if (special != null) {
208 if (effect != null) {
209 List<String> unmet = effect.getUnmetRequirements(this);
210 if (unmet == null || unmet.isEmpty()) {
211 effect.apply(this);
212 } else {
213 effect.unapply(this);
214 }
215 }
216 }
217 }
218
219 public void unapply() {
221
222 Boolean wasImproved = improved;
223 improved = null;
224 applyImproveModifiers(); // to unapply them
225 improved = wasImproved;
226
227 if (this instanceof MarketImmigrationModifier) {
228 market.removeTransientImmigrationModifier((MarketImmigrationModifier) this);
229 }
230
231 if (special != null) {
233 if (effect != null) {
234 effect.unapply(this);
235 }
236 }
237 }
238
239 protected void applyAICoreModifiers() {
240 if (aiCoreId == null) {
242 return;
243 }
244 boolean alpha = aiCoreId.equals(Commodities.ALPHA_CORE);
245 boolean beta = aiCoreId.equals(Commodities.BETA_CORE);
246 boolean gamma = aiCoreId.equals(Commodities.GAMMA_CORE);
247 if (alpha) applyAlphaCoreModifiers();
248 else if (beta) applyBetaCoreModifiers();
249 else if (gamma) applyGammaCoreModifiers();
250 }
251
252 protected void applyAlphaCoreModifiers() {}
253 protected void applyBetaCoreModifiers() {}
254 protected void applyGammaCoreModifiers() {}
255 protected void applyNoAICoreModifiers() {}
256
257
258
259 protected String getModId() {
260 //return "ind_" + id;
261 return modId;
262 }
263
264 protected String getModId(int index) {
265 //return "ind_" + id + "_" + index;
266 return modIds[index];
267 }
268
269 public void demand(String commodityId, int quantity) {
270 demand(0, commodityId, quantity, BASE_VALUE_TEXT);
271 }
272
273 public void demand(String commodityId, int quantity, String desc) {
274 demand(0, commodityId, quantity, desc);
275 }
276 public void demand(int index, String commodityId, int quantity, String desc) {
277 demand(getModId(index), commodityId, quantity, desc);
278 }
279 public void demand(String modId, String commodityId, int quantity, String desc) {
280// if (commodityId != null && commodityId.equals("organics") && getId().contains("military")) {
281// System.out.println("wefwefwe");
282// }
283 //quantity -= demandReduction;
284 // want to apply negative numbers here so they add up with anything coming in from market conditions
285 if (quantity == 0) {
286 getDemand(commodityId).getQuantity().unmodifyFlat(modId);
287 } else {
288 getDemand(commodityId).getQuantity().modifyFlat(modId, quantity, desc);
289 }
290
291 if (quantity > 0) {
292 if (!demandReduction.isUnmodified()) {
293 getDemand(commodityId).getQuantity().modifyFlat("ind_dr", -demandReduction.getModifiedInt());
294 } else {
295 getDemand(commodityId).getQuantity().unmodifyFlat("ind_dr");
296 }
297 }
298 }
299
300 public void supply(String commodityId, int quantity) {
301 supply(0, commodityId, quantity, BASE_VALUE_TEXT);
302 }
303
304 public void supply(String commodityId, int quantity, String desc) {
305 supply(0, commodityId, quantity, desc);
306 }
307
308 public void supply(int index, String commodityId, int quantity, String desc) {
309 supply(getModId(index), commodityId, quantity, desc);
310 }
311 public void supply(String modId, String commodityId, int quantity, String desc) {
312// if (this instanceof Mining && market.getName().equals("Medea") &&
313// Commodities.VOLATILES.equals(commodityId)) {
314// System.out.println("efwefwe");
315// }
316
317 //quantity += supplyBonus; doesn't work gets applied multiple times potentially
318 // want to apply negative numbers here so they add up with anything coming in from market conditions
319 if (quantity == 0) {
320 getSupply(commodityId).getQuantity().unmodifyFlat(modId);
321 } else {
322 getSupply(commodityId).getQuantity().modifyFlat(modId, quantity, desc);
323 }
324
325 if (quantity > 0) {
326 //if (!getSupply(commodityId).getQuantity().isUnmodified()) {
327 if (!supplyBonus.isUnmodified()) {
328 getSupply(commodityId).getQuantity().modifyFlat("ind_sb", supplyBonus.getModifiedInt());
329 } else {
330 getSupply(commodityId).getQuantity().unmodifyFlat("ind_sb");
331 }
332 }
333 //getSupply(commodityId).getQuantity().unmodifyFlat("ind_sb");
334 }
335
336 protected void applyDeficitToProduction(int index, Pair<String, Integer> deficit, String ... commodities) {
337 for (String commodity : commodities) {
338// if (this instanceof Mining && market.getName().equals("Louise")) {
339// System.out.println("efwefwe");
340// }
341 if (getSupply(commodity).getQuantity().isUnmodified()) continue;
342 supply(index, commodity, -deficit.two, getDeficitText(deficit.one));
343 }
344 }
345
346// public static float getIncomeStabilityMult(float stability) {
347// if (stability <= 5) {
348// return Math.max(0, stability / 5f);
349// }
350// return 1f + (stability - 5f) * .1f;
351// }
352
353 public void updateIncomeAndUpkeep() {
355 }
356
357 protected void applyIncomeAndUpkeep(float sizeOverride) {
358 float size = market.getSize();
359 if (sizeOverride >= 0) size = sizeOverride;
360 float sizeMult = getSizeMult(size);
361 sizeMult = Math.max(1, sizeMult - 2);
362
363 float stabilityMult = market.getIncomeMult().getModifiedValue();
364 float upkeepMult = market.getUpkeepMult().getModifiedValue();
365// if (hazardMultOverride >= 0) {
366// upkeepMult = hazardMultOverride;
367// }
368
369
370 int income = (int) (getSpec().getIncome() * sizeMult);
371 if (income != 0) {
372 getIncome().modifyFlatAlways("ind_base", income, "Base value");
373 getIncome().modifyMultAlways("ind_stability", stabilityMult, "Market income multiplier");
374 } else {
375 getIncome().unmodifyFlat("ind_base");
376 getIncome().unmodifyMult("ind_stability");
377 }
378
379
380 int upkeep = (int) (getSpec().getUpkeep() * sizeMult);
381 if (upkeep != 0) {
382 getUpkeep().modifyFlatAlways("ind_base", upkeep, "Base value");
383 getUpkeep().modifyMultAlways("ind_hazard", upkeepMult, "Market upkeep multiplier");
384 } else {
385 getUpkeep().unmodifyFlat("ind_base");
386 getUpkeep().unmodifyMult("ind_hazard");
387 }
388
390
391 if (!isFunctional()) {
392 getIncome().unmodifyFlat("ind_base");
393 getIncome().unmodifyMult("ind_stability");
394 }
395 }
396
397// public static float getUpkeepMult(MarketAPI market) {
398// return getUpkeepHazardMult(market.getHazardValue());
399// }
400// public static float getUpkeepHazardMult(float hazard) {
401// float hazardMult = hazard;
402// if (hazardMult < 0) hazardMult = 0;
403// return hazardMult;
404// }
405
406 public float getBuildTime() {
407 return getSpec().getBuildTime();
408 }
409
410 protected Float buildCostOverride = null;
411 public Float getBuildCostOverride() {
412 return buildCostOverride;
413 }
415 this.buildCostOverride = buildCostOverride;
416 }
417 public float getBuildCost() {
418 if (buildCostOverride != null) return buildCostOverride;
419 return getSpec().getCost();
420 }
421
422 public float getBaseUpkeep() {
423 float size = market.getSize();
424 float sizeMult = getSizeMult(size);
425 sizeMult = Math.max(1, sizeMult - 2);
426 return getSpec().getUpkeep() * sizeMult;
427 }
428
429// public float getActualUpkeep() {
430// return getBaseUpkeep() * market.getUpkeepMult().getModifiedValue();
431// }
432
433 protected boolean wasDisrupted = false;
434 public void advance(float amount) {
435 boolean disrupted = isDisrupted();
436 if (!disrupted && wasDisrupted) {
438 }
439 wasDisrupted = disrupted;
440
441// if (disrupted) {
442// //if (DebugFlags.COLONY_DEBUG) {
443// String key = getDisruptedKey();
444// market.getMemoryWithoutUpdate().unset(key);
445// //}
446// }
447
448 if (building && !disrupted) {
449 float days = Global.getSector().getClock().convertToDays(amount);
450 //DebugFlags.COLONY_DEBUG = true;
452 days *= 100f;
453 }
454 buildProgress += days;
455
456 if (buildProgress >= buildTime) {
458 }
459 }
460
461 }
462
463 protected void notifyDisrupted() {
464
465 }
466
467 protected void disruptionFinished() {
468
469 }
470
471 public boolean isBuilding() {
472 return building;
473 }
474
475 public boolean isFunctional() {
476 if (isDisrupted()) return false;
477 return !(isBuilding() && !isUpgrading());
478 }
479
480 public boolean isUpgrading() {
481 return building && upgradeId != null;
482 }
483
485 if (isDisrupted()) {
486 return 0f;
487 }
488 if (!isBuilding()) return 0f;
489
490 return Math.min(1f, buildProgress / buildTime);
491 }
492
494 if (isDisrupted()) {
495 int left = (int) getDisruptedDays();
496 if (left < 1) left = 1;
497 String days = "days";
498 if (left == 1) days = "day";
499
500 return "" + left + " " + days + "";
501 }
502
503 int left = (int) (buildTime - buildProgress);
504 if (left < 1) left = 1;
505 String days = "days";
506 if (left == 1) days = "day";
507
508 return left + " " + days;
509 }
510
512 if (isDisrupted()) {
513 int left = (int) getDisruptedDays();
514 if (left < 1) left = 1;
515 String days = "days";
516 if (left == 1) days = "day";
517
518 return "Disrupted: " + left + " " + days + " left";
519 }
520
521 int left = (int) (buildTime - buildProgress);
522 if (left < 1) left = 1;
523 String days = "days";
524 if (left == 1) days = "day";
525
526// if (isBuilding() && !isUpgrading()) {
527// //return left + " " + days;
528// return "building: " + (int)Math.round(buildProgress / buildTime * 100f) + "%";
529// }
530
531 if (isUpgrading()) {
532 return "Upgrading: " + left + " " + days + " left";
533 } else {
534 return "Building: " + left + " " + days + " left";
535 }
536 }
537
538 public void startBuilding() {
539 building = true;
540 buildProgress = 0;
541 upgradeId = null;
542
543 buildTime = spec.getBuildTime();
544 unapply();
545 }
546
548 building = false;
549 buildProgress = 0;
550 buildTime = 1f;
551 if (upgradeId != null) {
552 market.removeIndustry(getId(), null, true);
553 market.addIndustry(upgradeId);
554 BaseIndustry industry = (BaseIndustry) market.getIndustry(upgradeId);
555 industry.setAICoreId(getAICoreId());
556 industry.setImproved(isImproved());
557 industry.upgradeFinished(this);
558 industry.reapply();
559 } else {
561 reapply();
562 }
563 }
564
565 public void startUpgrading() {
566 building = true;
567 buildProgress = 0;
568 upgradeId = getSpec().getUpgrade();
569
570
571 IndustrySpecAPI upgrade = Global.getSettings().getIndustrySpec(upgradeId);
572 buildTime = upgrade.getBuildTime();
573 }
574
575 public void cancelUpgrade() {
576 building = false;
577 buildProgress = 0;
578 upgradeId = null;
579 }
580
581 public void downgrade() {
582 building = true;
583 buildProgress = 0;
584 upgradeId = getSpec().getDowngrade();
586 }
587
588
589 public void reapply() {
590 unapply();
591 apply();
592 }
593
598
599 public static void buildNextInQueue(MarketAPI market) {
600 ConstructionQueueItem next = null;
601 Iterator<ConstructionQueueItem> iter = market.getConstructionQueue().getItems().iterator();
602 while (iter.hasNext()) {
603 next = iter.next();
604 iter.remove();
605
606 Industry ind = market.instantiateIndustry(next.id);
607 int num = Misc.getNumIndustries(market);
608 int max = Misc.getMaxIndustries(market);
609 if (ind.isAvailableToBuild() && (num <= max || !ind.isIndustry())) { // <= because num includes what's queued
610 break;
611 } else {
612 if (market.isPlayerOwned()) {
613 MessageIntel intel = new MessageIntel(ind.getCurrentName() + " at " + market.getName(), Misc.getBasePlayerColor());
614 intel.addLine(BaseIntelPlugin.BULLET + "Construction aborted");
615
616 int refund = next.cost;
617 Global.getSector().getPlayerFleet().getCargo().getCredits().add(refund);
618 intel.addLine(BaseIntelPlugin.BULLET + "%s refunded",
619 Misc.getTextColor(),
620 new String [] {Misc.getDGSCredits(refund)}, Misc.getHighlightColor());
621 intel.setIcon(Global.getSector().getPlayerFaction().getCrest());
622 intel.setSound(BaseIntelPlugin.getSoundStandardUpdate());
623 Global.getSector().getCampaignUI().addMessage(intel, MessageClickAction.COLONY_INFO, market);
624 }
625 next = null;
626 }
627 }
628
629 if (next != null) {
630 market.addIndustry(next.id);
631 Industry ind = market.getIndustry(next.id);
632 ind.startBuilding();
633 if (ind instanceof BaseIndustry) {
634 ((BaseIndustry)ind).setBuildCostOverride(next.cost);
635 }
636
637 if (market.isPlayerOwned()) {
638 MessageIntel intel = new MessageIntel(ind.getCurrentName() + " at " + market.getName(), Misc.getBasePlayerColor());
639 intel.addLine(BaseIntelPlugin.BULLET + "Construction started");
640 intel.setIcon(Global.getSector().getPlayerFaction().getCrest());
641 intel.setSound(BaseIntelPlugin.getSoundStandardUpdate());
642 Global.getSector().getCampaignUI().addMessage(intel, MessageClickAction.COLONY_INFO, market);
643 }
644 }
645 }
646
647 protected void upgradeFinished(Industry previous) {
649
650 setSpecialItem(previous.getSpecialItem());
651 }
652
653 protected void sendBuildOrUpgradeMessage() {
654 if (market.isPlayerOwned()) {
655 MessageIntel intel = new MessageIntel(getCurrentName() + " at " + market.getName(), Misc.getBasePlayerColor());
656 intel.addLine(BaseIntelPlugin.BULLET + "Construction completed");
657 intel.setIcon(Global.getSector().getPlayerFaction().getCrest());
658 intel.setSound(BaseIntelPlugin.getSoundStandardUpdate());
659 Global.getSector().getCampaignUI().addMessage(intel, MessageClickAction.COLONY_INFO, market);
660 }
661 }
662
663 public void notifyBeingRemoved(MarketInteractionMode mode, boolean forUpgrade) {
664 if (aiCoreId != null && !forUpgrade) {
665 CargoAPI cargo = getCargoForInteractionMode(mode);
666 if (cargo != null) {
667 cargo.addCommodity(aiCoreId, 1);
668 }
669 }
670
671 if (special != null && !forUpgrade) {
672 CargoAPI cargo = getCargoForInteractionMode(mode);
673 if (cargo != null) {
674 cargo.addSpecial(special, 1);
675 }
676 }
677 }
678
679 protected CargoAPI getCargoForInteractionMode(MarketInteractionMode mode) {
680 CargoAPI cargo = null;
681 if (mode == null) return null;
682
683 if (mode == MarketInteractionMode.REMOTE) {
684 cargo = Misc.getStorageCargo(market);
685 } else {
686 cargo = Global.getSector().getPlayerFleet().getCargo();
687 }
688 return cargo;
689 }
690
691 public String getId() {
692 return id;
693 }
694
695 public IndustrySpecAPI getSpec() {
696 if (spec == null) spec = Global.getSettings().getIndustrySpec(id);
697 return spec;
698 }
699
700 public void clearUnmodified() {
701 if (supply != null) {
702 for (String id : new ArrayList<String>(supply.keySet())) {
703 MutableCommodityQuantity stat = supply.get(id);
704 if (stat != null && (stat.getQuantity().isUnmodified() || stat.getQuantity().getModifiedValue() <= 0)) {
705 supply.remove(id);
706 }
707 }
708 }
709 if (demand != null) {
710 for (String id : new ArrayList<String>(demand.keySet())) {
711 MutableCommodityQuantity stat = demand.get(id);
712 if (stat != null && (stat.getQuantity().isUnmodified() || stat.getQuantity().getModifiedValue() <= 0)) {
713 demand.remove(id);
714 }
715 }
716 }
717 }
718
719 public List<MutableCommodityQuantity> getAllDemand() {
720 List<MutableCommodityQuantity> result = new ArrayList<MutableCommodityQuantity>();
721 for (MutableCommodityQuantity q : demand.values()) {
722 if (q.getQuantity().getModifiedValue() > 0) {
723 result.add(q);
724 }
725 }
726 return result;
727 }
728
729 public List<MutableCommodityQuantity> getAllSupply() {
730 List<MutableCommodityQuantity> result = new ArrayList<MutableCommodityQuantity>();
731 for (MutableCommodityQuantity q : supply.values()) {
732 if (q.getQuantity().getModifiedValue() > 0) {
733 result.add(q);
734 }
735 }
736 return result;
737 }
738
739 public MutableCommodityQuantity getSupply(String id) {
740 MutableCommodityQuantity stat = supply.get(id);
741 if (stat == null) {
742 stat = new MutableCommodityQuantity(id);
743 supply.put(id, stat);
744 }
745 return stat;
746 }
747
748 public MutableCommodityQuantity getDemand(String id) {
749 MutableCommodityQuantity stat = demand.get(id);
750 if (stat == null) {
751 stat = new MutableCommodityQuantity(id);
752 demand.put(id, stat);
753 }
754 return stat;
755 }
756
757 public MutableStat getIncome() {
758 return income;
759 }
760
761 public MutableStat getUpkeep() {
762 return upkeep;
763 }
764
765 public MarketAPI getMarket() {
766 return market;
767 }
768
769// public String getMaxDeficitCommodity(String ... commodityIds) {
770// int max = 0;
771// String result = null;
772// for (String id : commodityIds) {
773// int demand = (int) getDemand(id).getQuantity().getModifiedValue();
774// CommodityOnMarketAPI com = market.getCommodityData(id);
775// int available = com.getAvailable();
776//
777// int deficit = Math.max(demand - available, 0);
778// if (deficit > max) {
779// max = deficit;
780// result = id;
781// }
782// }
783// return result;
784// }
785//
786// public int getMaxDeficit(String ... commodityIds) {
787// int max = 0;
788// for (String id : commodityIds) {
789// int demand = (int) getDemand(id).getQuantity().getModifiedValue();
790// CommodityOnMarketAPI com = market.getCommodityData(id);
791// int available = com.getAvailable();
792//
793// int deficit = Math.max(demand - available, 0);
794// if (deficit > max) max = deficit;
795// }
796// return max;
797// }
798
799 public Pair<String, Integer> getMaxDeficit(String ... commodityIds) {
800 Pair<String, Integer> result = new Pair<String, Integer>();
801 result.two = 0;
802 for (String id : commodityIds) {
803 int demand = (int) getDemand(id).getQuantity().getModifiedValue();
804 CommodityOnMarketAPI com = market.getCommodityData(id);
805 int available = com.getAvailable();
806
807 int deficit = Math.max(demand - available, 0);
808 if (deficit > result.two) {
809 result.one = id;
810 result.two = deficit;
811 }
812 }
813 return result;
814 }
815
816 public List<Pair<String, Integer>> getAllDeficit() {
817 List<String> commodities = new ArrayList<String>();
818 for (MutableCommodityQuantity curr : demand.values()) {
819 commodities.add(curr.getCommodityId());
820 }
821 return getAllDeficit(commodities.toArray(new String[0]));
822 }
823
824 public List<Pair<String, Integer>> getAllDeficit(String ... commodityIds) {
825 List<Pair<String, Integer>> result = new ArrayList<Pair<String,Integer>>();
826 for (String id : commodityIds) {
827 int demand = (int) getDemand(id).getQuantity().getModifiedValue();
828 CommodityOnMarketAPI com = market.getCommodityData(id);
829 int available = com.getAvailable();
830
831 int deficit = Math.max(demand - available, 0);
832 if (deficit > 0) {
833 Pair<String, Integer> curr = new Pair<String, Integer>();
834 curr.one = id;
835 curr.two = deficit;
836 result.add(curr);
837 }
838 }
839 return result;
840 }
841
842 public float getSizeMult() {
843 return getSizeMult(market.getSize());
844 }
845 public static float getCommodityEconUnitMult(float size) {
846 if (size <= 0) return 0f;
847// if (size == 1) return 0.2f;
848// if (size == 2) return 0.3f;
849// if (size == 3) return 0.5f;
850 return 1f;
851 }
852 public static float getSizeMult(float size) {
853 if (size <= 0) return 0f;
854// if (size == 1) return 0.2f;
855// if (size == 2) return 0.5f;
856// return size - 2f;
857 return size;
858
859// if (size <= 1) return 0.2f;
860// if (size == 2) return 0.3f;
861// if (size == 3) return 0.5f;
862// return size - 3f;
863
864// if (size == 4) return 2f;
865// if (size == 5) return 4f;
866// if (size == 6) return 8f;
867// if (size == 7) return 16f;
868// if (size == 8) return 32f;
869// if (size == 9) return 64f;
870// if (size == 10) return 128f;
871//
872// return (float) Math.pow(2, size - 3);
873 }
874
875
876 public void doPreSaveCleanup() {
877 supply = null;
878 demand = null;
879 income = null;
880 upkeep = null;
881 }
882
883 public void doPostSaveRestore() {
884 supply = new LinkedHashMap<String, MutableCommodityQuantity>();
885 demand = new LinkedHashMap<String, MutableCommodityQuantity>();
886
887 income = new MutableStat(0f);
888 upkeep = new MutableStat(0f);
889 }
890
891
892 public String getCurrentImage() {
893 return getSpec().getImageName();
894 }
895
896 public String getCurrentName() {
897 return getSpec().getName();
898 }
899
900 public boolean isAvailableToBuild() {
901 if (market.hasTag(Tags.MARKET_NO_INDUSTRIES_ALLOWED)) return false;
902 return market.hasIndustry(Industries.POPULATION) && !getId().equals(Industries.POPULATION);
903 }
904
905 public boolean showWhenUnavailable() {
906 if (market.hasTag(Tags.MARKET_NO_INDUSTRIES_ALLOWED)) return false;
907 return true;
908 }
909
910 public String getUnavailableReason() {
911 return "Can not be built";
912 }
913
914 public boolean isTooltipExpandable() {
915 return false;
916 }
917
918 public float getTooltipWidth() {
919 return 400f;
920 }
921
922 protected transient IndustryTooltipMode currTooltipMode = null;
923 public void createTooltip(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded) {
924 currTooltipMode = mode;
925
926 float pad = 3f;
927 float opad = 10f;
928
929 FactionAPI faction = market.getFaction();
930 Color color = faction.getBaseUIColor();
931 Color dark = faction.getDarkUIColor();
932 Color grid = faction.getGridUIColor();
933 Color bright = faction.getBrightUIColor();
934
935 Color gray = Misc.getGrayColor();
936 Color highlight = Misc.getHighlightColor();
937 Color bad = Misc.getNegativeHighlightColor();
938
939
940 MarketAPI copy = market.clone();
941 // the copy is a shallow copy and its conditions point to the original market
942 // so, make it share the suppressed conditions list, too, otherwise
943 // e.g. SolarArray will suppress conditions in the original market and the copy will still apply them
944 copy.setSuppressedConditions(market.getSuppressedConditions());
945 copy.setRetainSuppressedConditionsSetWhenEmpty(true);
946 market.setRetainSuppressedConditionsSetWhenEmpty(true);
947 MarketAPI orig = market;
948
949 //int numBeforeAdd = Misc.getNumIndustries(market);
950
951 market = copy;
952 boolean needToAddIndustry = !market.hasIndustry(getId());
953 //addDialogMode = true;
954 if (needToAddIndustry) market.getIndustries().add(this);
955
956 if (mode != IndustryTooltipMode.NORMAL) {
957 market.clearCommodities();
958 for (CommodityOnMarketAPI curr : market.getAllCommodities()) {
959 curr.getAvailableStat().setBaseValue(100);
960 }
961 }
962
963// if (addDialogMode) {
964// market.reapplyConditions();
965// apply();
966// }
967 market.reapplyConditions();
968 reapply();
969
970 String type = "";
971 if (isIndustry()) type = " - Industry";
972 if (isStructure()) type = " - Structure";
973
974 tooltip.addTitle(getCurrentName() + type, color);
975
976 String desc = spec.getDesc();
977 String override = getDescriptionOverride();
978 if (override != null) {
979 desc = override;
980 }
981 desc = Global.getSector().getRules().performTokenReplacement(null, desc, market.getPrimaryEntity(), null);
982
983 tooltip.addPara(desc, opad);
984
985// Industry inProgress = Misc.getCurrentlyBeingConstructed(market);
986// if ((mode == IndustryTooltipMode.ADD_INDUSTRY && inProgress != null) ||
987// (mode == IndustryTooltipMode.UPGRADE && inProgress != null)) {
988// //tooltip.addPara("Another project (" + inProgress.getCurrentName() + ") in progress", bad, opad);
989// //tooltip.addPara("Already building: " + inProgress.getCurrentName() + "", bad, opad);
990// tooltip.addPara("Another construction in progress: " + inProgress.getCurrentName() + "", bad, opad);
991// }
992
993 //tooltip.addPara("Type: %s", opad, gray, highlight, type);
994 if (isIndustry() && (mode == IndustryTooltipMode.ADD_INDUSTRY ||
995 mode == IndustryTooltipMode.UPGRADE ||
996 mode == IndustryTooltipMode.DOWNGRADE)
997 ) {
998
999 int num = Misc.getNumIndustries(market);
1000 int max = Misc.getMaxIndustries(market);
1001
1002
1003 // during the creation of the tooltip, the market has both the current industry
1004 // and the upgrade/downgrade. So if this upgrade/downgrade counts as an industry, it'd count double if
1005 // the current one is also an industry. Thus reduce num by 1 if that's the case.
1006 if (isIndustry()) {
1007 if (mode == IndustryTooltipMode.UPGRADE) {
1008 for (Industry curr : market.getIndustries()) {
1009 if (getSpec().getId().equals(curr.getSpec().getUpgrade())) {
1010 if (curr.isIndustry()) {
1011 num--;
1012 }
1013 break;
1014 }
1015 }
1016 } else if (mode == IndustryTooltipMode.DOWNGRADE) {
1017 for (Industry curr : market.getIndustries()) {
1018 if (getSpec().getId().equals(curr.getSpec().getDowngrade())) {
1019 if (curr.isIndustry()) {
1020 num--;
1021 }
1022 break;
1023 }
1024 }
1025 }
1026 }
1027
1028 Color c = gray;
1029 c = Misc.getTextColor();
1030 Color h1 = highlight;
1031 Color h2 = highlight;
1032 if (num > max) {// || (num >= max && mode == IndustryTooltipMode.ADD_INDUSTRY)) {
1033 //c = bad;
1034 h1 = bad;
1035 num--;
1036
1037 tooltip.addPara("Maximum number of industries reached", bad, opad);
1038 }
1039 //tooltip.addPara("Maximum of %s industries on a colony of this size. Currently: %s.",
1040// LabelAPI label = tooltip.addPara("Maximum industries for a colony of this size: %s. Industries: %s. ",
1041// opad, c, h1, "" + max, "" + num);
1042// label.setHighlightColors(h2, h1);
1043 }
1044
1045
1046
1047 addRightAfterDescriptionSection(tooltip, mode);
1048
1049 if (isDisrupted()) {
1050 int left = (int) getDisruptedDays();
1051 if (left < 1) left = 1;
1052 String days = "days";
1053 if (left == 1) days = "day";
1054
1055 tooltip.addPara("Operations disrupted! %s " + days + " until return to normal function.",
1056 opad, Misc.getNegativeHighlightColor(), highlight, "" + left);
1057 }
1058
1059 if (DebugFlags.COLONY_DEBUG || market.isPlayerOwned()) {
1060 if (mode == IndustryTooltipMode.NORMAL) {
1061 if (getSpec().getUpgrade() != null && !isBuilding()) {
1062 tooltip.addPara("Click to manage or upgrade", Misc.getPositiveHighlightColor(), opad);
1063 } else {
1064 tooltip.addPara("Click to manage", Misc.getPositiveHighlightColor(), opad);
1065 }
1066 //tooltip.addPara("Click to manage", market.getFaction().getBrightUIColor(), opad);
1067 }
1068 }
1069
1070 if (mode == IndustryTooltipMode.QUEUED) {
1071 tooltip.addPara("Click to remove or adjust position in queue", Misc.getPositiveHighlightColor(), opad);
1072 tooltip.addPara("Currently queued for construction. Does not have any impact on the colony.", opad);
1073
1074 int left = (int) (getSpec().getBuildTime());
1075 if (left < 1) left = 1;
1076 String days = "days";
1077 if (left == 1) days = "day";
1078 tooltip.addPara("Requires %s " + days + " to build.", opad, highlight, "" + left);
1079
1080 //return;
1081 } else if (!isFunctional() && mode == IndustryTooltipMode.NORMAL && !isDisrupted()) {
1082 tooltip.addPara("Currently under construction and not producing anything or providing other benefits.", opad);
1083
1084 int left = (int) (buildTime - buildProgress);
1085 if (left < 1) left = 1;
1086 String days = "days";
1087 if (left == 1) days = "day";
1088 tooltip.addPara("Requires %s more " + days + " to finish building.", opad, highlight, "" + left);
1089 }
1090
1091
1092 if (!isAvailableToBuild() &&
1093 (mode == IndustryTooltipMode.ADD_INDUSTRY ||
1094 mode == IndustryTooltipMode.UPGRADE ||
1095 mode == IndustryTooltipMode.DOWNGRADE)) {
1096 String reason = getUnavailableReason();
1097 if (reason != null) {
1098 tooltip.addPara(reason, bad, opad);
1099 }
1100 }
1101
1102 boolean category = getSpec().hasTag(Industries.TAG_PARENT);
1103
1104 if (!category) {
1105 int credits = (int) Global.getSector().getPlayerFleet().getCargo().getCredits().get();
1106 String creditsStr = Misc.getDGSCredits(credits);
1107 if (mode == IndustryTooltipMode.UPGRADE || mode == IndustryTooltipMode.ADD_INDUSTRY) {
1108 int cost = (int) getBuildCost();
1109 String costStr = Misc.getDGSCredits(cost);
1110
1111 int days = (int) getBuildTime();
1112 String daysStr = "days";
1113 if (days == 1) daysStr = "day";
1114
1115 LabelAPI label = null;
1116 if (mode == IndustryTooltipMode.UPGRADE) {
1117 label = tooltip.addPara("%s and %s " + daysStr + " to upgrade. You have %s.", opad,
1118 highlight, costStr, "" + days, creditsStr);
1119 } else {
1120 label = tooltip.addPara("%s and %s " + daysStr + " to build. You have %s.", opad,
1121 highlight, costStr, "" + days, creditsStr);
1122 }
1123 label.setHighlight(costStr, "" + days, creditsStr);
1124 if (credits >= cost) {
1125 label.setHighlightColors(highlight, highlight, highlight);
1126 } else {
1127 label.setHighlightColors(bad, highlight, highlight);
1128 }
1129 } else if (mode == IndustryTooltipMode.DOWNGRADE) {
1130 if (getSpec().getUpgrade() != null) {
1131 float refundFraction = Global.getSettings().getFloat("industryRefundFraction");
1132
1133 //int cost = (int) (getBuildCost() * refundFraction);
1134 IndustrySpecAPI spec = Global.getSettings().getIndustrySpec(getSpec().getUpgrade());
1135 int cost = (int) (spec.getCost() * refundFraction);
1136 String refundStr = Misc.getDGSCredits(cost);
1137
1138 tooltip.addPara("%s refunded for downgrade.", opad, highlight, refundStr);
1139 }
1140 }
1141
1142
1143 addPostDescriptionSection(tooltip, mode);
1144
1145 if (!getIncome().isUnmodified()) {
1146 int income = getIncome().getModifiedInt();
1147 tooltip.addPara("Monthly income: %s", opad, highlight, Misc.getDGSCredits(income));
1148 tooltip.addStatModGrid(300, 65, 10, pad, getIncome(), true, new StatModValueGetter() {
1149 public String getPercentValue(StatMod mod) {return null;}
1150 public String getMultValue(StatMod mod) {return null;}
1151 public Color getModColor(StatMod mod) {return null;}
1152 public String getFlatValue(StatMod mod) {
1153 return Misc.getWithDGS(mod.value) + Strings.C;
1154 }
1155 });
1156 }
1157
1158 if (!getUpkeep().isUnmodified()) {
1159 int upkeep = getUpkeep().getModifiedInt();
1160 tooltip.addPara("Monthly upkeep: %s", opad, highlight, Misc.getDGSCredits(upkeep));
1161 tooltip.addStatModGrid(300, 65, 10, pad, getUpkeep(), true, new StatModValueGetter() {
1162 public String getPercentValue(StatMod mod) {return null;}
1163 public String getMultValue(StatMod mod) {return null;}
1164 public Color getModColor(StatMod mod) {return null;}
1165 public String getFlatValue(StatMod mod) {
1166 return Misc.getWithDGS(mod.value) + Strings.C;
1167 }
1168 });
1169 }
1170
1171 addPostUpkeepSection(tooltip, mode);
1172
1173 boolean hasSupply = false;
1174 for (MutableCommodityQuantity curr : supply.values()) {
1175 int qty = curr.getQuantity().getModifiedInt();
1176 if (qty <= 0) continue;
1177 hasSupply = true;
1178 break;
1179 }
1180 boolean hasDemand = false;
1181 for (MutableCommodityQuantity curr : demand.values()) {
1182 int qty = curr.getQuantity().getModifiedInt();
1183 if (qty <= 0) continue;
1184 hasDemand = true;
1185 break;
1186 }
1187
1188 float maxIconsPerRow = 10f;
1189 if (hasSupply) {
1190 tooltip.addSectionHeading("Production", color, dark, Alignment.MID, opad);
1191 tooltip.beginIconGroup();
1192 tooltip.setIconSpacingMedium();
1193 float icons = 0;
1194 for (MutableCommodityQuantity curr : supply.values()) {
1195 int qty = curr.getQuantity().getModifiedInt();
1196 //if (qty <= 0) continue;
1197
1198 int normal = qty;
1199 if (normal > 0) {
1200 tooltip.addIcons(market.getCommodityData(curr.getCommodityId()), normal, IconRenderMode.NORMAL);
1201 }
1202
1203 int plus = 0;
1204 int minus = 0;
1205 for (StatMod mod : curr.getQuantity().getFlatMods().values()) {
1206 if (mod.value > 0) {
1207 plus += (int) mod.value;
1208 } else if (mod.desc != null && mod.desc.contains("shortage")) {
1209 minus += (int) Math.abs(mod.value);
1210 }
1211 }
1212 minus = Math.min(minus, plus);
1213 if (minus > 0 && mode == IndustryTooltipMode.NORMAL) {
1214 tooltip.addIcons(market.getCommodityData(curr.getCommodityId()), minus, IconRenderMode.DIM_RED);
1215 }
1216 icons += normal + Math.max(0, minus);
1217 }
1218 int rows = (int) Math.ceil(icons / maxIconsPerRow);
1219 rows = 3;
1220 tooltip.addIconGroup(32, rows, opad);
1221
1222
1223 }
1224// else if (!isFunctional() && mode == IndustryTooltipMode.NORMAL) {
1225// tooltip.addPara("Currently under construction and not producing anything or providing other benefits.", opad);
1226// }
1227
1228 addPostSupplySection(tooltip, hasSupply, mode);
1229
1230 if (hasDemand || hasPostDemandSection(hasDemand, mode)) {
1231 tooltip.addSectionHeading("Demand & effects", color, dark, Alignment.MID, opad);
1232 }
1233 if (hasDemand) {
1234 tooltip.beginIconGroup();
1235 tooltip.setIconSpacingMedium();
1236 float icons = 0;
1237 for (MutableCommodityQuantity curr : demand.values()) {
1238 int qty = curr.getQuantity().getModifiedInt();
1239 if (qty <= 0) continue;
1240
1241 CommodityOnMarketAPI com = orig.getCommodityData(curr.getCommodityId());
1242 int available = com.getAvailable();
1243
1244 int normal = Math.min(available, qty);
1245 int red = Math.max(0, qty - available);
1246
1247 if (mode != IndustryTooltipMode.NORMAL) {
1248 normal = qty;
1249 red = 0;
1250 }
1251 if (normal > 0) {
1252 tooltip.addIcons(com, normal, IconRenderMode.NORMAL);
1253 }
1254 if (red > 0) {
1255 tooltip.addIcons(com, red, IconRenderMode.DIM_RED);
1256 }
1257 icons += normal + Math.max(0, red);
1258 }
1259 int rows = (int) Math.ceil(icons / maxIconsPerRow);
1260 rows = 3;
1261 rows = 1;
1262 tooltip.addIconGroup(32, rows, opad);
1263 }
1264
1265 addPostDemandSection(tooltip, hasDemand, mode);
1266
1267 if (!needToAddIndustry) {
1268 //addAICoreSection(tooltip, AICoreDescriptionMode.TOOLTIP);
1269 addInstalledItemsSection(mode, tooltip, expanded);
1270 addImprovedSection(mode, tooltip, expanded);
1271
1272 ListenerUtil.addToIndustryTooltip(this, mode, tooltip, getTooltipWidth(), expanded);
1273 }
1274
1275 tooltip.addPara("*Shown production and demand values are already adjusted based on current market size and local conditions.", gray, opad);
1276 }
1277
1278 if (needToAddIndustry) {
1279 unapply();
1280 market.getIndustries().remove(this);
1281 }
1282 market = orig;
1283 market.setRetainSuppressedConditionsSetWhenEmpty(null);
1284 if (!needToAddIndustry) {
1285 reapply();
1286 }
1287 }
1288
1289 public void addInstalledItemsSection(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded) {
1290 float opad = 10f;
1291
1292 FactionAPI faction = market.getFaction();
1293 Color color = faction.getBaseUIColor();
1294 Color dark = faction.getDarkUIColor();
1295
1296 LabelAPI heading = tooltip.addSectionHeading("Items", color, dark, Alignment.MID, opad);
1297
1298 boolean addedSomething = false;
1299 if (aiCoreId != null) {
1300 AICoreDescriptionMode aiCoreDescMode = AICoreDescriptionMode.INDUSTRY_TOOLTIP;
1301 addAICoreSection(tooltip, aiCoreId, aiCoreDescMode);
1302 addedSomething = true;
1303 }
1304 addedSomething |= addNonAICoreInstalledItems(mode, tooltip, expanded);
1305
1306 if (!addedSomething) {
1307 heading.setText("No items installed");
1308 //tooltip.addPara("None.", opad);
1309 }
1310 }
1311
1312 protected boolean addNonAICoreInstalledItems(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded) {
1313 if (special == null) return false;
1314
1315 float opad = 10f;
1316 SpecialItemSpecAPI spec = Global.getSettings().getSpecialItemSpec(special.getId());
1317
1318 TooltipMakerAPI text = tooltip.beginImageWithText(spec.getIconName(), 48);
1320 effect.addItemDescription(this, text, special, InstallableItemDescriptionMode.INDUSTRY_TOOLTIP);
1321 tooltip.addImageWithText(opad);
1322
1323 return true;
1324 }
1325
1326// public List<SpecialItemData> getVisibleInstalledItems() {
1327// return new ArrayList<SpecialItemData>();
1328// }
1329
1330 public List<SpecialItemData> getVisibleInstalledItems() {
1331 List<SpecialItemData> result = new ArrayList<SpecialItemData>();
1332 if (special != null) {
1333 result.add(special);
1334 }
1335 return result;
1336 }
1337
1338 public boolean wantsToUseSpecialItem(SpecialItemData data) {
1339 if (special != null) return false;
1340 SpecialItemSpecAPI spec = Global.getSettings().getSpecialItemSpec(data.getId());
1341// String industry = spec.getParams();
1342// //String industry = ItemEffectsRepo.ITEM_TO_INDUSTRY.get(data.getId());
1343// return getId().equals(industry);
1344 String [] industries = spec.getParams().split(",");
1345 Set<String> all = new HashSet<String>();
1346 for (String ind: industries) all.add(ind.trim());
1347 return all.contains(getId());
1348 }
1349
1350// public boolean wantsToUseSpecialItem(SpecialItemData data) {
1351// return false;
1352// }
1353
1354
1355 public void addAICoreSection(TooltipMakerAPI tooltip, AICoreDescriptionMode mode) {
1356 addAICoreSection(tooltip, aiCoreId, mode);
1357 }
1358
1359 public void addAICoreSection(TooltipMakerAPI tooltip, String coreId, AICoreDescriptionMode mode) {
1360 float opad = 10f;
1361
1362 FactionAPI faction = market.getFaction();
1363 Color color = faction.getBaseUIColor();
1364 Color dark = faction.getDarkUIColor();
1365
1366// if (mode == AICoreDescriptionMode.TOOLTIP) {
1367// tooltip.addSectionHeading("AI Core", color, dark, Alignment.MID, opad);
1368// }
1369
1370// if (mode == AICoreDescriptionMode.TOOLTIP || mode == AICoreDescriptionMode.MANAGE_CORE_TOOLTIP) {
1371 if (mode == AICoreDescriptionMode.MANAGE_CORE_TOOLTIP) {
1372 if (coreId == null) {
1373 tooltip.addPara("No AI core currently assigned. Click to assign an AI core from your cargo.", opad);
1374 return;
1375 }
1376 }
1377
1378 boolean alpha = coreId.equals(Commodities.ALPHA_CORE);
1379 boolean beta = coreId.equals(Commodities.BETA_CORE);
1380 boolean gamma = coreId.equals(Commodities.GAMMA_CORE);
1381
1382 if (alpha) {
1383 addAlphaCoreDescription(tooltip, mode);
1384 } else if (beta) {
1385 addBetaCoreDescription(tooltip, mode);
1386 } else if (gamma) {
1387 addGammaCoreDescription(tooltip, mode);
1388 } else {
1389 addUnknownCoreDescription(coreId, tooltip, mode);
1390 }
1391 }
1392
1393 protected void addAlphaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode) {
1394 float opad = 10f;
1395 Color highlight = Misc.getHighlightColor();
1396
1397 String pre = "Alpha-level AI core currently assigned. ";
1398 if (mode == AICoreDescriptionMode.MANAGE_CORE_DIALOG_LIST || mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP) {
1399 pre = "Alpha-level AI core. ";
1400 }
1401 if (mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP || mode == AICoreDescriptionMode.MANAGE_CORE_TOOLTIP) {
1402 CommoditySpecAPI coreSpec = Global.getSettings().getCommoditySpec(aiCoreId);
1403 TooltipMakerAPI text = tooltip.beginImageWithText(coreSpec.getIconName(), 48);
1404 text.addPara(pre + "Reduces upkeep cost by %s. Reduces demand by %s unit. " +
1405 "Increases production by %s unit.", 0f, highlight,
1406 "" + (int)((1f - UPKEEP_MULT) * 100f) + "%", "" + DEMAND_REDUCTION,
1407 "" + SUPPLY_BONUS);
1408 tooltip.addImageWithText(opad);
1409 return;
1410 }
1411
1412 tooltip.addPara(pre + "Reduces upkeep cost by %s. Reduces demand by %s unit. " +
1413 "Increases production by %s unit.", opad, highlight,
1414 "" + (int)((1f - UPKEEP_MULT) * 100f) + "%", "" + DEMAND_REDUCTION,
1415 "" + SUPPLY_BONUS);
1416 }
1417
1418 protected void addBetaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode) {
1419 float opad = 10f;
1420 Color highlight = Misc.getHighlightColor();
1421
1422 String pre = "Beta-level AI core currently assigned. ";
1423 if (mode == AICoreDescriptionMode.MANAGE_CORE_DIALOG_LIST || mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP) {
1424 pre = "Beta-level AI core. ";
1425 }
1426 if (mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP || mode == AICoreDescriptionMode.MANAGE_CORE_TOOLTIP) {
1427 CommoditySpecAPI coreSpec = Global.getSettings().getCommoditySpec(aiCoreId);
1428 TooltipMakerAPI text = tooltip.beginImageWithText(coreSpec.getIconName(), 48);
1429 text.addPara(pre + "Reduces upkeep cost by %s. Reduces demand by %s unit.", opad, highlight,
1430 "" + (int)((1f - UPKEEP_MULT) * 100f) + "%", "" + DEMAND_REDUCTION);
1431 tooltip.addImageWithText(opad);
1432 return;
1433 }
1434
1435 tooltip.addPara(pre + "Reduces upkeep cost by %s. Reduces demand by %s unit.", opad, highlight,
1436 "" + (int)((1f - UPKEEP_MULT) * 100f) + "%", "" + DEMAND_REDUCTION);
1437 }
1438 protected void addGammaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode) {
1439 float opad = 10f;
1440 Color highlight = Misc.getHighlightColor();
1441
1442 String pre = "Gamma-level AI core currently assigned. ";
1443 if (mode == AICoreDescriptionMode.MANAGE_CORE_DIALOG_LIST || mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP) {
1444 pre = "Gamma-level AI core. ";
1445 }
1446 if (mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP || mode == AICoreDescriptionMode.MANAGE_CORE_TOOLTIP) {
1447 CommoditySpecAPI coreSpec = Global.getSettings().getCommoditySpec(aiCoreId);
1448 TooltipMakerAPI text = tooltip.beginImageWithText(coreSpec.getIconName(), 48);
1449// text.addPara(pre + "Reduces upkeep cost by %s.", opad, highlight,
1450// "" + (int)((1f - UPKEEP_MULT) * 100f) + "%");
1451// tooltip.addImageWithText(opad);
1452 text.addPara(pre + "Reduces demand by %s unit.", opad, highlight,
1453 "" + DEMAND_REDUCTION);
1454 tooltip.addImageWithText(opad);
1455 return;
1456 }
1457
1458// tooltip.addPara(pre + "Reduces upkeep cost by %s.", opad, highlight,
1459// "" + (int)((1f - UPKEEP_MULT) * 100f) + "%");
1460 tooltip.addPara(pre + "Reduces demand by %s unit.", opad, highlight,
1461 "" + DEMAND_REDUCTION);
1462 }
1463
1464 protected void addUnknownCoreDescription(String coreId, TooltipMakerAPI tooltip, AICoreDescriptionMode mode) {
1465
1466 CommoditySpecAPI core = Global.getSettings().getCommoditySpec(coreId);
1467 if (core == null) return;
1468
1469 float opad = 10f;
1470 Color highlight = Misc.getHighlightColor();
1471
1472 String pre = core.getName() + " currently assigned. ";
1473 if (mode == AICoreDescriptionMode.MANAGE_CORE_DIALOG_LIST || mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP) {
1474 pre = core.getName() + ". ";
1475 }
1476
1477 if (mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP || mode == AICoreDescriptionMode.MANAGE_CORE_TOOLTIP) {
1478 TooltipMakerAPI text = tooltip.beginImageWithText(core.getIconName(), 48);
1479 text.addPara(pre + "No effect.", opad);
1480 tooltip.addImageWithText(opad);
1481 return;
1482 }
1483
1484 tooltip.addPara(pre + "No effect.", opad);
1485 }
1486
1487
1488 protected void addPostSupplySection(TooltipMakerAPI tooltip, boolean hasSupply, IndustryTooltipMode mode) {
1489
1490 }
1491 protected void addPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode) {
1492
1493 }
1494 protected void addRightAfterDescriptionSection(TooltipMakerAPI tooltip, IndustryTooltipMode mode) {
1495
1496 }
1497 protected void addPostDescriptionSection(TooltipMakerAPI tooltip, IndustryTooltipMode mode) {
1498
1499 }
1500 protected void addPostUpkeepSection(TooltipMakerAPI tooltip, IndustryTooltipMode mode) {
1501
1502 }
1503
1504 public String getAICoreId() {
1505 return aiCoreId;
1506 }
1507
1508 public void setAICoreId(String aiCoreId) {
1509 this.aiCoreId = aiCoreId;
1510 }
1511
1513 if (aiCoreId == null || Commodities.GAMMA_CORE.equals(aiCoreId)) {
1514 getUpkeep().unmodifyMult("ind_core");
1515 return;
1516 }
1517
1518 float mult = UPKEEP_MULT;
1519 String name = "AI Core assigned";
1520 if (aiCoreId.equals(Commodities.ALPHA_CORE)) {
1521 name = "Alpha Core assigned";
1522 } else if (aiCoreId.equals(Commodities.BETA_CORE)) {
1523 name = "Beta Core assigned";
1524 } else if (aiCoreId.equals(Commodities.GAMMA_CORE)) {
1525 name = "Gamma Core assigned";
1526 }
1527
1528 getUpkeep().modifyMult("ind_core", mult, name);
1529 }
1530
1532 if (aiCoreId == null) {
1533 return;
1534 }
1535
1536 boolean alpha = aiCoreId.equals(Commodities.ALPHA_CORE);
1537 boolean beta = aiCoreId.equals(Commodities.BETA_CORE);
1538 boolean gamma = aiCoreId.equals(Commodities.GAMMA_CORE);
1539
1540 if (alpha) {
1541// supplyBonus.modifyFlat(getModId(0), SUPPLY_BONUS, "Alpha core");
1542// demandReduction.modifyFlat(getModId(0), DEMAND_REDUCTION, "Alpha core");
1544 } else if (beta) {
1545 //demandReduction.modifyFlat(getModId(0), DEMAND_REDUCTION, "Beta core");
1547 } else if (gamma) {
1548 //demandReduction = DEMAND_REDUCTION;
1549 //demandReduction.modifyFlat(getModId(0), DEMAND_REDUCTION, "Gamma core");
1551 }
1552 }
1553
1555 supplyBonus.modifyFlat(getModId(0), SUPPLY_BONUS, "Alpha core");
1556 demandReduction.modifyFlat(getModId(0), DEMAND_REDUCTION, "Alpha core");
1557 }
1558
1560 demandReduction.modifyFlat(getModId(0), DEMAND_REDUCTION, "Beta core");
1561 }
1562
1564 demandReduction.modifyFlat(getModId(0), DEMAND_REDUCTION, "Gamma core");
1565 }
1566
1568
1569// if (this instanceof Mining && market.getName().equals("Louise")) {
1570// System.out.println("efwefwe");
1571// }
1572// supplyBonus = 0;
1573// demandReduction = 0;
1574 supplyBonus.unmodify();
1575 demandReduction.unmodify();
1576
1578
1580
1581// supplyBonus += market.getAdmin().getStats().getDynamic().getValue(Stats.SUPPLY_BONUS_MOD, 0);
1582// demandReduction += market.getAdmin().getStats().getDynamic().getValue(Stats.DEMAND_REDUCTION_MOD, 0);
1583 supplyBonus.modifyFlat(getModId(1), market.getAdmin().getStats().getDynamic().getValue(Stats.SUPPLY_BONUS_MOD, 0), "Administrator");
1584 demandReduction.modifyFlat(getModId(1), market.getAdmin().getStats().getDynamic().getValue(Stats.DEMAND_REDUCTION_MOD, 0), "Administrator");
1585
1586 if (supplyBonusFromOther != null) {
1588 }
1589 if (demandReductionFromOther != null) {
1591 }
1592
1593// if (supplyBonusFromOther != null) {
1594// supplyBonusFromOther.unmodify();
1595// }
1596// if (demandReductionFromOther != null) {
1597// demandReductionFromOther.unmodify();
1598// }
1599
1600 }
1601
1602
1603 public boolean showShutDown() {
1604 return true;
1605 }
1606 public boolean canShutDown() {
1607 return true;
1608 }
1609 public String getCanNotShutDownReason() {
1610 return null;
1611 }
1612 public boolean canUpgrade() {
1613 return true;
1614 }
1615 public boolean canDowngrade() {
1616 return true;
1617 }
1618
1619 protected String getDescriptionOverride() {
1620 return null;
1621 }
1622
1623 public String getNameForModifier() {
1624 return Misc.ucFirst(getCurrentName().toLowerCase());
1625 }
1626
1627 public boolean isDemandLegal(CommodityOnMarketAPI com) {
1628 return !com.isIllegal();
1629 }
1630
1631 public boolean isSupplyLegal(CommodityOnMarketAPI com) {
1632 return !com.isIllegal();
1633 }
1634
1635 protected boolean isAICoreId(String str) {
1636 Set<String> cores = new HashSet<String>();
1637 cores.add(Commodities.ALPHA_CORE);
1638 cores.add(Commodities.BETA_CORE);
1639 cores.add(Commodities.GAMMA_CORE);
1640 return cores.contains(str);
1641 }
1642
1643 public void initWithParams(List<String> params) {
1644 for (String str : params) {
1645 if (isAICoreId(str)) {
1646 setAICoreId(str);
1647 break;
1648 }
1649 }
1650
1651 for (String str : params) {
1652// if (Items.PRISTINE_NANOFORGE.equals(str)) {
1653// System.out.println("wefwefew");
1654// }
1655 SpecialItemSpecAPI spec = Global.getSettings().getSpecialItemSpec(str);
1656 if (spec == null) continue;
1657
1658 String [] industries = spec.getParams().split(",");
1659 Set<String> all = new HashSet<String>();
1660 for (String ind : industries) all.add(ind.trim());
1661 if (all.contains(getId())) {
1662 setSpecialItem(new SpecialItemData(str, null));
1663 }
1664 }
1665 }
1666
1667 protected boolean hasPostDemandSection(boolean hasDemand, IndustryTooltipMode mode) {
1668 return false;
1669 }
1670
1671
1672 protected int getBaseStabilityMod() {
1673 return 0;
1674 }
1675
1677 int stabilityMod = getBaseStabilityMod();
1678 int stabilityPenalty = getStabilityPenalty();
1679 if (stabilityPenalty > stabilityMod) {
1680 stabilityPenalty = stabilityMod;
1681 }
1682 stabilityMod -= stabilityPenalty;
1683 if (stabilityMod > 0) {
1684 market.getStability().modifyFlat(getModId(), stabilityMod, getNameForModifier());
1685 }
1686// else if (stabilityMod < 0) {
1687// String str = getDeficitText(getStabilityAffectingDeficit().one);
1688// market.getStability().modifyFlat(getModId(), stabilityMod, getNameForModifier() + " (" + str.toLowerCase() + ")");
1689// }
1690 }
1691
1693 market.getStability().unmodifyFlat(getModId());
1694 }
1695
1696 protected Pair<String, Integer> getStabilityAffectingDeficit() {
1697 return new Pair<String, Integer>(Commodities.SUPPLIES, 0);
1698 }
1699 protected int getStabilityPenalty() {
1700 float deficit = getStabilityAffectingDeficit().two;
1701 if (deficit < 0) deficit = 0;
1702 return (int) Math.round(deficit);
1703 }
1704
1705
1706 protected void addStabilityPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode) {
1707 Color h = Misc.getHighlightColor();
1708 float opad = 10f;
1709
1710 MutableStat fake = new MutableStat(0);
1711 int stabilityMod = getBaseStabilityMod();
1712 int stabilityPenalty = getStabilityPenalty();
1713
1714 if (stabilityPenalty > stabilityMod) {
1715 stabilityPenalty = stabilityMod;
1716 }
1717
1718 String str = getDeficitText(getStabilityAffectingDeficit().one);
1719 fake.modifyFlat("1", stabilityMod, getNameForModifier());
1720 if (stabilityPenalty != 0) {
1721 fake.modifyFlat("2", -stabilityPenalty, str);
1722 }
1723
1724 int total = stabilityMod - stabilityPenalty;
1725 String totalStr = "+" + total;
1726 if (total < 0) {
1727 totalStr = "" + total;
1728 h = Misc.getNegativeHighlightColor();
1729 }
1730 float pad = 3f;
1731 if (total >= 0) {
1732 tooltip.addPara("Stability bonus: %s", opad, h, totalStr);
1733 } else {
1734 tooltip.addPara("Stability penalty: %s", opad, h, totalStr);
1735 }
1736 tooltip.addStatModGrid(400, 35, opad, pad, fake, new StatModValueGetter() {
1737 public String getPercentValue(StatMod mod) {
1738 return null;
1739 }
1740 public String getMultValue(StatMod mod) {
1741 return null;
1742 }
1743 public Color getModColor(StatMod mod) {
1744 if (mod.value < 0) return Misc.getNegativeHighlightColor();
1745 return null;
1746 }
1747 public String getFlatValue(StatMod mod) {
1748 return null;
1749 }
1750 });
1751 }
1752
1753 public void setHidden(boolean hidden) {
1754 if (hidden) hiddenOverride = true;
1755 else hiddenOverride = null;
1756 }
1757
1758 protected Boolean hiddenOverride = null;
1759 public boolean isHidden() {
1760 if (hiddenOverride != null) return hiddenOverride;
1761 return false;
1762 }
1763
1764 protected transient String dKey = null;
1765 public String getDisruptedKey() {
1766 if (dKey != null) return dKey;
1767 dKey = "$core_disrupted_" + getClass().getSimpleName();
1768 return dKey;
1769 }
1770
1771 public void setDisrupted(float days) {
1772 setDisrupted(days, false);
1773 }
1774 public void setDisrupted(float days, boolean useMax) {
1775 if (!canBeDisrupted()) return;
1776
1777 boolean was = isDisrupted();
1778 String key = getDisruptedKey();
1779
1780 MemoryAPI memory = market.getMemoryWithoutUpdate();
1781 float dur = days;
1782 if (useMax) {
1783 dur = Math.max(memory.getExpire(key), dur);
1784 }
1785
1786 if (dur <= 0) {
1787 memory.unset(key);
1788 } else {
1789 memory.set(key, true, dur);
1790 }
1791
1792 if (!was) {
1794 }
1795 }
1796
1797 public float getDisruptedDays() {
1798 String key = getDisruptedKey();
1799 float dur = market.getMemoryWithoutUpdate().getExpire(key);
1800 if (dur < 0) dur = 0;
1801 return dur;
1802 }
1803
1804 public boolean canBeDisrupted() {
1805 return true;
1806 }
1807
1808 public boolean isDisrupted() {
1809 String key = getDisruptedKey();
1810 return market.getMemoryWithoutUpdate().is(key, true);
1811 }
1812
1813 public float getPatherInterest() {
1814 float interest = 0;
1815 if (Commodities.ALPHA_CORE.equals(aiCoreId)) {
1816 interest += 4f;
1817 } else if (Commodities.BETA_CORE.equals(aiCoreId)) {
1818 interest += 2f;
1819 } else if (Commodities.GAMMA_CORE.equals(aiCoreId)) {
1820 interest += 1f;
1821 }
1822
1823 if (special != null) {
1824 SpecialItemSpecAPI spec = Global.getSettings().getSpecialItemSpec(special.getId());
1825 if (spec != null) {
1826 if (spec.hasTag(Items.TAG_PATHER1)) interest += 1;
1827 else if (spec.hasTag(Items.TAG_PATHER2)) interest += 2;
1828 else if (spec.hasTag(Items.TAG_PATHER4)) interest += 4;
1829 else if (spec.hasTag(Items.TAG_PATHER6)) interest += 6;
1830 else if (spec.hasTag(Items.TAG_PATHER8)) interest += 8;
1831 else if (spec.hasTag(Items.TAG_PATHER10)) interest += 10;
1832 }
1833 }
1834
1835 return interest;
1836 }
1837
1838 public CargoAPI generateCargoForGatheringPoint(Random random) {
1839 return null;
1840 }
1841
1843 return getCurrentName();
1844 }
1845
1846
1847 protected SpecialItemData special = null;
1848 public SpecialItemData getSpecialItem() {
1849 return special;
1850 }
1851
1852 public void setSpecialItem(SpecialItemData special) {
1853 //if (special == null && this.special != null) {
1854 if (this.special != null) {
1855 InstallableItemEffect effect = ItemEffectsRepo.ITEM_EFFECTS.get(this.special.getId());
1856 if (effect != null) {
1857 effect.unapply(this);
1858 }
1859 }
1860 this.special = special;
1861 }
1862
1863 protected float getDeficitMult(String ... commodities) {
1864 float deficit = getMaxDeficit(commodities).two;
1865 float demand = 0f;
1866
1867 for (String id : commodities) {
1868 demand = Math.max(demand, getDemand(id).getQuantity().getModifiedInt());
1869 }
1870
1871 if (deficit < 0) deficit = 0f;
1872 if (demand < 1) {
1873 demand = 1;
1874 deficit = 0f;
1875 }
1876
1877 float mult = (demand - deficit) / demand;
1878 if (mult < 0) mult = 0;
1879 if (mult > 1) mult = 1;
1880 return mult;
1881 }
1882
1883
1884 protected void addGroundDefensesImpactSection(TooltipMakerAPI tooltip, float bonus, String ...commodities) {
1885 Color h = Misc.getHighlightColor();
1886 float opad = 10f;
1887
1888 MutableStat fake = new MutableStat(1);
1889
1890 fake.modifyFlat("1", bonus, getNameForModifier());
1891
1892 if (commodities != null) {
1893 float mult = getDeficitMult(commodities);
1894 //mult = 0.89f;
1895 if (mult != 1) {
1896 String com = getMaxDeficit(commodities).one;
1897 fake.modifyFlat("2", -(1f - mult) * bonus, getDeficitText(com));
1898 }
1899 }
1900
1901 float total = Misc.getRoundedValueFloat(fake.getModifiedValue());
1902 String totalStr = Strings.X + total;
1903 if (total < 1f) {
1904 h = Misc.getNegativeHighlightColor();
1905 }
1906 float pad = 3f;
1907 tooltip.addPara("Ground defense strength: %s", opad, h, totalStr);
1908 tooltip.addStatModGrid(400, 35, opad, pad, fake, new StatModValueGetter() {
1909 public String getPercentValue(StatMod mod) {
1910 return null;
1911 }
1912 public String getMultValue(StatMod mod) {
1913 return null;
1914 }
1915 public Color getModColor(StatMod mod) {
1916 if (mod.value < 0) return Misc.getNegativeHighlightColor();
1917 return null;
1918 }
1919 public String getFlatValue(StatMod mod) {
1920 String r = Misc.getRoundedValue(mod.value);
1921 if (mod.value >= 0) return "+" + r;
1922 return r;
1923 }
1924 });
1925 }
1926
1927
1928 public boolean isIndustry() {
1929 return getSpec().hasTag(Industries.TAG_INDUSTRY);
1930 }
1931
1932 public boolean isStructure() {
1933 return getSpec().hasTag(Industries.TAG_STRUCTURE);
1934 }
1935 public boolean isOther() {
1936 return !isIndustry() && !isStructure();
1937 }
1938
1939 public void notifyColonyRenamed() {
1940
1941 }
1942
1943 public boolean canImprove() {
1945 }
1946
1947 public float getImproveBonusXP() {
1948 return 0;
1949 }
1950
1951 public String getImproveMenuText() {
1952 return "Make improvements...";
1953 }
1954
1956 int base = Global.getSettings().getInt("industryImproveBase");
1957 return base * (int) Math.round(Math.pow(2, Misc.getNumImprovedIndustries(market)));
1958
1959 //return 1 + Misc.getNumImprovedIndustries(market);
1960 }
1961
1962// private transient String iKey = null;
1963// public String getImprovedKey() {
1964// if (iKey != null) return iKey;
1965// iKey = "$core_improved_" + getClass().getSimpleName();
1966// return iKey;
1967// }
1968
1969 public boolean isImproved() {
1970 return improved != null && improved;
1971 }
1972
1973 public void setImproved(boolean improved) {
1974 if (!improved) {
1975 this.improved = null;
1976 } else {
1977 this.improved = improved;
1978 }
1979 }
1980
1981 protected void applyImproveModifiers() {
1982
1983 }
1984
1985 public void addImproveDesc(TooltipMakerAPI info, ImprovementDescriptionMode mode) {
1986 float initPad = 0f;
1987 float opad = 10f;
1988 boolean addedSomething = false;
1990 String unit = "unit";
1991 if (getImproveProductionBonus() != 1) {
1992 unit = "units";
1993 }
1994 if (mode == ImprovementDescriptionMode.INDUSTRY_TOOLTIP) {
1995 info.addPara("Production increased by %s " + unit + ".", initPad, Misc.getHighlightColor(),
1997 } else {
1998 info.addPara("Increases production by %s " + unit + ".", initPad, Misc.getHighlightColor(),
2000
2001 }
2002 initPad = opad;
2003 addedSomething = true;
2004 }
2005
2006 if (mode != ImprovementDescriptionMode.INDUSTRY_TOOLTIP) {
2007 // info.addPara("Each improved industry at a colony raises the cost to improve " +
2008 // "another industry by one " + Misc.STORY + " point.", initPad,
2009 // Misc.getStoryOptionColor(), Misc.STORY + " point");
2010 // info.addPara("Each improved industry at a colony doubles the number of " +
2011 // "" + Misc.STORY + " points required to improve an additional industry.", initPad,
2012 // Misc.getStoryOptionColor(), Misc.STORY + " points");
2013 // info.addPara("Each improved industry or structure at a colony doubles the number of " +
2014 // "" + Misc.STORY + " points required to improve an additional industry or structure.", initPad,
2015 // Misc.getStoryOptionColor(), Misc.STORY + " points");
2016 info.addPara("Each improvement made at a colony doubles the number of " +
2017 "" + Misc.STORY + " points required to make an additional improvement.", initPad,
2018 Misc.getStoryOptionColor(), Misc.STORY + " points");
2019 addedSomething = true;
2020 }
2021 if (!addedSomething) {
2022 info.addSpacer(-opad);
2023 }
2024 }
2025
2026 public String getImproveDialogTitle() {
2027 return "Improving " + getSpec().getName();
2028 }
2029
2030 public String getImproveSoundId() {
2031 return Sounds.STORY_POINT_SPEND_INDUSTRY;
2032 }
2033
2035 return false;
2036 }
2037
2040 }
2041
2043 return "Improvements";
2044 }
2045
2047 if (!canImproveToIncreaseProduction()) return;
2048 if (!isImproved()) return;
2049
2050 int bonus = getImproveProductionBonus();
2051 if (bonus <= 0) return;
2052
2053 supplyBonus.modifyFlat(getModId(3), bonus, getImprovementsDescForModifiers());
2054 }
2055
2056 public void addImprovedSection(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded) {
2057
2058 if (!isImproved()) return;
2059
2060 float opad = 10f;
2061
2062
2063 tooltip.addSectionHeading("Improvements made", Misc.getStoryOptionColor(),
2064 Misc.getStoryDarkColor(), Alignment.MID, opad);
2065
2066 tooltip.addSpacer(opad);
2067 addImproveDesc(tooltip, ImprovementDescriptionMode.INDUSTRY_TOOLTIP);
2068
2069// String noun = "industry";
2070// if (isStructure()) noun = "structure";
2071// tooltip.addPara("You've made improvements to this " + noun + ".",
2072// Misc.getStoryOptionColor(), opad);
2073
2074 }
2075
2076
2077 public RaidDangerLevel adjustCommodityDangerLevel(String commodityId, RaidDangerLevel level) {
2078 return level;
2079 }
2080
2081 public RaidDangerLevel adjustItemDangerLevel(String itemId, String data, RaidDangerLevel level) {
2082 return level;
2083 }
2084
2085 public int adjustMarineTokensToRaidItem(String itemId, String data, int marineTokens) {
2086 return marineTokens;
2087 }
2088
2089
2090 public boolean canInstallAICores() {
2091 return true;
2092 }
2093
2094// public List<InstallableIndustryItemPlugin> getInstallableItems() {
2095// return new ArrayList<InstallableIndustryItemPlugin>();
2096//}
2097
2098 protected transient Boolean hasInstallableItems = null;
2099 public List<InstallableIndustryItemPlugin> getInstallableItems() {
2100 boolean found = false;
2101 if (hasInstallableItems != null) {
2102 found = hasInstallableItems;
2103 } else {
2104 OUTER: for (SpecialItemSpecAPI spec : Global.getSettings().getAllSpecialItemSpecs()) {
2105 if (spec.getParams() == null || spec.getParams().isEmpty()) continue;
2106 if (spec.getNewPluginInstance(null) instanceof GenericSpecialItemPlugin) {
2107 for (String id : spec.getParams().split(",")) {
2108 id = id.trim();
2109 if (id.equals(getId())) {
2110 found = true;
2111 break OUTER;
2112 }
2113 }
2114 }
2115 }
2116 hasInstallableItems = found;
2117 }
2118 ArrayList<InstallableIndustryItemPlugin> list = new ArrayList<InstallableIndustryItemPlugin>();
2119 if (found) {
2120 list.add(new GenericInstallableItemPlugin(this));
2121 }
2122 return list;
2123 }
2124
2125 public float getBuildProgress() {
2126 return buildProgress;
2127 }
2128
2129 public void setBuildProgress(float buildProgress) {
2130 this.buildProgress = buildProgress;
2131 }
2132
2133
2134
2135
2136}
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
void addImproveDesc(TooltipMakerAPI info, ImprovementDescriptionMode mode)
List< Pair< String, Integer > > getAllDeficit(String ... commodityIds)
List< InstallableIndustryItemPlugin > getInstallableItems()
RaidDangerLevel adjustCommodityDangerLevel(String commodityId, RaidDangerLevel level)
void addInstalledItemsSection(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded)
void supply(String modId, String commodityId, int quantity, String desc)
Map< String, MutableCommodityQuantity > supply
void demand(int index, String commodityId, int quantity, String desc)
void addRightAfterDescriptionSection(TooltipMakerAPI tooltip, IndustryTooltipMode mode)
void supply(String commodityId, int quantity, String desc)
void createTooltip(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded)
void addStabilityPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode)
void addAICoreSection(TooltipMakerAPI tooltip, String coreId, AICoreDescriptionMode mode)
void addImprovedSection(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded)
int adjustMarineTokensToRaidItem(String itemId, String data, int marineTokens)
boolean hasPostDemandSection(boolean hasDemand, IndustryTooltipMode mode)
void addAlphaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode)
void supply(int index, String commodityId, int quantity, String desc)
void addPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode)
void addUnknownCoreDescription(String coreId, TooltipMakerAPI tooltip, AICoreDescriptionMode mode)
boolean addNonAICoreInstalledItems(IndustryTooltipMode mode, TooltipMakerAPI tooltip, boolean expanded)
void addAICoreSection(TooltipMakerAPI tooltip, AICoreDescriptionMode mode)
void addPostDescriptionSection(TooltipMakerAPI tooltip, IndustryTooltipMode mode)
CargoAPI getCargoForInteractionMode(MarketInteractionMode mode)
void demand(String modId, String commodityId, int quantity, String desc)
void addGammaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode)
void addGroundDefensesImpactSection(TooltipMakerAPI tooltip, float bonus, String ...commodities)
void addPostUpkeepSection(TooltipMakerAPI tooltip, IndustryTooltipMode mode)
Map< String, MutableCommodityQuantity > demand
void notifyBeingRemoved(MarketInteractionMode mode, boolean forUpgrade)
void addPostSupplySection(TooltipMakerAPI tooltip, boolean hasSupply, IndustryTooltipMode mode)
void demand(String commodityId, int quantity, String desc)
RaidDangerLevel adjustItemDangerLevel(String itemId, String data, RaidDangerLevel level)
Pair< String, Integer > getMaxDeficit(String ... commodityIds)
void applyDeficitToProduction(int index, Pair< String, Integer > deficit, String ... commodities)
void addBetaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode)
static Map< String, InstallableItemEffect > ITEM_EFFECTS
SpecialItemSpecAPI getSpecialItemSpec(String itemId)
IndustrySpecAPI getIndustrySpec(String industryId)
CommoditySpecAPI getCommoditySpec(String commodityId)
List< SpecialItemSpecAPI > getAllSpecialItemSpecs()
void addItemDescription(Industry industry, TooltipMakerAPI text, SpecialItemData data, InstallableItemDescriptionMode mode)