001package com.fs.starfarer.api.impl.campaign.intel.group; 002 003import com.fs.starfarer.api.Global; 004import com.fs.starfarer.api.campaign.CampaignFleetAPI; 005import com.fs.starfarer.api.campaign.StarSystemAPI; 006import com.fs.starfarer.api.fleet.FleetMemberAPI; 007import com.fs.starfarer.api.impl.campaign.ids.Factions; 008import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 009import com.fs.starfarer.api.impl.campaign.ids.Ranks; 010import com.fs.starfarer.api.impl.campaign.ids.Skills; 011import com.fs.starfarer.api.impl.campaign.intel.events.TriTachyonHostileActivityFactor; 012import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission; 013import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetQuality; 014import com.fs.starfarer.api.ui.TooltipMakerAPI; 015import com.fs.starfarer.api.util.IntervalUtil; 016import com.fs.starfarer.api.util.Misc; 017 018 019 020public class TTMercenaryAttack extends GenericRaidFGI { 021 022 public static final String TTMA_FLEET = "$TTMA_fleet"; 023 public static final String TTMA_COMMAND = "$TTMA_command"; 024 025 public static String KEY = "$TTMA_ref"; 026 public static TTMercenaryAttack get() { 027 return (TTMercenaryAttack) Global.getSector().getMemoryWithoutUpdate().get(KEY); 028 } 029 030 031 protected IntervalUtil interval = new IntervalUtil(0.1f, 0.3f); 032 033 034 public TTMercenaryAttack(GenericRaidParams params) { 035 super(params); 036 037 Global.getSector().getMemoryWithoutUpdate().set(KEY, this); 038 } 039 040 @Override 041 protected void notifyEnding() { 042 super.notifyEnding(); 043 044 Global.getSector().getMemoryWithoutUpdate().unset(KEY); 045 } 046 047 @Override 048 protected void notifyEnded() { 049 super.notifyEnded(); 050 } 051 052 053 @Override 054 public String getNoun() { 055 return "mercenary attack"; 056 } 057 058 @Override 059 public String getForcesNoun() { 060 return super.getForcesNoun(); 061 } 062 063 064 @Override 065 public String getBaseName() { 066 return "Tri-Tachyon Mercenary Attack"; 067 } 068 069 070 transient protected boolean merc = false; 071 @Override 072 protected String getFleetCreationFactionOverride(int size) { 073 if (getRandom().nextFloat() < 0.5f || size == 10) { 074 merc = true; 075 return Factions.MERCENARY; 076 } 077 merc = false; 078 return Factions.TRITACHYON; 079 } 080 081 @Override 082 protected void configureFleet(int size, FleetCreatorMission m) { 083 084 // so that the merc source is not a TriTach market, if that's where they spawned 085 // doesn't work (since based on spawn faction anyway) and gets weird w/ mercs going back to different markets -am 086 //m.getPreviousCreateFleetAction().params.setSource(null, false); 087 088 m.triggerSetFleetFlag(TTMA_FLEET); 089 090 if (size == 10) { 091 m.triggerSetFleetQuality(FleetQuality.SMOD_3); 092 m.triggerSetFleetFlag(TTMA_COMMAND); 093 } else if (getRandom().nextFloat() < 0.5f) { 094 m.triggerSetFleetQuality(FleetQuality.SMOD_1); 095 } else { 096 m.triggerSetFleetQuality(FleetQuality.SMOD_2); 097 } 098 099 // don't want to be shooting it out with the employer, who's normally hostile to independents 100 m.triggerMakeNonHostileToFaction(Factions.TRITACHYON); 101 102 103 // likely spawning from Nortia, try not to get sidetracked 104 m.triggerMakeNonHostileToFaction(Factions.DIKTAT); 105 m.triggerMakeNonHostileToFaction(Factions.PIRATES); 106 107 108 if (merc) { 109 m.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1); 110 m.triggerFleetAddCommanderSkill(Skills.TACTICAL_DRILLS, 1); 111 } else { 112 m.triggerFleetAddCommanderSkill(Skills.PHASE_CORPS, 1); 113 m.triggerFleetAddCommanderSkill(Skills.FLUX_REGULATION, 1); 114 } 115 116 if (size == 10) { 117 m.triggerFleetAddCommanderSkill(Skills.ELECTRONIC_WARFARE, 1); 118 m.triggerFleetAddCommanderSkill(Skills.SUPPORT_DOCTRINE, 1); 119 } 120 121 int tugs = 0; 122 if (size == 10) { 123 tugs = 2; 124 } else if (merc) { 125 tugs = getRandom().nextInt(3); 126 } 127 128 boolean lightDetachment = size <= 5; 129 if (lightDetachment) { 130 m.triggerSetFleetMaxShipSize(3); 131 } 132 133 m.triggerFleetMakeFaster(true, tugs, true); 134 } 135 136 @Override 137 protected void configureFleet(int size, CampaignFleetAPI fleet) { 138 boolean hasCombatCapital = false; 139 boolean hasCivCapital = false; 140 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 141 if (member.isCapital()) { 142 hasCombatCapital |= !member.isCivilian(); 143 hasCivCapital |= member.isCivilian(); 144 } 145 } 146 147 if (size == 10) { 148 fleet.setName("Tactistar Operations Command"); 149 fleet.getCommander().setRankId(Ranks.SPACE_ADMIRAL); 150 setNeverStraggler(fleet); 151 } else if (hasCombatCapital) { 152 fleet.setName("Tactistar Assault Detachment"); 153 fleet.getCommander().setRankId(Ranks.SPACE_CAPTAIN); 154 } else if (hasCivCapital) { 155 fleet.setName("Tactistar Support Detachment"); 156 fleet.getCommander().setRankId(Ranks.SPACE_CAPTAIN); 157 } else { 158 fleet.setName("Tactistar Light Detachment"); 159 fleet.getCommander().setRankId(Ranks.SPACE_COMMANDER); 160 } 161 } 162 163 164 @Override 165 public void abort() { 166 if (!isAborted()) { 167 for (CampaignFleetAPI curr : getFleets()) { 168 curr.getMemoryWithoutUpdate().unset(TTMA_FLEET); 169 } 170 } 171 super.abort(); 172 } 173 174 175 176 @Override 177 public void advance(float amount) { 178 super.advance(amount); 179 180 float days = Misc.getDays(amount); 181 interval.advance(days); 182 183 // only hostile while in the target system and on the job, so to speak 184 // unless the player is baseline hostile to independents 185 if (interval.intervalElapsed()) { 186 if (isCurrent(PAYLOAD_ACTION)) { 187 String reason = "TTMA"; 188 for (CampaignFleetAPI curr : getFleets()) { 189 Misc.setFlagWithReason(curr.getMemoryWithoutUpdate(), MemFlags.MEMORY_KEY_MAKE_HOSTILE, 190 reason, true, 1f); 191 } 192 193 } 194 } 195 } 196 197 @Override 198 protected void addPostAssessmentSection(TooltipMakerAPI info, float width, float height, float opad) { 199 TTMercenaryAttack attack = TTMercenaryAttack.get(); 200 StarSystemAPI target = TriTachyonHostileActivityFactor.getPrimaryTriTachyonSystem(); 201 boolean reversible = attack != null && !attack.isSpawning() && !attack.isFailed() && 202 !attack.isSucceeded() && !attack.isAborted() && !attack.isEnding() && !attack.isEnded() && 203 target != null; 204 if (reversible) { 205 info.addPara("Mercenary companies are notoriously flexible in their allegiances.", opad, 206 Misc.getHighlightColor(), "notoriously flexible"); 207 } 208 } 209} 210 211 212 213