001package com.fs.starfarer.api.impl.campaign.intel.group; 002 003import java.util.Random; 004 005import org.lwjgl.util.vector.Vector2f; 006 007import com.fs.starfarer.api.Global; 008import com.fs.starfarer.api.campaign.CampaignFleetAPI; 009import com.fs.starfarer.api.campaign.FleetAssignment; 010import com.fs.starfarer.api.campaign.SectorEntityToken; 011import com.fs.starfarer.api.characters.PersonAPI; 012import com.fs.starfarer.api.combat.MutableStatWithTempMods; 013import com.fs.starfarer.api.impl.campaign.NPCHassler; 014import com.fs.starfarer.api.impl.campaign.ids.FleetTypes; 015import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 016import com.fs.starfarer.api.impl.campaign.ids.People; 017import com.fs.starfarer.api.impl.campaign.ids.Ranks; 018import com.fs.starfarer.api.impl.campaign.ids.Skills; 019import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel; 020import com.fs.starfarer.api.impl.campaign.intel.events.PerseanLeagueHostileActivityFactor; 021import com.fs.starfarer.api.impl.campaign.intel.group.FGBlockadeAction.FGBlockadeParams; 022import com.fs.starfarer.api.impl.campaign.missions.FleetCreatorMission; 023import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetQuality; 024import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.FleetSize; 025import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerNum; 026import com.fs.starfarer.api.impl.campaign.missions.hub.HubMissionWithTriggers.OfficerQuality; 027import com.fs.starfarer.api.ui.TooltipMakerAPI; 028import com.fs.starfarer.api.util.Misc; 029 030 031 032public class PerseanLeagueBlockade extends BlockadeFGI { 033 034 public static float NUM_OTHER_FLEETS_MULT = 0.25f; 035 036 public static final String ARMADA = "$PLB_armada"; 037 public static final String SUPPLY = "$PLB_supply"; 038 public static final String GENERIC = "$PLB_generic"; 039 040 //public static final String ABORTED_OR_ENDING = "$PLB_abortedOrEnding"; 041 public static final String BLOCKADING = "$PLB_isBlockading"; 042 043 public static String KEY = "$plBlockade_ref"; 044 public static PerseanLeagueBlockade get() { 045 return (PerseanLeagueBlockade) Global.getSector().getMemoryWithoutUpdate().get(KEY); 046 } 047 048 049 public PerseanLeagueBlockade(GenericRaidParams params, FGBlockadeParams blockadeParams) { 050 super(params, blockadeParams); 051 052 Global.getSector().getMemoryWithoutUpdate().set(KEY, this); 053 054 PersonAPI reynard = People.getPerson(People.REYNARD_HANNAN); 055 if (reynard != null) { 056 Misc.makeImportant(reynard, "PLB"); 057 } 058 } 059 060 @Override 061 protected void notifyEnding() { 062 super.notifyEnding(); 063 064 Global.getSector().getMemoryWithoutUpdate().unset(KEY); 065 066 PersonAPI reynard = People.getPerson(People.REYNARD_HANNAN); 067 if (reynard != null) { 068 Misc.makeUnimportant(reynard, "PLB"); 069 } 070 } 071 072 @Override 073 protected void notifyEnded() { 074 super.notifyEnded(); 075 } 076 077 078 079 080 081 protected boolean createdArmada = false; 082 protected int supplyFleets = 0; 083 084 @Override 085 protected CampaignFleetAPI createFleet(int size, float damage) { 086 087 Random r = getRandom(); 088 089 Vector2f loc = origin.getLocationInHyperspace(); 090 091 FleetCreatorMission m = new FleetCreatorMission(r); 092 m.beginFleet(); 093 094 boolean armada = size == 10 && !createdArmada; 095 boolean supplyFleet = size == 1 && supplyFleets < 2; 096 097 if (armada) { 098 createdArmada = true; 099 100 m.triggerCreateFleet(FleetSize.MAXIMUM, FleetQuality.SMOD_2, params.factionId, FleetTypes.LEAGUE_ARMADA, loc); 101 m.triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER); 102 m.triggerSetFleetFlag(ARMADA); 103 104 m.triggerSetFleetType(FleetTypes.LEAGUE_ARMADA); 105 m.triggerSetFleetDoctrineQuality(5, 5, 5); 106 m.triggerSetFleetDoctrineOther(5, 0); 107 m.triggerSetFleetComposition(0f, 0f, 0f, 0f, 0f); 108 m.triggerFleetMakeFaster(true, 1, false); 109 110 m.triggerFleetAddCommanderSkill(Skills.CREW_TRAINING, 1); 111 m.triggerFleetAddCommanderSkill(Skills.COORDINATED_MANEUVERS, 1); 112 m.triggerFleetAddCommanderSkill(Skills.TACTICAL_DRILLS, 1); 113 m.triggerFleetAddCommanderSkill(Skills.CARRIER_GROUP, 1); 114 } else if (supplyFleet) { 115 supplyFleets++; 116 117 int total = 0; 118 for (Integer i : params.fleetSizes) total += i; 119 120 FleetSize supplyFleetSize = FleetSize.MEDIUM; 121 if (total < 50) { 122 supplyFleetSize = FleetSize.SMALL; 123 } else if (total >= 80) { 124 supplyFleetSize = FleetSize.LARGE; 125 } 126 127 m.triggerCreateFleet(supplyFleetSize, FleetQuality.DEFAULT, params.factionId, FleetTypes.SUPPLY_FLEET, loc); 128 m.triggerSetFleetOfficers(OfficerNum.DEFAULT, OfficerQuality.DEFAULT); 129 m.triggerSetFleetFlag(SUPPLY); 130 131 m.triggerSetFleetType(FleetTypes.SUPPLY_FLEET); 132 m.triggerFleetMakeFaster(true, 0, false); 133 134 m.triggerSetFleetComposition(0.5f, 0.5f, 0.1f, 0f, 0.1f); 135 } else { 136 m.createFleet(params.style, size, params.factionId, loc); 137 m.triggerSetFleetFlag(GENERIC); 138 } 139 140 m.setFleetSource(params.source); 141 setFleetCreatorQualityFromRoute(m); 142 m.setFleetDamageTaken(damage); 143 144 m.triggerSetPatrol(); 145 m.triggerMakeLowRepImpact(); 146 m.triggerMakeAlwaysSpreadTOffHostility(); 147 148 149 CampaignFleetAPI fleet = m.createFleet(); 150 151 if (fleet != null && !armada && !supplyFleet) { 152 fleet.addScript(new NPCHassler(fleet, getTargetSystem())); 153 } 154 155 if (fleet != null && armada) { 156 fleet.getCommander().setRankId(Ranks.SPACE_ADMIRAL); 157 setNeverStraggler(fleet); 158 } 159 160 return fleet; 161 } 162 163// @Override 164// public void abort() { 165// if (!isAborted()) { 166// for (CampaignFleetAPI curr : getFleets()) { 167// curr.getMemoryWithoutUpdate().set(ABORTED_OR_ENDING, true); 168// } 169// } 170// super.abort(); 171// } 172 173 174 175 @Override 176 public void advance(float amount) { 177 super.advance(amount); 178 179 if (isSpawnedFleets()) { 180 if (isEnded() || isEnding() || isAborted() || isCurrent(RETURN_ACTION)) { 181 for (CampaignFleetAPI curr : getFleets()) { 182 //curr.getMemoryWithoutUpdate().set(ABORTED_OR_ENDING, true); 183 curr.getMemoryWithoutUpdate().set(BLOCKADING, false); 184 } 185 return; 186 } 187 188 if (isCurrent(PAYLOAD_ACTION)) { 189 for (CampaignFleetAPI curr : getFleets()) { 190 curr.getMemoryWithoutUpdate().set(BLOCKADING, true); 191// curr.getMemoryWithoutUpdate().set(ARMADA, true); 192// curr.getMemoryWithoutUpdate().set(SUPPLY, true); 193 } 194 } 195 } 196 } 197 198 @Override 199 protected void periodicUpdate() { 200 super.periodicUpdate(); 201 202 if (HostileActivityEventIntel.get() == null) { // ??? 203 abort(); 204 return; 205 } 206 207 FGAction action = getCurrentAction(); 208 if (action instanceof FGBlockadeAction) { 209 MutableStatWithTempMods stat = HostileActivityEventIntel.get().getNumFleetsStat(getTargetSystem()); 210 stat.addTemporaryModMult(1f, "PLBlockade", null, NUM_OTHER_FLEETS_MULT); 211 } 212 213 if (!isSpawnedFleets() || isSpawning()) return; 214 215 int armada = 0; 216 int supply = 0; 217 for (CampaignFleetAPI curr : getFleets()) { 218 if (curr.getMemoryWithoutUpdate().getBoolean(ARMADA)) { 219 armada++; 220 } 221 if (curr.getMemoryWithoutUpdate().getBoolean(SUPPLY)) { 222 supply++; 223 } 224 } 225 226 if (armada <= 0 || supply <= 0) { 227 abort(); 228 return; 229 } 230 231 if (action instanceof FGBlockadeAction) { 232 FGBlockadeAction blockade = (FGBlockadeAction) action; 233 if (blockade.getPrimary() != null) { 234 int supplyIndex = 0; 235 for (CampaignFleetAPI curr : getFleets()) { 236 if (blockade.getPrimary().getContainingLocation() != curr.getContainingLocation()) { 237 continue; 238 } 239 if (curr.getMemoryWithoutUpdate().getBoolean(SUPPLY)) { 240 Misc.setFlagWithReason(curr.getMemoryWithoutUpdate(), MemFlags.FLEET_BUSY, curr.getId(), true, -1f); 241 242 curr.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_FLEET_DO_NOT_GET_SIDETRACKED, true, 0.4f); 243 curr.clearAssignments(); 244 245 SectorEntityToken resupplyLoc = blockade.getPrimary(); 246 if (supplyIndex == 1) { 247 for (SectorEntityToken jp : blockade.getBlockadePoints()) { 248 if (jp != resupplyLoc) { 249 resupplyLoc = jp; 250 break; 251 } 252 } 253 } 254 curr.addAssignment(FleetAssignment.ORBIT_PASSIVE, resupplyLoc, 3f, 255 "standing by to provide resupply"); 256 supplyIndex++; 257 } else if (curr.getMemoryWithoutUpdate().getBoolean(ARMADA)) { 258 259 } else { 260 curr.getMemoryWithoutUpdate().set(MemFlags.WILL_HASSLE_PLAYER, true, 2f); 261 curr.getMemoryWithoutUpdate().set(MemFlags.HASSLE_TYPE, PerseanLeagueHostileActivityFactor.HASSLE_REASON, 2f); 262 } 263 } 264 } 265 } 266 } 267 268 269 270 @Override 271 protected void addPostAssessmentSection(TooltipMakerAPI info, float width, float height, float opad) { 272 273 info.addPara("The blockading forces are led by a Grand Armada and " 274 + "supported by a pair of supply fleets.", opad); 275// bullet(info); 276// info.addPara("Forcing the Grand Armada to withdraw will defeat the blockade", opad); 277// info.addPara("Forcing both supply fleets to withdraw will defeat the blockade", 0f); 278// unindent(info); 279 } 280 281 282 283 284} 285 286 287 288