1package com.fs.starfarer.api.impl.campaign.intel.bases;
4import java.util.ArrayList;
5import java.util.LinkedHashMap;
9import org.apache.log4j.Logger;
10import org.json.JSONException;
11import org.json.JSONObject;
13import com.fs.starfarer.api.EveryFrameScript;
14import com.fs.starfarer.api.Global;
15import com.fs.starfarer.api.campaign.BattleAPI;
16import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason;
17import com.fs.starfarer.api.campaign.CampaignFleetAPI;
18import com.fs.starfarer.api.campaign.FactionAPI;
19import com.fs.starfarer.api.campaign.JumpPointAPI;
20import com.fs.starfarer.api.campaign.PersonImportance;
21import com.fs.starfarer.api.campaign.ReputationActionResponsePlugin.ReputationAdjustmentResult;
22import com.fs.starfarer.api.campaign.SectorEntityToken;
23import com.fs.starfarer.api.campaign.StarSystemAPI;
24import com.fs.starfarer.api.campaign.TextPanelAPI;
25import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
26import com.fs.starfarer.api.campaign.econ.CommodityOnMarketAPI;
27import com.fs.starfarer.api.campaign.econ.EconomyAPI.EconomyUpdateListener;
28import com.fs.starfarer.api.campaign.econ.Industry;
29import com.fs.starfarer.api.campaign.econ.MarketAPI;
30import com.fs.starfarer.api.campaign.econ.MarketAPI.SurveyLevel;
31import com.fs.starfarer.api.campaign.listeners.FleetEventListener;
32import com.fs.starfarer.api.characters.PersonAPI;
33import com.fs.starfarer.api.combat.MutableStat.StatMod;
34import com.fs.starfarer.api.combat.ShipVariantAPI;
35import com.fs.starfarer.api.fleet.FleetMemberAPI;
36import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin;
37import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.CustomRepImpact;
38import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope;
39import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions;
40import com.fs.starfarer.api.impl.campaign.DebugFlags;
41import com.fs.starfarer.api.impl.campaign.Tuning;
42import com.fs.starfarer.api.impl.campaign.fleets.RouteLocationCalculator;
43import com.fs.starfarer.api.impl.campaign.ids.Conditions;
44import com.fs.starfarer.api.impl.campaign.ids.Entities;
45import com.fs.starfarer.api.impl.campaign.ids.Factions;
46import com.fs.starfarer.api.impl.campaign.ids.Industries;
47import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
48import com.fs.starfarer.api.impl.campaign.ids.Ranks;
49import com.fs.starfarer.api.impl.campaign.ids.Stats;
50import com.fs.starfarer.api.impl.campaign.ids.Submarkets;
51import com.fs.starfarer.api.impl.campaign.ids.Tags;
52import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
53import com.fs.starfarer.api.impl.campaign.intel.PersonBountyIntel.BountyResult;
54import com.fs.starfarer.api.impl.campaign.intel.PersonBountyIntel.BountyResultType;
55import com.fs.starfarer.api.impl.campaign.intel.bar.PortsideBarData;
56import com.fs.starfarer.api.impl.campaign.intel.bar.events.PirateBaseRumorBarEvent;
57import com.fs.starfarer.api.impl.campaign.intel.deciv.DecivTracker;
58import com.fs.starfarer.api.impl.campaign.intel.events.PirateBasePirateActivityCause2;
59import com.fs.starfarer.api.impl.campaign.intel.raid.PirateRaidActionStage;
60import com.fs.starfarer.api.impl.campaign.intel.raid.PirateRaidAssembleStage;
61import com.fs.starfarer.api.impl.campaign.intel.raid.RaidIntel;
62import com.fs.starfarer.api.impl.campaign.intel.raid.RaidIntel.RaidDelegate;
63import com.fs.starfarer.api.impl.campaign.intel.raid.RaidIntel.RaidStageStatus;
64import com.fs.starfarer.api.impl.campaign.intel.raid.ReturnStage;
65import com.fs.starfarer.api.impl.campaign.intel.raid.TravelStage;
66import com.fs.starfarer.api.impl.campaign.procgen.MarkovNames;
67import com.fs.starfarer.api.impl.campaign.procgen.MarkovNames.MarkovNameResult;
68import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator;
69import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.AddedEntity;
70import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.EntityLocation;
71import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator.LocationType;
72import com.fs.starfarer.api.impl.campaign.rulecmd.HA_CMD;
73import com.fs.starfarer.api.ui.Alignment;
74import com.fs.starfarer.api.ui.LabelAPI;
75import com.fs.starfarer.api.ui.SectorMapAPI;
76import com.fs.starfarer.api.ui.TooltipMakerAPI;
77import com.fs.starfarer.api.util.IntervalUtil;
78import com.fs.starfarer.api.util.Misc;
79import com.fs.starfarer.api.util.WeightedRandomPicker;
82 EconomyUpdateListener, RaidDelegate {
87 public static String
MEM_FLAG =
"$core_pirateBase";
106 public static enum PirateBaseTier {
122 public static class BaseBountyData {
123 public float bountyElapsedDays = 0f;
124 public float bountyDuration = 0;
125 public float baseBounty = 0;
126 public float repChange = 0;
127 public FactionAPI bountyFaction =
null;
176 market.getMemoryWithoutUpdate().set(MemFlags.HIDDEN_BASE_MEM_FLAG,
true);
179 market.setFactionId(Factions.PIRATES);
181 market.setSurveyLevel(SurveyLevel.FULL);
183 market.setFactionId(factionId);
184 market.addCondition(Conditions.POPULATION_3);
186 market.addIndustry(Industries.POPULATION);
187 market.addIndustry(Industries.SPACEPORT);
188 market.addIndustry(Industries.MILITARYBASE);
190 market.addSubmarket(Submarkets.SUBMARKET_OPEN);
191 market.addSubmarket(Submarkets.SUBMARKET_BLACK);
193 market.getTariff().modifyFlat(
"default_tariff",
market.getFaction().getTariffFraction());
195 LinkedHashMap<LocationType, Float> weights =
new LinkedHashMap<LocationType, Float>();
196 weights.put(LocationType.IN_ASTEROID_BELT, 10f);
197 weights.put(LocationType.IN_ASTEROID_FIELD, 10f);
198 weights.put(LocationType.IN_RING, 10f);
199 weights.put(LocationType.IN_SMALL_NEBULA, 10f);
200 weights.put(LocationType.GAS_GIANT_ORBIT, 10f);
201 weights.put(LocationType.PLANET_ORBIT, 10f);
202 WeightedRandomPicker<EntityLocation> locs = BaseThemeGenerator.getLocations(
null,
system,
null, 100f, weights);
203 EntityLocation loc = locs.pick();
210 AddedEntity added = BaseThemeGenerator.addNonSalvageEntity(
system, loc, Entities.MAKESHIFT_STATION, factionId);
212 if (added ==
null || added.entity ==
null) {
240 BaseThemeGenerator.convertOrbitWithSpin(
entity, -5f);
245 entity.setSensorProfile(1f);
246 entity.setDiscoverable(
true);
247 entity.getDetectedRangeMod().modifyFlat(
"gen", 5000f);
250 market.getMemoryWithoutUpdate().set(DecivTracker.NO_DECIV_KEY,
true);
252 market.reapplyIndustries();
259 baseCommander.setImportanceAndVoice(PersonImportance.HIGH, Misc.random);
264 log.info(String.format(
"Added pirate base in [%s], tier: %s",
system.getName(),
tier.name()));
279 PortsideBarData.getInstance().addEvent(
new PirateBaseRumorBarEvent(
this));
284 if (super.isHidden())
return true;
292 return base * (0.75f + (float) Math.random() * 0.5f);
297 case TIER_1_1MODULE: base = 100f;
break;
298 case TIER_2_1MODULE: base = 150f;
break;
299 case TIER_3_2MODULE: base = 250f;
break;
300 case TIER_4_3MODULE: base = 300f;
break;
301 case TIER_5_3MODULE: base = 450f;
break;
303 return base * (0.75f + (float) Math.random() * 0.5f);
307 if (status == RaidStageStatus.SUCCESS) {
313 float raidFP = raid.getAssembleStage().getOrigSpawnFP();
323 !Misc.getMarketsInLocation(
target, Factions.PLAYER).isEmpty()) {
327 boolean hasTargets =
false;
328 for (MarketAPI curr : Misc.getMarketsInLocation(
target)) {
335 if (!hasTargets)
return;
340 float successMult = 0.5f;
342 JumpPointAPI gather =
null;
343 List<JumpPointAPI> points =
system.getEntities(JumpPointAPI.class);
344 float min = Float.MAX_VALUE;
345 for (JumpPointAPI curr : points) {
346 float dist = Misc.getDistance(
entity.getLocation(), curr.getLocation());
354 if (gather ==
null || raidJump ==
null)
return;
356 PirateRaidAssembleStage assemble =
new PirateRaidAssembleStage(raid, gather,
this);
357 assemble.addSource(
market);
358 assemble.setSpawnFP(raidFP);
359 assemble.setAbortFP(raidFP * successMult);
360 raid.addStage(assemble);
362 TravelStage travel =
new TravelStage(raid, gather, raidJump,
false);
363 travel.setAbortFP(raidFP * successMult);
364 raid.addStage(travel);
366 PirateRaidActionStage action =
new PirateRaidActionStage(raid,
target);
367 action.setAbortFP(raidFP * successMult);
368 raid.addStage(action);
370 raid.addStage(
new ReturnStage(raid));
372 boolean shouldNotify = raid.shouldSendUpdate();
386 WeightedRandomPicker<String> stations =
new WeightedRandomPicker<String>();
390 JSONObject json =
getFactionForUIColors().getCustom().getJSONObject(Factions.CUSTOM_PIRATE_BASE_STATION_TYPES);
391 for (String key : JSONObject.getNames(json)) {
392 stations.add(key, (
float) json.optDouble(key, 0f));
394 }
catch (JSONException e) {
399 if (stations.isEmpty()) {
400 stations.add(Industries.ORBITALSTATION, 5f);
401 stations.add(Industries.ORBITALSTATION_MID, 3f);
402 stations.add(Industries.ORBITALSTATION_HIGH, 1f);
406 return stations.pick();
410 for (Industry curr :
market.getIndustries()) {
411 if (curr.getSpec().hasTag(Industries.TAG_STATION)) {
426 String currIndId =
null;
427 if (stationInd !=
null) {
428 currIndId = stationInd.getId();
429 market.removeIndustry(stationInd.getId(),
null,
false);
433 if (currIndId ==
null) {
437 if (currIndId ==
null)
return;
439 market.addIndustry(currIndId);
441 if (stationInd ==
null)
return;
443 stationInd.finishBuildingOrUpgrading();
446 CampaignFleetAPI fleet = Misc.getStationFleet(
entity);
447 if (fleet ==
null)
return;
449 List<FleetMemberAPI> members = fleet.getFleetData().getMembersListCopy();
450 if (members.size() < 1)
return;
452 fleet.inflateIfNeeded();
454 FleetMemberAPI station = members.get(0);
456 WeightedRandomPicker<Integer> picker =
new WeightedRandomPicker<Integer>();
458 for (String slotId : station.getVariant().getModuleSlots()) {
459 ShipVariantAPI mv = station.getVariant().getModuleVariant(slotId);
460 if (Misc.isActiveModule(mv)) {
461 picker.add(index, 1f);
466 float removeMult = 0f;
482 int remove = Math.round(picker.getItems().size() * removeMult);
483 if (remove < 1 && removeMult > 0)
remove = 1;
486 if (
remove >= picker.getItems().size() - 1) {
487 remove = picker.getItems().size() - 2;
490 for (
int i = 0; i <
remove; i++) {
491 Integer pick = picker.pickAndRemove();
493 station.getStatus().setHullFraction(pick, 0f);
494 station.getStatus().setDetached(pick,
true);
495 station.getStatus().setPermaDetached(pick,
true);
499 if (
tier == PirateBaseTier.TIER_5_3MODULE ||
tier == PirateBaseTier.TIER_4_3MODULE) {
536 CampaignFleetAPI fleet = Misc.getStationFleet(
market);
541 fleet.addEventListener(
this);
580 (((
float) Math.random() < 0.2f && allowRandomRaids) ||
597 boolean canEndBounty = !
entity.isInCurrentLocation();
598 bountyData.bountyElapsedDays += days;
617 if (
entity.isInCurrentLocation())
return;
622 if ((
float) Math.random() < prob) {
638 case TIER_1_1MODULE:
return PirateBaseTier.TIER_2_1MODULE;
639 case TIER_2_1MODULE:
return PirateBaseTier.TIER_3_2MODULE;
640 case TIER_3_2MODULE:
return PirateBaseTier.TIER_4_3MODULE;
641 case TIER_4_3MODULE:
return PirateBaseTier.TIER_5_3MODULE;
642 case TIER_5_3MODULE:
return null;
649 case TIER_1_1MODULE:
return null;
650 case TIER_2_1MODULE:
return PirateBaseTier.TIER_1_1MODULE;
651 case TIER_3_2MODULE:
return PirateBaseTier.TIER_2_1MODULE;
652 case TIER_4_3MODULE:
return PirateBaseTier.TIER_3_2MODULE;
653 case TIER_5_3MODULE:
return PirateBaseTier.TIER_4_3MODULE;
668 Global.
getSector().getIntelManager().addIntel(
this, text ==
null, text);
681 super.notifyEnding();
682 log.info(String.format(
"Removing pirate base at [%s]",
system.getName()));
688 Misc.removeRadioChatter(
market);
705 Misc.fadeAndExpire(
entity);
708 result =
new BountyResult(BountyResultType.END_OTHER, 0,
null);
710 if (reason == FleetDespawnReason.DESTROYED_BY_BATTLE &&
711 param instanceof BattleAPI) {
712 BattleAPI battle = (BattleAPI) param;
713 if (battle.isPlayerInvolved()) {
716 payment = (int) (
bountyData.baseBounty * battle.getPlayerInvolvementFraction());
719 Global.
getSector().getPlayerFleet().getCargo().getCredits().add(payment);
721 CustomRepImpact impact =
new CustomRepImpact();
722 impact.delta = bountyData.repChange * battle.getPlayerInvolvementFraction();
723 if (impact.delta < 0.01f) impact.delta = 0.01f;
724 ReputationAdjustmentResult rep =
Global.
getSector().adjustPlayerReputation(
725 new RepActionEnvelope(RepActions.CUSTOM,
726 impact,
null,
null,
false,
true),
729 result =
new BountyResult(BountyResultType.END_PLAYER_BOUNTY, payment, rep);
731 result =
new BountyResult(BountyResultType.END_PLAYER_NO_REWARD, 0,
null);
736 boolean sendUpdate = DebugFlags.SEND_UPDATES_WHEN_NO_COMM ||
737 result.type != BountyResultType.END_OTHER ||
758 Color h = Misc.getHighlightColor();
759 Color g = Misc.getGrayColor();
764 if (mode == ListInfoMode.IN_DESC) initPad = opad;
772 info.addPara(
"Agreement broken", initPad, tc,
773 Misc.getNegativeHighlightColor(),
"Agreement broken");
776 info.addPara(
"Agreement dissolved", tc, initPad);
780 info.addPara(
"Agreement made with base commander", initPad, tc,
781 Misc.getPositiveHighlightColor(),
"Agreement");
788 if (isUpdate || mode != ListInfoMode.IN_DESC) {
789 FactionAPI faction =
bountyData.bountyFaction;
790 info.addPara(
"Bounty faction: " + faction.getDisplayName(), initPad, tc,
791 faction.getBaseUIColor(), faction.getDisplayName());
794 info.addPara(
"%s reward", initPad, tc, h, Misc.getDGSCredits(
bountyData.baseBounty));
801 case END_PLAYER_BOUNTY:
802 info.addPara(
"%s received", initPad, tc, h, Misc.getDGSCredits(
result.payment));
804 null,
null, info, tc, isUpdate, 0f);
820 info.addPara(
getName(), c, 0f);
826 return base +
" Base";
834 return base +
" Base - Bounty Posted";
836 return base +
" Base - Bounty Expired";
840 if (
result.type == BountyResultType.END_PLAYER_BOUNTY) {
841 return base +
" Base - Bounty Completed";
842 }
else if (
result.type == BountyResultType.END_PLAYER_NO_REWARD) {
843 return base +
" Base - Destroyed";
847 String name =
market.getName();
850 return base +
" Base - Abandoned";
853 return base +
" Base - Discovered";
855 if (
entity.isDiscoverable()) {
856 return base +
" Base - Exact Location Unknown";
858 return base +
" Base - " + name;
863 return market.getFaction();
872 Color h = Misc.getHighlightColor();
873 Color g = Misc.getGrayColor();
874 Color tc = Misc.getTextColor();
882 FactionAPI faction =
market.getFaction();
884 info.addImage(faction.getLogo(), width, 128, opad);
886 String has = faction.getDisplayNameHasOrHave();
888 info.addPara(Misc.ucFirst(faction.getDisplayNameWithArticle()) +
" " + has +
889 " established a base in the " +
890 market.getContainingLocation().getNameWithLowercaseType() +
". " +
891 "The base serves as a staging ground for raids against nearby colonies.",
892 opad, faction.getBaseUIColor(), faction.getDisplayNameWithArticleWithoutArticle());
894 if (!
entity.isDiscoverable()) {
897 info.addPara(
"It has limited defensive capabilities " +
898 "and is protected by a few fleets.", opad);
901 info.addPara(
"It has limited defensive capabilities " +
902 "and is protected by a small number of fleets.", opad);
905 info.addPara(
"It has fairly well-developed defensive capabilities " +
906 "and is protected by a considerable number of fleets.", opad);
909 info.addPara(
"It has very well-developed defensive capabilities " +
910 "and is protected by a large number of fleets.", opad);
913 info.addPara(
"It has very well-developed defensive capabilities " +
914 "and is protected by a large number of fleets. Both the " +
915 "base and the fleets have elite-level equipment, at least by pirate standards.", opad);
920 info.addPara(
"You have not yet discovered the exact location or capabilities of this base.", opad);
929 String fee = Misc.getDGSCredits(HA_CMD.computePirateProtectionPaymentPerMonth(
this));
930 LabelAPI label = info.addPara(
"You have an %s with "
931 +
"the base commander, and fleets from this base do not, as a rule, "
932 +
"harass your colonies or shipping. The protection payment is %s of "
933 +
"the gross income of all of your affected colonies, which "
934 +
"amounts to %s per month at their current level of income.", opad,
935 Misc.getPositiveHighlightColor(),
937 "" + (
int)Math.round(feeFraction * 100f) +
"%", fee
939 label.setHighlightColors(Misc.getPositiveHighlightColor(), h, h);
940 label.setHighlight(
"agreement",
"" + (
int)Math.round(feeFraction * 100f) +
"%", fee);
944 info.addSectionHeading(
"Recent events",
945 faction.getBaseUIColor(), faction.getDarkUIColor(), Alignment.MID, opad);
948 info.addPara(
"Pirates operating from this base have been targeting the " +
949 target.getNameWithLowercaseType() +
".", opad);
953 info.addPara(Misc.ucFirst(
bountyData.bountyFaction.getDisplayNameWithArticle()) +
" " +
954 bountyData.bountyFaction.getDisplayNameHasOrHave() +
955 " posted a bounty for the destruction of this base.",
956 opad,
bountyData.bountyFaction.getBaseUIColor(),
957 bountyData.bountyFaction.getDisplayNameWithArticleWithoutArticle());
959 if (
result !=
null &&
result.type == BountyResultType.END_PLAYER_BOUNTY) {
960 info.addPara(
"You have successfully completed this bounty.", opad);
967 if (
result.type == BountyResultType.END_PLAYER_NO_REWARD) {
968 info.addPara(
"You have destroyed this base.", opad);
969 }
else if (
result.type == BountyResultType.END_OTHER) {
970 info.addPara(
"It is rumored that this base is no longer operational.", opad);
982 Set<String> tags = super.getIntelTags(map);
984 tags.add(Tags.INTEL_BOUNTY);
986 tags.add(Tags.INTEL_EXPLORATION);
991 if (
target !=
null && !Misc.getMarketsInLocation(
target, Factions.PLAYER).isEmpty()) {
992 tags.add(Tags.INTEL_COLONIES);
996 if (!PirateBasePirateActivityCause2.getColoniesAffectedBy(
this).isEmpty()) {
997 tags.add(Tags.INTEL_COLONIES);
1000 tags.add(
market.getFactionId());
1010 if (
market.getPrimaryEntity().isDiscoverable()) {
1011 return system.getCenter();
1013 return market.getPrimaryEntity();
1021 MarkovNames.loadIfNeeded();
1023 MarkovNameResult gen =
null;
1024 for (
int i = 0; i < 10; i++) {
1025 gen = MarkovNames.generate(
null);
1027 String test = gen.name;
1028 if (test.toLowerCase().startsWith(
"the "))
continue;
1030 if (p !=
null && !p.isEmpty()) {
1033 if (test.length() > 22)
continue;
1042 WeightedRandomPicker<String> post =
new WeightedRandomPicker<String>();
1044 post.add(
"Astrome");
1045 post.add(
"Barrage");
1046 post.add(
"Briganderie");
1049 post.add(
"Citadel");
1054 post.add(
"Freehold");
1055 post.add(
"Freeport");
1056 post.add(
"Freehaven");
1057 post.add(
"Free Orbit");
1058 post.add(
"Galastat");
1059 post.add(
"Garrison");
1062 post.add(
"Headquarters");
1063 post.add(
"Hideout");
1064 post.add(
"Hideaway");
1069 post.add(
"Mine Depot");
1074 post.add(
"Presidio");
1076 post.add(
"Platform");
1077 post.add(
"Corsairie");
1079 post.add(
"Retreat");
1080 post.add(
"Refinery");
1082 post.add(
"Safehold");
1083 post.add(
"Starhold");
1084 post.add(
"Starport");
1085 post.add(
"Stardock");
1086 post.add(
"Sanctuary");
1087 post.add(
"Station");
1088 post.add(
"Spacedock");
1089 post.add(
"Tertiary");
1090 post.add(
"Terminus");
1091 post.add(
"Terminal");
1092 post.add(
"Tortuga");
1099 CommodityOnMarketAPI com =
market.getCommodityData(commodityId);
1101 String modId =
market.getId();
1102 StatMod mod = com.getAvailableStat().getFlatStatMod(modId);
1104 curr = Math.round(mod.value);
1107 int avWithoutPenalties = (int) Math.round(com.getAvailableStat().getBaseValue());
1108 for (StatMod m : com.getAvailableStat().getFlatMods().values()) {
1109 if (m.value < 0)
continue;
1110 avWithoutPenalties += (int) Math.round(m.value);
1113 int a = com.getAvailable() - curr;
1114 a = avWithoutPenalties - curr;
1115 int d = com.getMaxDemand();
1118 int supply = Math.max(1, d - a);
1119 com.getAvailableStat().modifyFlat(modId, supply,
"Brought in by raiders");
1125 float fleetSizeBonus = 1f;
1126 float qualityBonus = 0f;
1132 case TIER_1_1MODULE:
1134 fleetSizeBonus = 0.2f;
1136 case TIER_2_1MODULE:
1137 qualityBonus = 0.2f;
1138 fleetSizeBonus = 0.3f;
1141 case TIER_3_2MODULE:
1142 qualityBonus = 0.3f;
1143 fleetSizeBonus = 0.4f;
1147 case TIER_4_3MODULE:
1148 qualityBonus = 0.4f;
1149 fleetSizeBonus = 0.5f;
1153 case TIER_5_3MODULE:
1154 qualityBonus = 0.5f;
1155 fleetSizeBonus = 0.75f;
1162 market.getStats().getDynamic().getMod(Stats.FLEET_QUALITY_MOD).
1163 modifyFlatAlways(
market.getId(), qualityBonus,
1164 "Development level");
1166 market.getStats().getDynamic().getMod(Stats.COMBAT_FLEET_SIZE_MULT).modifyFlatAlways(
market.getId(),
1168 "Development level");
1171 String modId =
market.getId();
1172 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_LIGHT_MOD).modifyFlat(modId, light);
1173 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_MEDIUM_MOD).modifyFlat(modId, medium);
1174 market.getStats().getDynamic().getMod(Stats.PATROL_NUM_HEAVY_MOD).modifyFlat(modId, heavy);
1188 float base = 100000f;
1190 case TIER_1_1MODULE:
1192 bountyData.repChange = 0.02f;
1194 case TIER_2_1MODULE:
1196 bountyData.repChange = 0.05f;
1198 case TIER_3_2MODULE:
1200 bountyData.repChange = 0.06f;
1202 case TIER_4_3MODULE:
1204 bountyData.repChange = 0.07f;
1206 case TIER_5_3MODULE:
1208 bountyData.repChange = 0.1f;
1212 bountyData.baseBounty = base * (0.9f + (float) Math.random() * 0.2f);
1214 bountyData.baseBounty = (int)(
bountyData.baseBounty / 10000) * 10000;
1217 WeightedRandomPicker<FactionAPI> picker =
new WeightedRandomPicker<FactionAPI>();
1219 if (curr.getFaction().isPlayerFaction())
continue;
1220 if (curr.getFaction().getCustom().optBoolean(Factions.CUSTOM_POSTS_NO_BOUNTIES))
continue;
1223 picker.add(curr.getFaction(), (float) Math.pow(2f, curr.getSize()));
1227 FactionAPI faction = picker.pick();
1228 if (faction ==
null) {
1233 bountyData.bountyFaction = faction;
1234 bountyData.bountyDuration = 180f;
1235 bountyData.bountyElapsedDays = 0f;
1237 Misc.makeImportant(
entity,
"baseBounty");
1249 Misc.makeUnimportant(
entity,
"baseBounty");
1257 if (newTarget ==
target)
return;
1290 List<MarketAPI>
result =
new ArrayList<MarketAPI>();
1299 if (
market.isHidden())
return false;
1300 if (
market.getFaction() ==
this.market.getFaction())
return false;
1315 this.targetPlayerColoniesOnly = targetPlayerColonies;
1331 WeightedRandomPicker<StarSystemAPI> picker =
new WeightedRandomPicker<StarSystemAPI>();
1332 boolean forceTargetIsValid =
false;
1340 forceTargetIsValid =
true;
1342 if (curr.hasCondition(Conditions.PIRATE_ACTIVITY))
continue;
1348 float w = curr.getSize();
1351 float dist = Misc.getDistanceLY(curr.getLocationInHyperspace(),
market.getLocationInHyperspace());
1353 float mult = 1f - Math.max(0f, dist - 10f) / 10f;
1354 if (mult < 0.1f) mult = 0.1f;
1355 if (mult > 1) mult = 1;
1358 if (dist > 15f)
continue;
1364 picker.add(
system, score);
1367 if (forceTargetIsValid) {
1371 return picker.pick();
1377 List<ArrowData>
result =
new ArrayList<ArrowData>();
1379 SectorEntityToken entityFrom =
entity;
1381 SectorEntityToken iconEntity = map.getIntelIconEntity(
this);
1382 if (iconEntity !=
null) {
1383 entityFrom = iconEntity;
1387 ArrowData arrow =
new ArrowData(entityFrom,
target.getCenter());
1396 case TIER_1_1MODULE:
return 0.1f;
1397 case TIER_2_1MODULE:
return 0.2f;
1398 case TIER_3_2MODULE:
return 0.3f;
1399 case TIER_4_3MODULE:
return 0.4f;
1400 case TIER_5_3MODULE:
return 0.5f;
1407 case TIER_1_1MODULE:
return 1f;
1408 case TIER_2_1MODULE:
return 1f;
1409 case TIER_3_2MODULE:
return 2f;
1410 case TIER_4_3MODULE:
return 2f;
1411 case TIER_5_3MODULE:
return 3f;
static SettingsAPI getSettings()
static FactoryAPI getFactory()
static Logger getLogger(Class c)
static SectorAPI getSector()
static void addAdjustmentMessage(float delta, FactionAPI faction, PersonAPI person, TextPanelAPI panel, TooltipMakerAPI info, Color tc, boolean withCurrent, float pad)
static boolean SEND_UPDATES_WHEN_NO_COMM
static boolean RAID_DEBUG
static int PIRATE_RAID_MIN_TIMEOUT_MONTHS
static float NO_PIRATE_RAID_DAYS_FROM_GAME_START
static int PIRATE_RAID_DEFEATED_TIMEOUT_MONTHS
static int PIRATE_RAID_MAX_TIMEOUT_MONTHS
void sendUpdate(Object listInfoParam, TextPanelAPI textPanel)
void unindent(TooltipMakerAPI info)
void addDays(TooltipMakerAPI info, String after, float days)
Long getPlayerVisibleTimestamp()
void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel)
Object getListInfoParam()
Color getBulletColorForMode(ListInfoMode mode)
void bullet(TooltipMakerAPI info)
Color getTitleColor(ListInfoMode mode)
void checkForTierChange()
StarSystemAPI getSystem()
PirateBaseTier matchedStationToTier
static PirateBaseIntel getIntelFor(SectorEntityToken station)
SectorEntityToken getMapLocation(SectorMapAPI map)
boolean targetPlayerColoniesOnly
boolean affectsMarket(MarketAPI market)
float getTimeRemainingFraction()
Industry getStationIndustry()
PirateBaseTier getNextTier(PirateBaseTier tier)
List< ArrowData > getArrowData(SectorMapAPI map)
float getStabilityPenalty()
static final String PIRATE_BASE_COMMANDER
StarSystemAPI getForceTarget()
static Object DEAL_CANCELLED_PARAM
FactionAPI getFactionForUIColors()
boolean isTargetPlayerColoniesOnly()
Set< String > getIntelTags(SectorMapAPI map)
SectorEntityToken getEntity()
static final String HAS_DEAL_WITH_BASE_COMMANDER
StarSystemAPI pickTarget()
void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle)
void createSmallDescription(TooltipMakerAPI info, float width, float height)
PersonAPI getBaseCommander()
void notifyRaidEnded(RaidIntel raid, RaidStageStatus status)
static Object DISCOVERED_PARAM
PirateBaseTier getPrevTier(PirateBaseTier tier)
PirateBaseIntel(StarSystemAPI system, String factionId, PirateBaseTier tier)
static PirateBaseIntel getIntelFor(StarSystemAPI system)
boolean isEconomyListenerExpired()
static Object BOUNTY_EXPIRED_PARAM
void setBaseCommander(PersonAPI baseCommander)
float getAccessibilityPenalty()
CampaignFleetAPI addedListenerTo
void updateStationIfNeeded()
void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode)
StarSystemAPI getTarget()
void commodityUpdated(String commodityId)
BaseBountyData bountyData
boolean playerHasDealWithBaseCommander()
StarSystemAPI forceTarget
String getSmallDescriptionTitle()
void setForceTarget(StarSystemAPI forceTarget)
static Object DEAL_MADE_PARAM
void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode)
IntervalUtil monthlyInterval
void setTargetPlayerColoniesOnly(boolean targetPlayerColonies)
void startRaid(StarSystemAPI target, float raidFP)
static PirateBaseIntel getIntelFor(MarketAPI market)
void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param)
CampaignFleetAPI getAddedListenerTo()
void setPlayerHasDealWithBaseCommander(boolean hasDeal)
List< MarketAPI > getAffectedMarkets(StarSystemAPI system)
static Object DEAL_BROKEN_PARAM
void advanceImpl(float amount)
void makeKnown(TextPanelAPI text)
float getDaysSinceStart()
static PirateBaseManager getInstance()
static void markRecentlyUsedForBase(StarSystemAPI system)
MarketAPI createMarket(String id, String name, int size)
String getSpriteName(String category, String id)
float getFloat(String key)