1package com.fs.starfarer.api.impl.campaign.econ.impl;
3import java.util.Random;
5import com.fs.starfarer.api.Global;
6import com.fs.starfarer.api.campaign.BattleAPI;
7import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
8import com.fs.starfarer.api.campaign.CampaignFleetAPI;
9import com.fs.starfarer.api.campaign.FactionAPI.ShipPickMode;
10import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
11import com.fs.starfarer.api.campaign.econ.Industry;
12import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
13import com.fs.starfarer.api.campaign.rules.MemoryAPI;
14import com.fs.starfarer.api.fleet.FleetMemberAPI;
15import com.fs.starfarer.api.impl.campaign.econ.impl.MilitaryBase.PatrolFleetData;
16import com.fs.starfarer.api.impl.campaign.fleets.FleetFactory.PatrolType;
17import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
18import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
19import com.fs.starfarer.api.impl.campaign.fleets.PatrolAssignmentAIV4;
20import com.fs.starfarer.api.impl.campaign.fleets.RouteManager;
21import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.OptionalFleetData;
22import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
23import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteFleetSpawner;
24import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteSegment;
25import com.fs.starfarer.api.impl.campaign.ids.Commodities;
26import com.fs.starfarer.api.impl.campaign.ids.Factions;
27import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
28import com.fs.starfarer.api.impl.campaign.ids.Ranks;
29import com.fs.starfarer.api.impl.campaign.ids.Stats;
30import com.fs.starfarer.api.impl.campaign.ids.Tags;
31import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD.RaidDangerLevel;
32import com.fs.starfarer.api.loading.VariantSource;
33import com.fs.starfarer.api.ui.TooltipMakerAPI;
34import com.fs.starfarer.api.util.IntervalUtil;
35import com.fs.starfarer.api.util.Misc;
36import com.fs.starfarer.api.util.Pair;
37import com.fs.starfarer.api.util.WeightedRandomPicker;
44 return !
market.getFactionId().equals(Factions.DIKTAT);
49 return super.isFunctional() &&
market.getFactionId().equals(Factions.DIKTAT);
55 int size =
market.getSize();
57 demand(Commodities.SUPPLIES, size - 1);
58 demand(Commodities.FUEL, size - 1);
59 demand(Commodities.SHIPS, size - 1);
61 supply(Commodities.CREW, size);
63 demand(Commodities.HAND_WEAPONS, size);
64 supply(Commodities.MARINES, size);
66 Pair<String, Integer> deficit =
getMaxDeficit(Commodities.HAND_WEAPONS);
71 MemoryAPI memory =
market.getMemoryWithoutUpdate();
72 Misc.setFlagWithReason(memory, MemFlags.MARKET_PATROL,
getModId(),
true, -1);
73 Misc.setFlagWithReason(memory, MemFlags.MARKET_MILITARY,
getModId(),
true, -1);
86 MemoryAPI memory =
market.getMemoryWithoutUpdate();
87 Misc.setFlagWithReason(memory, MemFlags.MARKET_PATROL,
getModId(),
false, -1);
88 Misc.setFlagWithReason(memory, MemFlags.MARKET_MILITARY,
getModId(),
false, -1);
94 return mode != IndustryTooltipMode.NORMAL ||
isFunctional();
98 protected void addPostDemandSection(TooltipMakerAPI tooltip,
boolean hasDemand, IndustryTooltipMode mode) {
99 if (mode != IndustryTooltipMode.NORMAL ||
isFunctional()) {
110 if (
getSpec().getName().contains(
"HQ")) {
113 return Misc.ucFirst(
getSpec().getName());
118 return getMaxDeficit(Commodities.SUPPLIES, Commodities.FUEL, Commodities.SHIPS, Commodities.HAND_WEAPONS);
123 return super.getCurrentImage();
142 super.buildingFinished();
144 tracker.forceIntervalElapsed();
149 super.upgradeFinished(previous);
151 tracker.forceIntervalElapsed();
156 super.advance(amount);
164 float spawnRate = 1f;
165 float rateMult =
market.getStats().getDynamic().getStat(Stats.COMBAT_FLEET_SPAWN_RATE_MULT).getModifiedValue();
166 spawnRate *= rateMult;
169 float extraTime = 0f;
172 float interval =
tracker.getIntervalDuration();
173 extraTime = interval * days;
177 tracker.advance(days * spawnRate + extraTime);
181 if (
tracker.intervalElapsed()) {
184 int light =
getCount(PatrolType.FAST);
185 int medium =
getCount(PatrolType.COMBAT);
186 int heavy =
getCount(PatrolType.HEAVY);
192 WeightedRandomPicker<PatrolType> picker =
new WeightedRandomPicker<PatrolType>();
193 picker.add(PatrolType.HEAVY, maxHeavy - heavy);
194 picker.add(PatrolType.COMBAT, maxMedium - medium);
195 picker.add(PatrolType.FAST, maxLight - light);
197 if (picker.isEmpty())
return;
199 PatrolType type = picker.pick();
200 PatrolFleetData custom =
new PatrolFleetData(type);
202 OptionalFleetData extra =
new OptionalFleetData(
market);
203 extra.fleetType = type.getFleetType();
205 RouteData route = RouteManager.getInstance().addRoute(sid,
market, Misc.genRandomSeed(), extra,
this, custom);
206 float patrolDays = 35f + (float) Math.random() * 10f;
208 route.addSegment(
new RouteSegment(patrolDays,
market.getPrimaryEntity()));
221 for (RouteData data : RouteManager.getInstance().getRoutesForSource(
getRouteSourceId())) {
222 if (data.getCustom() instanceof PatrolFleetData) {
223 PatrolFleetData custom = (PatrolFleetData) data.getCustom();
224 for (PatrolType type : types) {
225 if (type == custom.type) {
236 if (type == PatrolType.FAST) {
237 return (
int)
market.getStats().getDynamic().getMod(Stats.PATROL_NUM_LIGHT_MOD).computeEffective(0);
239 if (type == PatrolType.COMBAT) {
240 return (
int)
market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).computeEffective(0);
242 if (type == PatrolType.HEAVY) {
243 return (
int)
market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).computeEffective(0);
259 if (reason == FleetDespawnReason.REACHED_DESTINATION) {
260 RouteData route = RouteManager.getInstance().getRoute(
getRouteSourceId(), fleet);
261 if (route.getCustom() instanceof PatrolFleetData) {
262 PatrolFleetData custom = (PatrolFleetData) route.getCustom();
263 if (custom.spawnFP > 0) {
264 float fraction = fleet.getFleetPoints() / custom.spawnFP;
273 PatrolFleetData custom = (PatrolFleetData) route.getCustom();
274 PatrolType type = custom.type;
276 Random random = route.getRandom();
280 float freighter = 0f;
281 String fleetType = type.getFleetType();
284 combat = Math.round(3f + (
float) random.nextFloat() * 2f) * 5f;
287 combat = Math.round(6f + (
float) random.nextFloat() * 3f) * 5f;
288 tanker = Math.round((
float) random.nextFloat()) * 5f;
291 combat = Math.round(10f + (
float) random.nextFloat() * 5f) * 5f;
292 tanker = Math.round((
float) random.nextFloat()) * 10f;
293 freighter = Math.round((
float) random.nextFloat()) * 10f;
297 FleetParamsV3 params =
new FleetParamsV3(
300 Factions.LIONS_GUARD,
301 route.getQualityOverride(),
311 params.timestamp = route.getTimestamp();
312 params.random = random;
313 params.modeOverride = Misc.getShipPickMode(
market);
314 params.modeOverride = ShipPickMode.PRIORITY_THEN_ALL;
315 CampaignFleetAPI fleet = FleetFactoryV3.createFleet(params);
317 if (fleet ==
null || fleet.isEmpty())
return null;
319 fleet.setFaction(
market.getFactionId(),
true);
320 fleet.setNoFactionInName(
true);
322 fleet.addEventListener(
this);
327 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_PATROL_FLEET,
true);
328 fleet.getMemoryWithoutUpdate().set(MemFlags.FLEET_IGNORES_OTHER_FLEETS,
true, 0.3f);
330 if (type == PatrolType.FAST || type == PatrolType.COMBAT) {
331 fleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_CUSTOMS_INSPECTOR,
true);
334 String postId = Ranks.POST_PATROL_COMMANDER;
335 String rankId = Ranks.SPACE_COMMANDER;
338 rankId = Ranks.SPACE_LIEUTENANT;
341 rankId = Ranks.SPACE_COMMANDER;
344 rankId = Ranks.SPACE_CAPTAIN;
348 fleet.getCommander().setPostId(postId);
349 fleet.getCommander().setRankId(rankId);
351 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
352 if (member.isCapital()) {
353 member.setVariant(member.getVariant().clone(),
false,
false);
354 member.getVariant().setSource(VariantSource.REFIT);
355 member.getVariant().addTag(Tags.TAG_NO_AUTOFIT);
356 member.getVariant().addTag(Tags.VARIANT_CONSISTENT_WEAPON_DROPS);
360 market.getContainingLocation().addEntity(fleet);
361 fleet.setFacing((
float) Math.random() * 360f);
363 fleet.setLocation(
market.getPrimaryEntity().getLocation().x,
market.getPrimaryEntity().getLocation().y);
365 fleet.addScript(
new PatrolAssignmentAIV4(fleet, route));
370 if (custom.spawnFP <= 0) {
371 custom.spawnFP = fleet.getFleetPoints();
378 return getMarket().getId() +
"_" +
"lionsguard";
static SettingsAPI getSettings()
static SectorAPI getSector()
IndustrySpecAPI getSpec()
Map< String, MutableCommodityQuantity > supply
void addStabilityPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode)
void unmodifyStabilityWithBaseMod()
void modifyStabilityWithBaseMod()
Map< String, MutableCommodityQuantity > demand
Pair< String, Integer > getMaxDeficit(String ... commodityIds)
void applyDeficitToProduction(int index, Pair< String, Integer > deficit, String ... commodities)
int getBaseStabilityMod()
String getRouteSourceId()
CampaignFleetAPI spawnFleet(RouteData route)
String getNameForModifier()
boolean shouldCancelRouteAfterDelayCheck(RouteData route)
boolean shouldRepeat(RouteData route)
RaidDangerLevel adjustCommodityDangerLevel(String commodityId, RaidDangerLevel level)
void reportAboutToBeDespawnedByRouteManager(RouteData route)
RaidDangerLevel adjustItemDangerLevel(String itemId, String data, RaidDangerLevel level)
boolean isDemandLegal(CommodityOnMarketAPI com)
int getMaxPatrols(PatrolType type)
void advance(float amount)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
int getCount(PatrolType ... types)
boolean isAvailableToBuild()
Pair< String, Integer > getStabilityAffectingDeficit()
boolean isSupplyLegal(CommodityOnMarketAPI com)
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
float returningPatrolValue
void upgradeFinished(Industry previous)
boolean hasPostDemandSection(boolean hasDemand, IndustryTooltipMode mode)
boolean showWhenUnavailable()
void addPostDemandSection(TooltipMakerAPI tooltip, boolean hasDemand, IndustryTooltipMode mode)
float getFloat(String key)