Starsector API
Loading...
Searching...
No Matches
MilitaryBase.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.Random;
5
6import org.lwjgl.util.vector.Vector2f;
7
8import com.fs.starfarer.api.Global;
9import com.fs.starfarer.api.campaign.BattleAPI;
10import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
11import com.fs.starfarer.api.campaign.CampaignFleetAPI;
12import com.fs.starfarer.api.campaign.PlanetAPI;
13import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
14import com.fs.starfarer.api.campaign.econ.CommoditySpecAPI;
15import com.fs.starfarer.api.campaign.econ.Industry;
16import com.fs.starfarer.api.campaign.econ.MarketAPI;
17import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
18import com.fs.starfarer.api.campaign.rules.MemoryAPI;
19import com.fs.starfarer.api.impl.campaign.DebugFlags;
20import com.fs.starfarer.api.impl.campaign.fleets.FleetFactory.PatrolType;
21import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
22import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
23import com.fs.starfarer.api.impl.campaign.fleets.PatrolAssignmentAIV4;
24import com.fs.starfarer.api.impl.campaign.fleets.RouteManager;
25import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.OptionalFleetData;
26import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
27import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteFleetSpawner;
28import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteSegment;
29import com.fs.starfarer.api.impl.campaign.ids.Commodities;
30import com.fs.starfarer.api.impl.campaign.ids.Factions;
31import com.fs.starfarer.api.impl.campaign.ids.Industries;
32import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
33import com.fs.starfarer.api.impl.campaign.ids.Ranks;
34import com.fs.starfarer.api.impl.campaign.ids.Stats;
35import com.fs.starfarer.api.impl.campaign.ids.Strings;
36import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.RaidDangerLevel;
37import com.fs.starfarer.api.ui.TooltipMakerAPI;
38import com.fs.starfarer.api.util.IntervalUtil;
39import com.fs.starfarer.api.util.Misc;
40import com.fs.starfarer.api.util.Pair;
41import com.fs.starfarer.api.util.WeightedRandomPicker;
42
43
44
45public class MilitaryBase extends BaseIndustry implements RouteFleetSpawner, FleetEventListener {
46
47 public static float OFFICER_PROB_MOD_PATROL_HQ = 0.1f;
48 public static float OFFICER_PROB_MOD_MILITARY_BASE = 0.2f;
49 public static float OFFICER_PROB_MOD_HIGH_COMMAND = 0.3f;
50
51
52 public static float DEFENSE_BONUS_PATROL = 0.1f;
53 public static float DEFENSE_BONUS_MILITARY = 0.2f;
54 public static float DEFENSE_BONUS_COMMAND = 0.3f;
55
56 public static int IMPROVE_NUM_PATROLS_BONUS = 1;
57
58 public void apply() {
59
60 int size = market.getSize();
61
62 boolean patrol = getSpec().hasTag(Industries.TAG_PATROL);
63 boolean militaryBase = getSpec().hasTag(Industries.TAG_MILITARY);
64 boolean command = getSpec().hasTag(Industries.TAG_COMMAND);
65
66 super.apply(!patrol);
67 if (patrol) {
69 }
70
71 int extraDemand = 0;
72
73 int light = 1;
74 int medium = 0;
75 int heavy = 0;
76
77 if (patrol) {
78 extraDemand = 0;
79 } else if (militaryBase) {
80 extraDemand = 2;
81 } else if (command) {
82 extraDemand = 3;
83 }
84
85 if (patrol) {
86 light = 2;
87 medium = 0;
88 heavy = 0;
89 } else {
90 if (size <= 3) {
91 light = 2;
92 medium = 0;
93 heavy = 0;
94 } else if (size == 4) {
95 light = 2;
96 medium = 0;
97 heavy = 0;
98 } else if (size == 5) {
99 light = 2;
100 medium = 1;
101 heavy = 0;
102 } else if (size == 6) {
103 light = 3;
104 medium = 1;
105 heavy = 0;
106 } else if (size == 7) {
107 light = 3;
108 medium = 2;
109 heavy = 0;
110 } else if (size == 8) {
111 light = 3;
112 medium = 3;
113 heavy = 0;
114 } else if (size >= 9) {
115 light = 4;
116 medium = 3;
117 heavy = 0;
118 }
119 }
120
121 if (militaryBase || command) {
122 //light++;
123 medium = Math.max(medium + 1, size / 2 - 1);
124 heavy = Math.max(heavy, medium - 1);
125 }
126
127 if (command) {
128 medium++;
129 heavy++;
130 }
131
132// if (market.getId().equals("jangala")) {
133// System.out.println("wefwefwe");
134// }
135
136// light += 5;
137// medium += 3;
138// heavy += 2;
139
140// float spawnRateMultStability = getStabilitySpawnRateMult();
141// if (spawnRateMultStability != 1) {
142// market.getStats().getDynamic().getStat(Stats.COMBAT_FLEET_SPAWN_RATE_MULT).modifyMult(getModId(), spawnRateMultStability);
143// }
144
145
146 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_LIGHT_MOD).modifyFlat(getModId(), light);
147 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).modifyFlat(getModId(), medium);
148 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).modifyFlat(getModId(), heavy);
149
150
151 demand(Commodities.SUPPLIES, size - 1 + extraDemand);
152 demand(Commodities.FUEL, size - 1 + extraDemand);
153 demand(Commodities.SHIPS, size - 1 + extraDemand);
154
155 supply(Commodities.CREW, size);
156
157 if (!patrol) {
158 //demand(Commodities.HAND_WEAPONS, size);
159 supply(Commodities.MARINES, size);
160
161// Pair<String, Integer> deficit = getMaxDeficit(Commodities.HAND_WEAPONS);
162// applyDeficitToProduction(1, deficit, Commodities.MARINES);
163 }
164
165
167
168 float mult = getDeficitMult(Commodities.SUPPLIES);
169 String extra = "";
170 if (mult != 1) {
171 String com = getMaxDeficit(Commodities.SUPPLIES).one;
172 extra = " (" + getDeficitText(com).toLowerCase() + ")";
173 }
174 float bonus = DEFENSE_BONUS_MILITARY;
175 if (patrol) bonus = DEFENSE_BONUS_PATROL;
176 else if (command) bonus = DEFENSE_BONUS_COMMAND;
177 market.getStats().getDynamic().getMod(Stats.GROUND_DEFENSES_MOD)
178 .modifyMult(getModId(), 1f + bonus * mult, getNameForModifier() + extra);
179
180
181 MemoryAPI memory = market.getMemoryWithoutUpdate();
182 Misc.setFlagWithReason(memory, MemFlags.MARKET_PATROL, getModId(), true, -1);
183
184 if (militaryBase || command) {
185 Misc.setFlagWithReason(memory, MemFlags.MARKET_MILITARY, getModId(), true, -1);
186 }
187
188 float officerProb = OFFICER_PROB_MOD_PATROL_HQ;
189 if (militaryBase) officerProb = OFFICER_PROB_MOD_MILITARY_BASE;
190 else if (command) officerProb = OFFICER_PROB_MOD_HIGH_COMMAND;
191 market.getStats().getDynamic().getMod(Stats.OFFICER_PROB_MOD).modifyFlat(getModId(0), officerProb);
192
193
194 if (!isFunctional()) {
195 supply.clear();
196 unapply();
197 }
198
199 }
200
201 @Override
202 public void unapply() {
203 super.unapply();
204
205 MemoryAPI memory = market.getMemoryWithoutUpdate();
206 Misc.setFlagWithReason(memory, MemFlags.MARKET_PATROL, getModId(), false, -1);
207 Misc.setFlagWithReason(memory, MemFlags.MARKET_MILITARY, getModId(), false, -1);
208
210
211 //market.getStats().getDynamic().getStat(Stats.COMBAT_FLEET_SPAWN_RATE_MULT).unmodifyMult(getModId());
212 //market.getStats().getDynamic().getMod(Stats.GROUND_DEFENSES_MULT).unmodifyFlat(getModId());
213
214 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_LIGHT_MOD).unmodifyFlat(getModId());
215 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).unmodifyFlat(getModId());
216 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).unmodifyFlat(getModId());
217
218 market.getStats().getDynamic().getMod(Stats.GROUND_DEFENSES_MOD).unmodifyMult(getModId());
219
220 market.getStats().getDynamic().getMod(Stats.OFFICER_PROB_MOD).unmodifyFlat(getModId(0));
221 }
222
223 protected boolean hasPostDemandSection(boolean hasDemand, IndustryTooltipMode mode) {
224 return mode != IndustryTooltipMode.NORMAL || isFunctional();
225 }
226
227 @Override
228 protected void addPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode) {
229 if (mode != IndustryTooltipMode.NORMAL || isFunctional()) {
230 addStabilityPostDemandSection(tooltip, hasDemand, mode);
231
232 boolean patrol = getSpec().hasTag(Industries.TAG_PATROL);
233 boolean command = getSpec().hasTag(Industries.TAG_COMMAND);
234 float bonus = DEFENSE_BONUS_MILITARY;
235 if (patrol) bonus = DEFENSE_BONUS_PATROL;
236 if (command) bonus = DEFENSE_BONUS_COMMAND;
237 addGroundDefensesImpactSection(tooltip, bonus, Commodities.SUPPLIES);
238 }
239 }
240
241 @Override
242 protected int getBaseStabilityMod() {
243 boolean patrol = getSpec().hasTag(Industries.TAG_PATROL);
244 boolean militaryBase = getSpec().hasTag(Industries.TAG_MILITARY);
245 boolean command = getSpec().hasTag(Industries.TAG_COMMAND);
246 int stabilityMod = 1;
247 if (patrol) {
248 stabilityMod = 1;
249 } else if (militaryBase) {
250 stabilityMod = 2;
251 } else if (command) {
252 stabilityMod = 2;
253 }
254 return stabilityMod;
255 }
256
257 public String getNameForModifier() {
258// boolean patrol = Industries.PATROLHQ.equals(getId());
259// if (patrol) return getSpec().getName();
260 if (getSpec().getName().contains("HQ")) {
261 return getSpec().getName();
262 }
263
264 return Misc.ucFirst(getSpec().getName().toLowerCase());
265 }
266
267
268// protected float getStabilitySpawnRateMult() {
269// return Math.max(0.2f, market.getStabilityValue() / 10f);
270// }
271
272 @Override
273 protected Pair<String, Integer> getStabilityAffectingDeficit() {
274 boolean patrol = getSpec().hasTag(Industries.TAG_PATROL);
275 if (patrol) {
276 return getMaxDeficit(Commodities.SUPPLIES, Commodities.FUEL, Commodities.SHIPS);
277 }
278 //return getMaxDeficit(Commodities.SUPPLIES, Commodities.FUEL, Commodities.SHIPS, Commodities.HAND_WEAPONS);
279 return getMaxDeficit(Commodities.SUPPLIES, Commodities.FUEL, Commodities.SHIPS);
280 }
281
282
283 @Override
284 public String getCurrentImage() {
285 boolean military = Industries.MILITARYBASE.equals(getId());
286 if (military) {
287 PlanetAPI planet = market.getPlanetEntity();
288 if (planet == null || planet.isGasGiant()) {
289 return Global.getSettings().getSpriteName("industry", "military_base_orbital");
290 }
291 }
292 return super.getCurrentImage();
293 }
294
295
296 public boolean isDemandLegal(CommodityOnMarketAPI com) {
297 return true;
298 }
299
300 public boolean isSupplyLegal(CommodityOnMarketAPI com) {
301 return true;
302 }
303
304 public boolean isAvailableToBuild() {
305 boolean canBuild = false;
306 for (Industry ind : market.getIndustries()) {
307 if (ind == this) continue;
308 if (!ind.isFunctional()) continue;
309 if (ind.getSpec().hasTag(Industries.TAG_SPACEPORT)) {
310 canBuild = true;
311 break;
312 }
313 }
314 return canBuild;
315 }
316
317 public String getUnavailableReason() {
318 return "Requires a functional spaceport";
319 }
320
321
322 //protected IntervalUtil tracker = new IntervalUtil(5f, 9f);
323 protected IntervalUtil tracker = new IntervalUtil(Global.getSettings().getFloat("averagePatrolSpawnInterval") * 0.7f,
324 Global.getSettings().getFloat("averagePatrolSpawnInterval") * 1.3f);
325
326 protected float returningPatrolValue = 0f;
327
328 @Override
329 protected void buildingFinished() {
330 super.buildingFinished();
331
332 tracker.forceIntervalElapsed();
333 }
334
335 @Override
336 protected void upgradeFinished(Industry previous) {
337 super.upgradeFinished(previous);
338
339 tracker.forceIntervalElapsed();
340 }
341
342 @Override
343 public void advance(float amount) {
344 super.advance(amount);
345
346 if (Global.getSector().getEconomy().isSimMode()) return;
347
348 if (!isFunctional()) return;
349
350 float days = Global.getSector().getClock().convertToDays(amount);
351
352// float stability = market.getPrevStability();
353// float spawnRate = 1f + (stability - 5) * 0.2f;
354// if (spawnRate < 0.5f) spawnRate = 0.5f;
355
356 float spawnRate = 1f;
357 float rateMult = market.getStats().getDynamic().getStat(Stats.COMBAT_FLEET_SPAWN_RATE_MULT).getModifiedValue();
358 spawnRate *= rateMult;
359
360 if (Global.getSector().isInNewGameAdvance()) {
361 spawnRate *= 3f;
362 }
363
364 float extraTime = 0f;
365 if (returningPatrolValue > 0) {
366 // apply "returned patrols" to spawn rate, at a maximum rate of 1 interval per day
367 float interval = tracker.getIntervalDuration();
368 extraTime = interval * days;
369 returningPatrolValue -= days;
371 }
372 tracker.advance(days * spawnRate + extraTime);
373
374 //DebugFlags.FAST_PATROL_SPAWN = true;
376 tracker.advance(days * spawnRate * 100f);
377 }
378
379 if (tracker.intervalElapsed()) {
380// if (market.isPlayerOwned()) {
381// System.out.println("ewfwefew");
382// }
383// if (market.getName().equals("Jangala")) {
384// System.out.println("wefwefe");
385// }
386 String sid = getRouteSourceId();
387
388 int light = getCount(PatrolType.FAST);
389 int medium = getCount(PatrolType.COMBAT);
390 int heavy = getCount(PatrolType.HEAVY);
391
392 int maxLight = getMaxPatrols(PatrolType.FAST);
393 int maxMedium = getMaxPatrols(PatrolType.COMBAT);
394 int maxHeavy = getMaxPatrols(PatrolType.HEAVY);
395
396 WeightedRandomPicker<PatrolType> picker = new WeightedRandomPicker<PatrolType>();
397 picker.add(PatrolType.HEAVY, maxHeavy - heavy);
398 picker.add(PatrolType.COMBAT, maxMedium - medium);
399 picker.add(PatrolType.FAST, maxLight - light);
400
401 if (picker.isEmpty()) return;
402
403 PatrolType type = picker.pick();
404 PatrolFleetData custom = new PatrolFleetData(type);
405
406 OptionalFleetData extra = new OptionalFleetData(market);
407 extra.fleetType = type.getFleetType();
408
409 RouteData route = RouteManager.getInstance().addRoute(sid, market, Misc.genRandomSeed(), extra, this, custom);
410 extra.strength = (float) getPatrolCombatFP(type, route.getRandom());
411 extra.strength = Misc.getAdjustedStrength(extra.strength, market);
412
413
414 float patrolDays = 35f + (float) Math.random() * 10f;
415 route.addSegment(new RouteSegment(patrolDays, market.getPrimaryEntity()));
416 }
417 }
418
419 public static class PatrolFleetData {
420 public PatrolType type;
421 public int spawnFP;
422 //public int despawnFP;
423 public PatrolFleetData(PatrolType type) {
424 this.type = type;
425 }
426 }
427
428 public void reportAboutToBeDespawnedByRouteManager(RouteData route) {
429// if (route.getActiveFleet() == null) return;
430// PatrolFleetData custom = (PatrolFleetData) route.getCustom();
431// custom.despawnFP = route.getActiveFleet().getFleetPoints();
432 }
433
434 public boolean shouldRepeat(RouteData route) {
435// PatrolFleetData custom = (PatrolFleetData) route.getCustom();
438// return route.getActiveFleet() != null && route.getActiveFleet().getFleetPoints() >= custom.spawnFP * 0.6f;
439 return false;
440 }
441
442 public int getCount(PatrolType ... types) {
443 int count = 0;
444 for (RouteData data : RouteManager.getInstance().getRoutesForSource(getRouteSourceId())) {
445 if (data.getCustom() instanceof PatrolFleetData) {
446 PatrolFleetData custom = (PatrolFleetData) data.getCustom();
447 for (PatrolType type : types) {
448 if (type == custom.type) {
449 count++;
450 break;
451 }
452 }
453 }
454 }
455 return count;
456 }
457
458 public int getMaxPatrols(PatrolType type) {
459 if (type == PatrolType.FAST) {
460 return (int) market.getStats().getDynamic().getMod(Stats.PATROL_NUM_LIGHT_MOD).computeEffective(0);
461 }
462 if (type == PatrolType.COMBAT) {
463 return (int) market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).computeEffective(0);
464 }
465 if (type == PatrolType.HEAVY) {
466 return (int) market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).computeEffective(0);
467 }
468 return 0;
469 }
470
471 public String getRouteSourceId() {
472 return getMarket().getId() + "_" + "military";
473 }
474
475 public boolean shouldCancelRouteAfterDelayCheck(RouteData route) {
476 return false;
477 }
478
479
480 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) {
481
482 }
483
484 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) {
485 if (!isFunctional()) return;
486
487 if (reason == FleetDespawnReason.REACHED_DESTINATION) {
488 RouteData route = RouteManager.getInstance().getRoute(getRouteSourceId(), fleet);
489 if (route.getCustom() instanceof PatrolFleetData) {
490 PatrolFleetData custom = (PatrolFleetData) route.getCustom();
491 if (custom.spawnFP > 0) {
492 float fraction = fleet.getFleetPoints() / custom.spawnFP;
493 returningPatrolValue += fraction;
494 }
495 }
496 }
497 }
498
499 public static int getPatrolCombatFP(PatrolType type, Random random) {
500 float combat = 0;
501 switch (type) {
502 case FAST:
503 combat = Math.round(3f + (float) random.nextFloat() * 2f) * 5f;
504 break;
505 case COMBAT:
506 combat = Math.round(6f + (float) random.nextFloat() * 3f) * 5f;
507 break;
508 case HEAVY:
509 combat = Math.round(10f + (float) random.nextFloat() * 5f) * 5f;
510 break;
511 }
512 return (int) Math.round(combat);
513 }
514
515 public CampaignFleetAPI spawnFleet(RouteData route) {
516
517 PatrolFleetData custom = (PatrolFleetData) route.getCustom();
518 PatrolType type = custom.type;
519
520 Random random = route.getRandom();
521
522 CampaignFleetAPI fleet = createPatrol(type, market.getFactionId(), route, market, null, random);
523
524 if (fleet == null || fleet.isEmpty()) return null;
525
526 fleet.addEventListener(this);
527
528 market.getContainingLocation().addEntity(fleet);
529 fleet.setFacing((float) Math.random() * 360f);
530 // this will get overridden by the patrol assignment AI, depending on route-time elapsed etc
531 fleet.setLocation(market.getPrimaryEntity().getLocation().x, market.getPrimaryEntity().getLocation().y);
532
533 fleet.addScript(new PatrolAssignmentAIV4(fleet, route));
534
535 fleet.getMemoryWithoutUpdate().set(MemFlags.FLEET_IGNORES_OTHER_FLEETS, true, 0.3f);
536
537 //market.getContainingLocation().addEntity(fleet);
538 //fleet.setLocation(market.getPrimaryEntity().getLocation().x, market.getPrimaryEntity().getLocation().y);
539
540 if (custom.spawnFP <= 0) {
541 custom.spawnFP = fleet.getFleetPoints();
542 }
543
544 return fleet;
545 }
546
547 public static CampaignFleetAPI createPatrol(PatrolType type, String factionId, RouteData route, MarketAPI market, Vector2f locInHyper, Random random) {
548 if (random == null) random = new Random();
549
550
551 float combat = getPatrolCombatFP(type, random);
552 float tanker = 0f;
553 float freighter = 0f;
554 String fleetType = type.getFleetType();
555 switch (type) {
556 case FAST:
557 break;
558 case COMBAT:
559 tanker = Math.round((float) random.nextFloat() * 5f);
560 break;
561 case HEAVY:
562 tanker = Math.round((float) random.nextFloat() * 10f);
563 freighter = Math.round((float) random.nextFloat() * 10f);
564 break;
565 }
566
567 FleetParamsV3 params = new FleetParamsV3(
568 market,
569 locInHyper,
570 factionId,
571 route == null ? null : route.getQualityOverride(),
572 fleetType,
573 combat, // combatPts
574 freighter, // freighterPts
575 tanker, // tankerPts
576 0f, // transportPts
577 0f, // linerPts
578 0f, // utilityPts
579 0f // qualityMod
580 );
581 if (route != null) {
582 params.timestamp = route.getTimestamp();
583 }
584 params.random = random;
585 CampaignFleetAPI fleet = FleetFactoryV3.createFleet(params);
586
587 if (fleet == null || fleet.isEmpty()) return null;
588
589 if (!fleet.getFaction().getCustomBoolean(Factions.CUSTOM_PATROLS_HAVE_NO_PATROL_MEMORY_KEY)) {
590 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PATROL_FLEET, true);
591 if (type == PatrolType.FAST || type == PatrolType.COMBAT) {
592 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_CUSTOMS_INSPECTOR, true);
593 }
594 } else if (fleet.getFaction().getCustomBoolean(Factions.CUSTOM_PIRATE_BEHAVIOR)) {
595 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PIRATE, true);
596
597 // hidden pather and pirate bases
598 // make them raid so there's some consequence to just having a colony in a system with one of those
599 if (market != null && market.isHidden()) {
600 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_RAIDER, true);
601 }
602 }
603
604 String postId = Ranks.POST_PATROL_COMMANDER;
605 String rankId = Ranks.SPACE_COMMANDER;
606 switch (type) {
607 case FAST:
608 rankId = Ranks.SPACE_LIEUTENANT;
609 break;
610 case COMBAT:
611 rankId = Ranks.SPACE_COMMANDER;
612 break;
613 case HEAVY:
614 rankId = Ranks.SPACE_CAPTAIN;
615 break;
616 }
617
618 fleet.getCommander().setPostId(postId);
619 fleet.getCommander().setRankId(rankId);
620
621 return fleet;
622 }
623
624
625
626 public static float ALPHA_CORE_BONUS = 0.25f;
627 @Override
628 protected void applyAlphaCoreModifiers() {
629 market.getStats().getDynamic().getMod(Stats.COMBAT_FLEET_SIZE_MULT).modifyMult(
630 getModId(), 1f + ALPHA_CORE_BONUS, "Alpha core (" + getNameForModifier() + ")");
631 }
632
633 @Override
634 protected void applyNoAICoreModifiers() {
635 market.getStats().getDynamic().getMod(Stats.COMBAT_FLEET_SIZE_MULT).unmodifyMult(getModId());
636 }
637
638 @Override
640 demandReduction.modifyFlat(getModId(0), DEMAND_REDUCTION, "Alpha core");
641 }
642
643 protected void addAlphaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode) {
644 float opad = 10f;
645 Color highlight = Misc.getHighlightColor();
646
647 String pre = "Alpha-level AI core currently assigned. ";
648 if (mode == AICoreDescriptionMode.MANAGE_CORE_DIALOG_LIST || mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP) {
649 pre = "Alpha-level AI core. ";
650 }
651 float a = ALPHA_CORE_BONUS;
652 //String str = "" + (int)Math.round(a * 100f) + "%";
653 String str = Strings.X + (1f + a);
654
655 if (mode == AICoreDescriptionMode.INDUSTRY_TOOLTIP) {
656 CommoditySpecAPI coreSpec = Global.getSettings().getCommoditySpec(aiCoreId);
657 TooltipMakerAPI text = tooltip.beginImageWithText(coreSpec.getIconName(), 48);
658 text.addPara(pre + "Reduces upkeep cost by %s. Reduces demand by %s unit. " +
659 "Increases fleet size by %s.", 0f, highlight,
660 "" + (int)((1f - UPKEEP_MULT) * 100f) + "%", "" + DEMAND_REDUCTION,
661 str);
662 tooltip.addImageWithText(opad);
663 return;
664 }
665
666 tooltip.addPara(pre + "Reduces upkeep cost by %s. Reduces demand by %s unit. " +
667 "Increases fleet size by %s.", opad, highlight,
668 "" + (int)((1f - UPKEEP_MULT) * 100f) + "%", "" + DEMAND_REDUCTION,
669 str);
670
671 }
672
673
674 @Override
675 public boolean canImprove() {
676 return true;
677 }
678
679 protected void applyImproveModifiers() {
680
681 String key = "mil_base_improve";
682 if (isImproved()) {
683 boolean patrol = getSpec().hasTag(Industries.TAG_PATROL);
684// boolean militaryBase = getSpec().hasTag(Industries.TAG_MILITARY);
685// boolean command = getSpec().hasTag(Industries.TAG_COMMAND);
686
687 if (patrol) {
688 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).modifyFlat(key, IMPROVE_NUM_PATROLS_BONUS);
689 } else {
690 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).modifyFlat(key, IMPROVE_NUM_PATROLS_BONUS);
691 }
692 } else {
693 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).unmodifyFlat(key);
694 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).unmodifyFlat(key);
695 }
696 }
697
698 public void addImproveDesc(TooltipMakerAPI info, ImprovementDescriptionMode mode) {
699 float opad = 10f;
700 Color highlight = Misc.getHighlightColor();
701
702 String str = "" + (int) IMPROVE_NUM_PATROLS_BONUS;
703
704 boolean patrol = getSpec().hasTag(Industries.TAG_PATROL);
705 String type = "medium patrols";
706 if (!patrol) type = "heavy patrols";
707
708 if (mode == ImprovementDescriptionMode.INDUSTRY_TOOLTIP) {
709 info.addPara("Number of " + type + " launched increased by %s.", 0f, highlight, str);
710 } else {
711 info.addPara("Increases the number of " + type + " launched by %s.", 0f, highlight, str);
712 }
713
714 info.addSpacer(opad);
715 super.addImproveDesc(info, mode);
716 }
717
718
719 @Override
720 public RaidDangerLevel adjustCommodityDangerLevel(String commodityId, RaidDangerLevel level) {
721 return level.next();
722 }
723
724 @Override
725 public RaidDangerLevel adjustItemDangerLevel(String itemId, String data, RaidDangerLevel level) {
726 return level.next();
727 }
728
729
730}
731
732
733
734
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
Map< String, MutableCommodityQuantity > supply
void addStabilityPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode)
void addGroundDefensesImpactSection(TooltipMakerAPI tooltip, float bonus, String ...commodities)
Map< String, MutableCommodityQuantity > demand
Pair< String, Integer > getMaxDeficit(String ... commodityIds)
void addImproveDesc(TooltipMakerAPI info, ImprovementDescriptionMode mode)
static CampaignFleetAPI createPatrol(PatrolType type, String factionId, RouteData route, MarketAPI market, Vector2f locInHyper, Random random)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
RaidDangerLevel adjustCommodityDangerLevel(String commodityId, RaidDangerLevel level)
RaidDangerLevel adjustItemDangerLevel(String itemId, String data, RaidDangerLevel level)
boolean hasPostDemandSection(boolean hasDemand, IndustryTooltipMode mode)
void addPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode)
void addAlphaCoreDescription(TooltipMakerAPI tooltip, AICoreDescriptionMode mode)
static int getPatrolCombatFP(PatrolType type, Random random)
String getSpriteName(String category, String id)
CommoditySpecAPI getCommoditySpec(String commodityId)