1package com.fs.starfarer.api.impl.campaign.intel.raid;
4import java.util.ArrayList;
6import java.util.Random;
9import org.lwjgl.util.vector.Vector2f;
11import com.fs.starfarer.api.Global;
12import com.fs.starfarer.api.campaign.CampaignFleetAPI;
13import com.fs.starfarer.api.campaign.FactionAPI;
14import com.fs.starfarer.api.campaign.SectorEntityToken;
15import com.fs.starfarer.api.campaign.StarSystemAPI;
16import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
17import com.fs.starfarer.api.campaign.econ.MarketAPI;
18import com.fs.starfarer.api.impl.campaign.DebugFlags;
19import com.fs.starfarer.api.impl.campaign.command.WarSimScript;
20import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3;
21import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3;
22import com.fs.starfarer.api.impl.campaign.fleets.RouteLocationCalculator;
23import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.OptionalFleetData;
24import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteData;
25import com.fs.starfarer.api.impl.campaign.fleets.RouteManager.RouteFleetSpawner;
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.Tags;
30import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
31import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseAssignmentAI.FleetActionDelegate;
32import com.fs.starfarer.api.impl.campaign.procgen.themes.RouteFleetAssignmentAI;
33import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.MarketCMD;
34import com.fs.starfarer.api.ui.Alignment;
35import com.fs.starfarer.api.ui.LabelAPI;
36import com.fs.starfarer.api.ui.SectorMapAPI;
37import com.fs.starfarer.api.ui.TooltipMakerAPI;
38import com.fs.starfarer.api.util.Misc;
46 public static enum RaidStageStatus {
52 public static interface RaidDelegate {
53 void notifyRaidEnded(
RaidIntel raid, RaidStageStatus status);
56 public static interface RaidStage {
57 RaidStageStatus getStatus();
58 void advance(
float amount);
60 float getExtraDaysUsed();
68 protected List<RaidStage>
stages =
new ArrayList<RaidStage>();
71 protected String
sid =
"raid_" +
id;
114 return stages.indexOf(stage);
122 for (RaidStage stage :
stages) {
130 for (RaidStage stage :
stages) {
140 for (RaidStage stage :
stages) {
169 return super.canMakeVisibleToPlayer(playerInRelayRange);
202 super.advanceImpl(amount);
219 stage.advance(amount);
221 RaidStageStatus status = stage.getStatus();
222 if (status == RaidStageStatus.SUCCESS) {
229 }
else if (status == RaidStageStatus.FAILURE) {
263 super.notifyEnding();
266 RaidStageStatus status = RaidStageStatus.SUCCESS;
268 status = RaidStageStatus.FAILURE;
270 delegate.notifyRaidEnded(
this, status);
278 for (RaidStage stage :
stages) {
288 eta += Math.max(0f, stage.getMaxDays() - stage.getElapsed());
290 eta += Math.max(0f, 20f - stage.getElapsed());
293 eta += Math.max(0f, travelDays - stage.getElapsed());
307 if (mode == ListInfoMode.IN_DESC) initPad = opad;
323 if (!other.getFaction().isHostileTo(
faction))
continue;
324 int size = other.getSize();
325 if (size > max || (size == max && other.getFaction().isPlayerFaction())) {
332 if (target !=
null) {
340 info.
addPara(
"Arrived in-system", tc, initPad);
357 info.
addPara(
"Estimated %s " + days +
" until arrival",
358 initPad, tc, h,
"" + (
int)Math.round(eta));
382 if (as ==
null)
return null;
424 String fleets =
"fleets";
425 if (numFleets == 1) fleets =
" large fleet, or several smaller ones";
428 " conducting a raid of the " +
system.
getName() +
". The raiding forces are " +
429 "projected to be " + strDesc +
430 " and likely comprised of " + numFleets +
" " + fleets +
".",
435 List<MarketAPI> targets =
new ArrayList<MarketAPI>();
437 if (market.getFaction().isHostileTo(
faction)) {
444 List<MarketAPI> safe =
new ArrayList<MarketAPI>();
445 List<MarketAPI> unsafe =
new ArrayList<MarketAPI>();
448 if (defensiveStr > raidStr * 1.25f) {
456 if (targets.isEmpty()) {
457 info.
addPara(
"There are no colonies for the raid to target in the system.", opad);
459 boolean showSafe =
false;
461 info.
addPara(
"The raiding forces should be outmatched by fleets defending the system. In the absence of " +
462 "other factors, the raid is unlikely to find success.", opad);
464 info.
addPara(
"The raiding forces are evenly matched with fleets defending the system.", opad);
467 info.
addPara(
"The raiding forces are superior to the fleets defending the system.", opad);
471 if (safe.size() == targets.size()) {
472 info.
addPara(
"However, all colonies should be safe from the raid, " +
473 "owing to their orbital defenses.", opad);
475 info.
addPara(
"Considering orbital defenses (if any), the following colonies are " +
476 "at risk from the raid:", opad);
477 float initPad = opad;
495 for (RaidStage stage :
stages) {
496 stage.showStageInfo(info);
510 Set<String> tags = super.getIntelTags(map);
527 return base +
" - Failed";
529 for (RaidStage stage :
stages) {
531 return base +
" - Successful";
534 return base +
" - Over";
544 for (RaidStage stage :
stages) {
579 List<ArrowData> result =
new ArrayList<ArrowData>();
584 if (iconEntity !=
null) {
585 entityFrom = iconEntity;
612 Random random = route.getRandom();
617 if (fleet ==
null || fleet.
isEmpty())
return null;
622 fleet.
setFacing((
float) Math.random() * 360f);
641 if (random ==
null) random =
new Random();
643 OptionalFleetData extra = route.getExtra();
645 float combat = extra.fp;
646 float tanker = extra.fp * (0.1f + random.nextFloat() * 0.05f);
647 float transport = extra.fp * (0.1f + random.nextFloat() * 0.05f);
648 float freighter = 0f;
656 route ==
null ?
null : route.getQualityOverride(),
671 params.timestamp = route.getTimestamp();
673 params.random = random;
676 if (fleet ==
null || fleet.
isEmpty())
return null;
713 if (mult < 1) mult = 1f;
716 raidStr += route.getExtra().fp;
722 float raidFP = raidStr;
732 if (num < 1) num = 1;
739 if (num < 1) num = 1;
760 boolean withGround,
boolean withBombard,
761 String raid, String raids) {
777 String spaceStr =
"";
778 String groundStr =
"";
779 String outcomeDesc =
null;
780 boolean even =
false;
781 if (raidStr < defensiveStr * 0.75f) {
782 spaceStr =
"outmatched";
783 if (outcomeDesc ==
null) outcomeDesc =
"The " + raid +
" is likely to be defeated in orbit";
784 }
else if (raidStr < defensiveStr * 1.25f) {
785 spaceStr =
"evenly matched";
786 if (outcomeDesc ==
null) outcomeDesc =
"The " + raids +
" outcome is uncertain";
789 spaceStr =
"superior";
790 if (!withGround && !withBombard) {
791 if (outcomeDesc ==
null) outcomeDesc =
"The " + raid +
" is likely to be successful";
797 groundStr =
"outmatched";
798 if (outcomeDesc ==
null || even) outcomeDesc =
"The " + raid +
" is likely to be largely repelled by the ground defences";
799 }
else if (re < 0.66f) {
800 groundStr =
"evenly matched";
801 if (outcomeDesc ==
null) outcomeDesc =
"The " + raids +
" outcome is uncertain";
803 groundStr =
"superior";
804 if (outcomeDesc ==
null) outcomeDesc =
"The " + raid +
" is likely to be successful";
807 info.
addPara(
"Compared to the defenses, the " + raids +
" space forces are %s " +
808 "and its ground forces are %s." +
809 " " + outcomeDesc +
".", opad, h, spaceStr, groundStr);
810 }
else if (withBombard) {
814 if (required * .67 > available) {
815 groundStr =
"outmatched";
816 if (outcomeDesc ==
null) outcomeDesc =
"The bombardment is likely to be countered by the ground defences";
817 }
else if (required * 1.33f > available) {
818 groundStr =
"evenly matched";
819 if (outcomeDesc ==
null) outcomeDesc =
"The bombardment's outcome is uncertain";
821 groundStr =
"superior";
822 if (outcomeDesc ==
null) outcomeDesc =
"The bombardment is likely to be successful";
825 info.
addPara(
"Compared to the defenses, the " + raids +
" space forces are %s. " +
826 "" + outcomeDesc +
".", opad, h, spaceStr, groundStr);
829 info.
addPara(
"Compared to the defenses of " + target.
getName() +
", " +
830 "the " + raids +
" space forces are %s." +
831 " " + outcomeDesc +
".", opad, h, spaceStr, groundStr);
838 return IntelSortTier.TIER_2;
840 return super.getSortTier();
static SectorAPI getSector()
static boolean SEND_UPDATES_WHEN_NO_COMM
static float getFactionStrength(String factionId, StarSystemAPI system)
static float getStationStrength(FactionAPI faction, StarSystemAPI system, SectorEntityToken from)
static float getEnemyStrength(String factionId, StarSystemAPI system)
static CampaignFleetAPI createFleet(FleetParamsV3 params)
static float getTravelDays(SectorEntityToken from, SectorEntityToken to)
static final String PLAYER
static final String CUSTOM_PIRATE_BEHAVIOR
static final String MEMORY_KEY_WAR_FLEET
static final String MEMORY_KEY_PIRATE
static final String MEMORY_KEY_RAIDER
static String POST_PATROL_COMMANDER
static String SPACE_COMMANDER
boolean isSendingUpdate()
void unindent(TooltipMakerAPI info)
static String getSoundStandardUpdate()
void sendUpdateIfPlayerHasIntel(Object listInfoParam, TextPanelAPI textPanel)
Object getListInfoParam()
Color getBulletColorForMode(ListInfoMode mode)
static String getSoundColonyThreat()
static String getDaysString(float days)
void bullet(TooltipMakerAPI info)
static String getSoundMajorPosting()
Color getTitleColor(ListInfoMode mode)
static void addMarketToList(TooltipMakerAPI info, MarketAPI market, float pad)
abstract boolean isPlayerTargeted()
float getLargeSize(boolean limitToSpawnFP)
List< MarketAPI > getSources()
SectorEntityToken gatheringPoint
RaidStageStatus getStatus()
List< RouteData > getRoutes()
IntelSortTier getSortTier()
void createSmallDescription(TooltipMakerAPI info, float width, float height)
CampaignFleetAPI spawnFleet(RouteData route)
String getSmallDescriptionTitle()
static Object UPDATE_RETURNING
SectorEntityToken getMapLocation(SectorMapAPI map)
RaidIntel(StarSystemAPI system, FactionAPI faction, RaidDelegate delegate)
void addStage(RaidStage stage)
List< ArrowData > getArrowData(SectorMapAPI map)
AssembleStage getAssembleStage()
boolean shouldRepeat(RouteData route)
CampaignFleetAPI createFleet(String factionId, RouteData route, MarketAPI market, Vector2f locInHyper, Random random)
Set< String > getIntelTags(SectorMapAPI map)
void addStandardStrengthComparisons(TooltipMakerAPI info, MarketAPI target, FactionAPI targetFaction, boolean withGround, boolean withBombard, String raid, String raids)
void failedAtStage(RaidStage stage)
ActionStage getActionStage()
boolean isPlayerTargeted()
static Object UPDATE_FAILED
String getCommMessageSound()
void forceFail(boolean withUpdate)
void reportAboutToBeDespawnedByRouteManager(RouteData route)
FactionAPI getFactionForUIColors()
boolean canMakeVisibleToPlayer(boolean playerInRelayRange)
static Object ENTERED_SYSTEM_UPDATE
OrganizeStage getOrganizeStage()
void addBulletPoints(TooltipMakerAPI info, ListInfoMode mode)
String getRouteSourceId()
int getStageIndex(RaidStage stage)
void createIntelInfo(TooltipMakerAPI info, ListInfoMode mode)
StarSystemAPI getSystem()
float getRaidFPAdjusted()
void sendEnteredSystemUpdate()
RouteFleetAssignmentAI createAssignmentAI(CampaignFleetAPI fleet, RouteData route)
MarketAPI getFirstSource()
void advanceImpl(float amount)
void setExtraDays(float extraDays)
boolean shouldSendUpdate()
boolean shouldCancelRouteAfterDelayCheck(RouteData route)
static float getRaidEffectiveness(MarketAPI market, CampaignFleetAPI fleet)
static int getBombardmentCost(MarketAPI market, CampaignFleetAPI fleet)
static Color getTextColor()
static float FP_TO_GROUND_RAID_STR_APPROX_MULT
static List< MarketAPI > getMarketsInLocation(LocationAPI location, String factionId)
static String ucFirst(String str)
static Color getGrayColor()
static String getStrengthDesc(float strAdjustedFP)
static Color getHighlightColor()
static float getAdjustedFP(float fp, MarketAPI market)
static float FP_TO_BOMBARD_COST_APPROX_MULT
static float getAdjustedStrength(float fp, MarketAPI market)
void setLocation(float x, float y)
String getDisplayNameHasOrHave()
String getDisplayNameWithArticleWithoutArticle()
String getDisplayNameWithArticle()
boolean getCustomBoolean(String key)
String getDisplayNameIsOrAre()
String getNameWithLowercaseType()
void addEntity(SectorEntityToken entity)
void addScript(EveryFrameScript script)
LocationAPI getCurrentLocation()
void removeScript(EveryFrameScript script)
IntelManagerAPI getIntelManager()
LocationAPI getContainingLocation()
void addScript(EveryFrameScript script)
void setFacing(float facing)
MemoryAPI getMemoryWithoutUpdate()
SectorEntityToken getHyperspaceAnchor()
SectorEntityToken getCenter()
boolean isPlayerInRangeOfCommRelay()
LocationAPI getContainingLocation()
SectorEntityToken getPrimaryEntity()
void set(String key, Object value)
void setRankId(String rank)
void setPostId(String postId)
void setHighlight(int start, int end)
void setHighlightColors(Color ... colors)
SectorEntityToken getIntelIconEntity(IntelInfoPlugin plugin)