001package com.fs.starfarer.api.impl.campaign.missions.academy; 002 003import java.awt.Color; 004import java.util.ArrayList; 005import java.util.Arrays; 006import java.util.List; 007import java.util.Map; 008 009import org.lwjgl.util.vector.Vector2f; 010 011import com.fs.starfarer.api.Global; 012import com.fs.starfarer.api.campaign.BattleAPI; 013import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason; 014import com.fs.starfarer.api.campaign.CampaignFleetAPI; 015import com.fs.starfarer.api.campaign.CargoAPI; 016import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType; 017import com.fs.starfarer.api.campaign.CargoStackAPI; 018import com.fs.starfarer.api.campaign.InteractionDialogAPI; 019import com.fs.starfarer.api.campaign.LocationAPI; 020import com.fs.starfarer.api.campaign.SectorEntityToken; 021import com.fs.starfarer.api.campaign.SpecialItemData; 022import com.fs.starfarer.api.campaign.StarSystemAPI; 023import com.fs.starfarer.api.campaign.TextPanelAPI; 024import com.fs.starfarer.api.campaign.econ.MarketAPI; 025import com.fs.starfarer.api.campaign.listeners.BaseFleetEventListener; 026import com.fs.starfarer.api.campaign.listeners.CurrentLocationChangedListener; 027import com.fs.starfarer.api.campaign.rules.MemoryAPI; 028import com.fs.starfarer.api.characters.PersonAPI; 029import com.fs.starfarer.api.impl.campaign.DerelictShipEntityPlugin.DerelictShipData; 030import com.fs.starfarer.api.impl.campaign.GateEntityPlugin; 031import com.fs.starfarer.api.impl.campaign.ids.Entities; 032import com.fs.starfarer.api.impl.campaign.ids.Factions; 033import com.fs.starfarer.api.impl.campaign.ids.FleetTypes; 034import com.fs.starfarer.api.impl.campaign.ids.Items; 035import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 036import com.fs.starfarer.api.impl.campaign.ids.People; 037import com.fs.starfarer.api.impl.campaign.ids.Ranks; 038import com.fs.starfarer.api.impl.campaign.ids.Tags; 039import com.fs.starfarer.api.impl.campaign.procgen.themes.BaseThemeGenerator; 040import com.fs.starfarer.api.impl.campaign.procgen.themes.SalvageSpecialAssigner.ShipRecoverySpecialCreator; 041import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity; 042import com.fs.starfarer.api.impl.campaign.rulecmd.missions.GateCMD; 043import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.PerShipData; 044import com.fs.starfarer.api.impl.campaign.rulecmd.salvage.special.ShipRecoverySpecial.ShipCondition; 045import com.fs.starfarer.api.ui.TooltipMakerAPI; 046import com.fs.starfarer.api.util.Misc; 047import com.fs.starfarer.api.util.Misc.Token; 048import com.fs.starfarer.api.util.WeightedRandomPicker; 049 050public class GAAtTheGates extends GABaseMission implements CurrentLocationChangedListener { 051 052 public static String SHOW_GATE_SCAN_COUNT = "show_gate_scan_count"; 053 054 public static enum Stage { 055 TALK_TO_COUREUSE, 056 TALK_TO_YARIBAY, 057 TALK_TO_HEGEMON, 058 MEET_DAUD, 059 DO_SCANS, 060 RETURN_WITH_DEAL_AND_SCANS, 061 FIRST_JANUS_EXPERIMENT, 062 FIRST_JANUS_RESULTS, 063 COUREUSE_MISSION, 064 TALK_TO_KANTA, 065 FINDING_LOKE, 066 RETURN_TO_KANTA, 067 GO_TO_MAGEC_GATE, 068 ZAL_TO_GALATIA, 069 COMPLETED, 070 } 071 072 protected PersonAPI baird; 073 protected PersonAPI coureuse; 074 protected PersonAPI gargoyle; 075 076 protected PersonAPI horus_yaribay; 077 protected PersonAPI siyavong; 078 protected MarketAPI kazeron; 079 //protected StarSystemAPI magec; 080 protected SectorEntityToken magecGate; 081 protected SectorEntityToken galatiaGate; 082 083 protected PersonAPI daud; 084 protected MarketAPI chicomoztoc; 085 086 protected PersonAPI kanta; 087 protected PersonAPI loke; 088 protected PersonAPI cotton; 089 protected PersonAPI zal; 090 protected PersonAPI kantasDenStationCommander; 091 protected MarketAPI kantasDen; 092 protected MarketAPI epiphany; 093 094 protected SectorEntityToken encounterGateHegemony; 095 protected CampaignFleetAPI encounterHegemonyFleet; 096 097 protected SectorEntityToken encounterGateLuddic; 098 protected CampaignFleetAPI encounterLuddicFleet; 099 100 protected SectorEntityToken encounterGateTT; 101 protected CampaignFleetAPI encounterTTFleet; 102 protected int ttScanCost; 103 protected int pirateScanCost; 104 protected int coureuseCredits; 105 106 protected SectorEntityToken encounterGatePirate; 107 protected CampaignFleetAPI encounterPirateFleet; 108 109 //protected SectorEntityToken encounterGateAlarm; 110 //protected CampaignFleetAPI encounterHegemonyFleet; 111 112 protected List<ScanEncounterVariation> scanEncounterVariations; 113 114 public static float SYSTEM_NO_GATE_ENCOUNTER_CHANCE = 0.2f; 115 public static float FACTION_GATE_ENCOUNTER_CHANCE = 0.5f; 116 117 public static enum ScanEncounterVariation { 118 HEGEMONY, 119 TRITACHYON, 120 LUDDIC, 121 PIRATE, 122 DERELICT, 123 JAMMER, 124 SCAVENGER, 125 PATHER, 126 ALARM, 127 } 128 129 public static float KANTA_RAID_DIFFICULTY = 1000f; 130 public static float COTTON_RAID_DIFFICULTY = 1000f; 131 132 @Override 133 protected boolean create(MarketAPI createdAt, boolean barEvent) { 134 // if already accepted by the player, abort 135 if (!setGlobalReference("$gaATG_ref", "$gaATG_inProgress")) { 136 return false; 137 } 138 139 baird = getImportantPerson(People.BAIRD); 140 if (baird == null) return false; 141 142 coureuse = getImportantPerson(People.COUREUSE); 143 if (coureuse == null) return false; 144 145 gargoyle = getImportantPerson(People.GARGOYLE); 146 if (gargoyle == null) return false; 147 148 horus_yaribay = getImportantPerson(People.HORUS_YARIBAY); 149 if (horus_yaribay == null) return false; 150 151 siyavong = getImportantPerson(People.SIYAVONG); 152 if (siyavong == null) return false; 153 154 daud = getImportantPerson(People.DAUD); 155 if (daud == null) return false; 156 157 kanta = getImportantPerson(People.KANTA); 158 if (kanta == null) return false; 159 160 loke = getImportantPerson(People.CLONE_LOKE); 161 if (loke == null) return false; 162 163 cotton = getImportantPerson(People.COTTON); 164 if (cotton == null) return false; 165 166 zal = getImportantPerson(People.ZAL); 167 if (zal == null) return false; 168 169 kazeron = Global.getSector().getEconomy().getMarket("kazeron"); 170 if (kazeron == null) return false; 171 172 chicomoztoc = Global.getSector().getEconomy().getMarket("chicomoztoc"); 173 if (chicomoztoc == null) return false; 174 175 kantasDen = Global.getSector().getEconomy().getMarket("kantas_den"); 176 if (kantasDen == null) return false; 177 178 kantasDenStationCommander = getPersonAtMarketPost(kantasDen, Ranks.POST_STATION_COMMANDER); 179 if (kantasDenStationCommander == null) return false; 180 181 epiphany = Global.getSector().getEconomy().getMarket("epiphany"); 182 if (epiphany == null) return false; 183 184 // find the Magec gate! 185 StarSystemAPI magec = kantasDen.getStarSystem(); 186 for (SectorEntityToken curr : magec.getCustomEntitiesWithTag(Tags.GATE)) { 187 //if (GateEntityPlugin.isScanned(curr)) continue; 188 //if (GateEntityPlugin.isActive(curr)) continue; 189 // plus whatever other checks are needed 190 magecGate = curr; 191 break; 192 } 193 if (magecGate == null) return false; 194 195 // and Galatia Gate 196 StarSystemAPI galatia = Global.getSector().getStarSystem("galatia"); 197 for (SectorEntityToken curr : galatia.getCustomEntitiesWithTag(Tags.GATE)) { 198 //if (GateEntityPlugin.isScanned(curr)) continue; 199 //if (GateEntityPlugin.isActive(curr)) continue; 200 // plus whatever other checks are needed 201 galatiaGate = curr; 202 break; 203 } 204 if (galatiaGate == null) return false; 205 206 setName("At The Gates"); 207 setRepFactionChangesNone(); 208 setRepPersonChangesNone(); 209 210 // set up our fleet spawns! 211 // Siyavong first 212 // Siyavong gets a patrol fleet to intercept player 213 //beginWithinHyperspaceRangeTrigger(kazeron, 1f, false, Stage.TALK_TO_HEGEMON); 214 //triggerCreateFleet(FleetSize.SMALL, FleetQuality.VERY_LOW, Factions.LUDDIC_PATH, FleetTypes.PATROL_SMALL, probeSystem); 215 216 beginStageTrigger(Stage.TALK_TO_HEGEMON); 217 triggerCreateFleet(FleetSize.MEDIUM, FleetQuality.HIGHER, Factions.PERSEAN, FleetTypes.PATROL_MEDIUM, kazeron.getStarSystem()); 218 triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER); 219 triggerMakeNonHostile(); 220 triggerMakeFleetIgnoreOtherFleetsExceptPlayer(); // don't go chasing others, please. 221 triggerFleetAllowLongPursuit(); 222 triggerSetFleetAlwaysPursue(); 223 triggerFleetMakeFaster(true, 1, true); 224 225 triggerPickLocationAroundEntity(kazeron.getStarSystem().getHyperspaceAnchor(), 250f); 226 triggerSpawnFleetAtPickedLocation("$gaATG_siyavongFleet", null); 227 //triggerSpawnFleetAtPickedLocation("$gaATG_pirateScanFleet", null); 228 229 //triggerPickLocationTowardsEntity(kazeron.getStarSystem().getHyperspaceAnchor(), 90f, getUnits(1f)); 230 triggerSetFleetMissionRef("$gaATG_ref"); // so they can be made unimportant 231 triggerOrderFleetInterceptPlayer(); 232 triggerOrderFleetEBurn(1f); 233 triggerFleetMakeImportant(null, Stage.TALK_TO_HEGEMON); 234 endTrigger(); 235 236 237 // For the big showdown w/ Kanta 238 List<SectorEntityToken> jumpPoints = magecGate.getStarSystem().getJumpPoints(); 239 for (SectorEntityToken point : jumpPoints) { 240 spawnKantaVengeanceFleetPirateScout(point); 241 spawnKantaVengeanceFleetPirateScout(point); // 2 scouts per. 242 spawnKantaVengeanceFleetPirateArmada(point); 243 spawnKantaVengeanceFleetMerc(point); 244 } 245 spawnKantaVengeanceFleetPirateArmada(kantasDen.getPrimaryEntity()); 246 247 //scanEncounterVariations = Arrays.asList(ScanEncounterVariation.values()); // NO. Bad list. 248 scanEncounterVariations = new ArrayList<ScanEncounterVariation>(Arrays.asList(ScanEncounterVariation.values())); 249 250 ttScanCost = genRoundNumber(20000, 30000); // bribe for TT scanning fleet 251 pirateScanCost = genRoundNumber(10000, 20000); // bribe for Pirate gate-blockers 252 coureuseCredits = genRoundNumber(10000, 20000); // Coureuse's pathetic savings 253 254 setStoryMission(); 255 256 setStartingStage(Stage.TALK_TO_COUREUSE); 257 addSuccessStages(Stage.COMPLETED); 258 259 makeImportant(coureuse, null, Stage.TALK_TO_COUREUSE); 260 makeImportant(horus_yaribay, null, Stage.TALK_TO_YARIBAY); 261 makeImportant(daud, null, Stage.TALK_TO_HEGEMON); 262 makeImportant(chicomoztoc, null, Stage.MEET_DAUD); 263 makeImportant(baird, null, Stage.RETURN_WITH_DEAL_AND_SCANS); 264 makeImportant(baird, null, Stage.FIRST_JANUS_RESULTS); 265 makeImportant(coureuse, null, Stage.COUREUSE_MISSION); 266 makeImportant(kantasDen, "$gaATG_talkToKanta", Stage.TALK_TO_KANTA); 267 makeImportant(epiphany, "$gaATG_findingLoke", Stage.FINDING_LOKE); 268 makeImportant(kanta.getMarket(), null, Stage.RETURN_TO_KANTA); 269 makeImportant(magecGate, null, Stage.GO_TO_MAGEC_GATE); 270 makeImportant(baird.getMarket(), null, Stage.ZAL_TO_GALATIA); 271 272 //setStageOnGlobalFlag(Stage.TALK_TO_COUREUSE, "$gaATG_goTalkToCoureuse"); 273 connectWithGlobalFlag(Stage.TALK_TO_COUREUSE, Stage.TALK_TO_YARIBAY, "$gaATG_goTalkToYaribay"); 274 connectWithGlobalFlag(Stage.TALK_TO_YARIBAY, Stage.TALK_TO_HEGEMON, "$gaATG_goTalkToDaud"); 275 connectWithGlobalFlag(Stage.TALK_TO_HEGEMON, Stage.MEET_DAUD, "$gaATG_goToDaudMeeting"); 276 connectWithGlobalFlag(Stage.MEET_DAUD, Stage.DO_SCANS, "$gaATG_gotDaudDeal"); 277 connectWithGlobalFlag(Stage.DO_SCANS, Stage.RETURN_WITH_DEAL_AND_SCANS, "$gaATG_scannedSixGates"); 278 279 setStageOnGlobalFlag(Stage.FIRST_JANUS_EXPERIMENT, "$gaATG_useJanusPrototype"); 280 setStageOnGlobalFlag(Stage.FIRST_JANUS_RESULTS, "$gaATG_firstJanusResults"); 281 setStageOnGlobalFlag(Stage.COUREUSE_MISSION, "$gaATG_getMissionFromCoureuse"); 282 setStageOnGlobalFlag(Stage.TALK_TO_KANTA, "$gaATG_gotKantaToken"); 283 setStageOnGlobalFlag(Stage.FINDING_LOKE, "$gaATG_findingLoke"); 284 setStageOnGlobalFlag(Stage.RETURN_TO_KANTA, "$gaATG_foundLoke"); 285 setStageOnGlobalFlag(Stage.GO_TO_MAGEC_GATE, "$gaATG_foundZal"); 286 287 connectWithEnteredLocation(Stage.GO_TO_MAGEC_GATE, Stage.ZAL_TO_GALATIA, galatia); 288 //setStageOnGlobalFlag(Stage.ZAL_TO_GALATIA, "$gaATG_zalToGalatia"); 289 setStageOnGlobalFlag(Stage.COMPLETED, "$gaATG_completed"); 290 291 // so they can decivilize etc but not before this and any other story missions using these are completed 292 beginStageTrigger(Stage.COMPLETED); 293 triggerSetGlobalMemoryValue("$gaATG_missionCompleted", true); 294 triggerMakeNonStoryCritical(kazeron, chicomoztoc, epiphany, siyavong.getMarket(), kanta.getMarket()); 295 endTrigger(); 296 297 return true; 298 } 299 @Override 300 protected boolean callAction(String action, String ruleId, InteractionDialogAPI dialog, List<Token> params, 301 Map<String, MemoryAPI> memoryMap) { 302 303 // $global.numGatesScanned tracks this too; maybe not ideal to dupe the var, but yolo -dgb 304 if ("scannedGateForCoureuse".equals(action)) { 305 sendUpdate(SHOW_GATE_SCAN_COUNT, dialog.getTextPanel()); 306 return true; 307 } 308 else if ("setGalatiaGateScanned".equals(action)) 309 { 310 galatiaGate.getMemoryWithoutUpdate().set(GateEntityPlugin.GATE_SCANNED, true); 311 GateCMD.notifyScanned(galatiaGate); 312 return true; 313 } 314 else if ("clearedHegemonyGate".equals(action)) { 315 encounterGateHegemony.getMemoryWithoutUpdate().unset("$GAATGhegemonyScanFleet"); 316 return true; 317 } 318 else if ("clearedHegemonyGateSendScans".equals(action)) { 319 encounterGateHegemony.getMemoryWithoutUpdate().set("$GAATGhegSendScan", true); 320 encounterGateHegemony.getMemoryWithoutUpdate().unset("$GAATGhegemonyScanFleet"); 321 encounterHegemonyFleet.getMemoryWithoutUpdate().unset("$youDoTheScan"); 322 encounterHegemonyFleet.getMemoryWithoutUpdate().set("$youDidTheScan", true); 323 return true; 324 } 325 else if ("sentHegemonyScan".equals(action)) { 326 encounterHegemonyFleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_IGNORE_PLAYER_COMMS, true); 327 return true; 328 } 329 else if ("clearedLuddicGate".equals(action)) { 330 encounterGateLuddic.getMemoryWithoutUpdate().unset("$GAATGluddicScanGate"); 331 return true; 332 } 333 else if ("luddicGateFleetMoveAway".equals(action)) { 334 encounterGateLuddic.getMemoryWithoutUpdate().unset("$GAATGluddicScanGate"); 335 encounterGateLuddic.getMemoryWithoutUpdate().set("$GAATGluddicPostScan", true); 336 encounterLuddicFleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_AVOID_PLAYER_SLOWLY, true); 337 encounterLuddicFleet.getMemoryWithoutUpdate().set(MemFlags.MEMORY_KEY_IGNORE_PLAYER_COMMS, true); 338 return true; 339 } 340 else if ("luddicGateFleetMoveBack".equals(action)) { 341 //encounterGateLuddic.getMemoryWithoutUpdate().unset("$GAATGluddicScanGate"); 342 encounterLuddicFleet.getMemoryWithoutUpdate().unset(MemFlags.MEMORY_KEY_AVOID_PLAYER_SLOWLY); 343 encounterLuddicFleet.getMemoryWithoutUpdate().unset(MemFlags.MEMORY_KEY_IGNORE_PLAYER_COMMS); 344 encounterLuddicFleet.getMemoryWithoutUpdate().set("$resumedVigil", true); 345 return true; 346 } 347 348 else if ("boughtTTscan".equals(action)) { 349 encounterGateTT.getMemoryWithoutUpdate().unset("$GAATGttScanGate"); 350 encounterGateTT.getMemoryWithoutUpdate().set(GateEntityPlugin.GATE_SCANNED, true); 351 GateCMD.notifyScanned(encounterGateTT); 352 sendUpdate(SHOW_GATE_SCAN_COUNT, dialog.getTextPanel()); 353 return true; 354 } 355 else if ("clearedTTGate".equals(action)) { 356 encounterGateTT.getMemoryWithoutUpdate().unset("$GAATGttScanGate"); 357 return true; 358 } 359 else if ("clearedPirateGate".equals(action)) { 360 encounterGatePirate.getMemoryWithoutUpdate().unset("$GAATGpirateScanGate"); 361 encounterPirateFleet.getMemoryWithoutUpdate().unset("$gaATG_pirateScanFleet"); 362 return true; 363 } 364 else if ("doZalEscape".equals(action)) { 365 Global.getSector().layInCourseFor(magecGate); 366 galatiaGate.getMemoryWithoutUpdate().set(GateEntityPlugin.GATE_SCANNED, true); 367 return true; 368 } 369 else if ("giveJanusDevice".equals(action)) { 370 CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo(); 371 cargo.addSpecial(new SpecialItemData(Items.JANUS, null), 1); 372 CargoStackAPI stack = Global.getFactory().createCargoStack(CargoItemType.SPECIAL, new SpecialItemData(Items.JANUS, null), null); 373 AddRemoveCommodity.addStackGainText(stack, dialog.getTextPanel()); 374 return true; 375 } 376 else if ("endMissionCleanup".equals(action)){ 377 378 epiphany.getMemoryWithoutUpdate().unset("$askedForKidnapperCotton"); 379 epiphany.getMemoryWithoutUpdate().unset("$offeredBribeForCotton"); 380 epiphany.getMemoryWithoutUpdate().unset("$setUpCottonMeeting"); 381 epiphany.getMemoryWithoutUpdate().unset("$askedBarCotton"); 382 epiphany.getMemoryWithoutUpdate().unset("$setUpCottonMeeting"); 383 384 //magecGate.getMemoryWithoutUpdate().unset("$visitedWithZal"); 385 return true; 386 } 387 else if ("zalCommHack".equals(action)){ 388 389 TextPanelAPI text = dialog.getTextPanel(); 390 text.setFontVictor(); 391 Color red = Misc.getNegativeHighlightColor(); 392 text.addParagraph("COMM FEED 0 INTERRUPTED \nCOMM FEED 1 INTERRUPTED", red); 393 //text.setFontSmallInsignia(); 394 text.setFontInsignia(); 395 return true; 396 } 397 else if ("zalMinesHack".equals(action)) 398 { 399 Global.getSoundPlayer().playSound("hit_heavy", 1, 1, Global.getSoundPlayer().getListenerPos(), new Vector2f()); 400 return true; 401 } 402 else if ("giveJanusDevice".equals(action)) 403 { 404 CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo(); 405 cargo.addSpecial(new SpecialItemData(Items.JANUS, null), 1); 406 CargoStackAPI stack = Global.getFactory().createCargoStack(CargoItemType.SPECIAL, new SpecialItemData(Items.JANUS, null), null); 407 AddRemoveCommodity.addStackGainText(stack, dialog.getTextPanel()); 408 return true; 409 } 410 //else if ("addYaribayContact".equals(action)) 411 //{ 412 // ContactIntel.addPotentialContact(horus_yaribay, kazeron, dialog.getTextPanel()); 413 // //setPersonIsPotentialContactOnSuccess(horus_yaribay, 1f); // probability = 1f, otherwise it's only a chance (default 0.25) 414 // return true; 415 //} 416 417 return false; 418 } 419 420 protected void updateInteractionDataImpl() { 421 set("$gaATG_stage", getCurrentStage()); 422 set("$gaATG_gatesScanned", GateEntityPlugin.getNumGatesScanned()); 423 set("$gaATG_ttScanCost", Misc.getWithDGS(ttScanCost)); 424 set("$gaATG_pirateScanCost", Misc.getWithDGS(pirateScanCost)); 425 set("$gaATG_coureuseCredits", Misc.getWithDGS(coureuseCredits)); 426 427 set("$gaATG_kantaRaidDifficulty", KANTA_RAID_DIFFICULTY); 428 set("$gaATG_cottonRaidDifficulty", COTTON_RAID_DIFFICULTY); 429 set("$kantasDenStationCommander", kantasDenStationCommander.getId()); // kantasDenStationCommander); 430 } 431 432 @Override 433 public void advance(float amount) { 434 super.advance(amount); 435 if ( currentStage == Stage.TALK_TO_COUREUSE || 436 currentStage == Stage.TALK_TO_YARIBAY || 437 currentStage == Stage.TALK_TO_HEGEMON || 438 currentStage == Stage.DO_SCANS) { 439 int scanned = GateEntityPlugin.getNumGatesScanned(); 440 if (scanned >= 6 && 441 !Global.getSector().getMemoryWithoutUpdate().contains("$gaATG_scannedSixGates")) { // failsafe; apparently possible to not have this be set? 442 Global.getSector().getMemoryWithoutUpdate().set("$gaATG_scannedSixGates", true); 443 checkStageChangesAndTriggers(null, null); 444 } 445 } 446 } 447 448 @Override 449 public void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height) { 450 451 452 453 float opad = 10f; 454 Color h = Misc.getHighlightColor(); 455 456 // Contact the High Hegemon 457 //if (currentStage == Stage.TALK_TO_COUREUSE || 458 if ( currentStage == Stage.TALK_TO_YARIBAY ) { 459 info.addPara("Contact Horus Yaribay to get envoy credentials so you can contact High Hegemon Daud.", opad); 460 //info.addImages(width, 128, opad, opad, horus_yaribay.getPortraitSprite(),horus_yaribay.getFaction().getCrest()); 461 addStandardMarketDesc("Gens Yaribay is based " + kazeron.getOnOrAt(), kazeron, info, opad); 462 } 463 else if (currentStage == Stage.TALK_TO_HEGEMON) 464 { 465 info.addPara("Set up a private meeting with High Hegemon Baikal Daud and get him to accept the deal with Provost Baird.", opad); 466 //info.addImages(width, 128, opad, opad, daud.getPortraitSprite(),daud.getFaction().getCrest()); 467 info.addPara("Optional: provide Daud with encrypted Yaribay comm codes.", opad); 468 addStandardMarketDesc("The High Hegemon's office is based " + chicomoztoc.getOnOrAt(), chicomoztoc, info, opad); 469 } 470 else if (currentStage == Stage.MEET_DAUD) 471 { 472 info.addPara("Meet with High Hegemon Baikal Daud on a shipyard orbiting Chicomoztoc.", opad); 473 //info.addImages(width, 128, opad, opad, daud.getPortraitSprite(),daud.getFaction().getCrest()); 474 info.addPara("Optional: provide Daud with encrypted Yaribay comm codes.", opad); 475 addStandardMarketDesc("The High Hegemon's office is based " + chicomoztoc.getOnOrAt(), chicomoztoc, info, opad); 476 } 477 else if (currentStage == Stage.RETURN_WITH_DEAL_AND_SCANS) 478 { 479 info.addPara("You've arranged a deal between High Hegemon Daud and Provost Baird which allows " 480 + "the Galatia Academy to resume overt research on Gate technology.",opad); 481 } 482 483 484 // Scan six Gates 485 if ( currentStage == Stage.TALK_TO_COUREUSE) 486 { 487 info.addPara("Get the Gate scanning instrument from Academician Coureuse.", opad); 488 } 489 else if ( currentStage == Stage.TALK_TO_COUREUSE || 490 currentStage == Stage.TALK_TO_YARIBAY || 491 currentStage == Stage.TALK_TO_HEGEMON || 492 currentStage == Stage.DO_SCANS && 493 GateEntityPlugin.getNumGatesScanned() < 6 ) 494 { 495 info.addPara("Scan six Gates with the instruments provided by Academician Coureuse.", opad); 496 info.addPara("%s Gates scanned", opad, Misc.getHighlightColor(), 497 "" + GateEntityPlugin.getNumGatesScanned() + " / 6"); 498 unindent(info); 499 //info.addImage(Global.getSettings().getSpriteName("illustrations", "dead_gate"), width, opad); 500 bullet(info); 501 } 502 503 // Everything else in the mission arc. 504 if (currentStage == Stage.RETURN_WITH_DEAL_AND_SCANS) 505 { 506 info.addPara("Return to the Galatia Academy with the six completed Gate scans.", opad); 507 } 508 else if (currentStage == Stage.FIRST_JANUS_EXPERIMENT) 509 { 510 info.addPara("Use the prototype Janus Device on a Gate in an uninhabited system outside of the " 511 + "Core worlds.", opad); 512 } 513 else if (currentStage == Stage.FIRST_JANUS_RESULTS) 514 { 515 info.addPara("Return to the Galatia Academy to report the results of the first Janus Prototype " 516 + "experiment.", opad); 517 } 518 else if (currentStage == Stage.COUREUSE_MISSION) 519 { 520 info.addPara("Contact Academician Scylla Coureuse about what she needs you to do.", opad); 521 } 522 else if (currentStage == Stage.TALK_TO_KANTA) 523 { 524 info.addPara("Use Gargoyle's token to arrange a meeting with Warlord Kanta in the Magec system - or find some other way to extract Zal.", opad); 525 } 526 else if (currentStage == Stage.FINDING_LOKE) 527 { 528 info.addPara("Find and extract the clone of Loke from the Pather kidnappers.", opad); 529 } 530 else if (currentStage == Stage.RETURN_TO_KANTA) 531 { 532 info.addPara("Return Clone Loke to Warlord Kanta.", opad); 533 //info.addImages(width, 128, opad, opad, kanta.getPortraitSprite(), kanta.getFaction().getCrest()); 534 } 535 else if (currentStage == Stage.GO_TO_MAGEC_GATE) 536 { 537 info.addPara("Go to the Magec Gate and jump to Galatia.", opad); 538 } 539 else if (currentStage == Stage.ZAL_TO_GALATIA) 540 { 541 info.addPara("Return to the Galatia Academy with Elissa Zal and the working Janus Device.", opad); 542 } 543 } 544 545 @Override 546 protected boolean shouldSendUpdateForStage(Object id) { 547 if (getCurrentStage() == Stage.DO_SCANS && GateEntityPlugin.getNumGatesScanned() >= 6) { 548 return false; // going straight to RETURN_WITH_DEAL_AND_SCANS 549 } 550 return super.shouldSendUpdateForStage(id); 551 } 552 @Override 553 public boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad) { 554 555 Color h = Misc.getHighlightColor(); 556 557 if (getListInfoParam() == SHOW_GATE_SCAN_COUNT) { 558// if (GateEntityPlugin.getNumGatesScanned() >= 6) 559// { 560// // We don't want to end up writing 7/6 if the player gets excitable about scanning before talking to Daud -dgb 561 // I kind of think we do - it looks confusing if they scan but the number doesn't go up 562 // and in most cases there's no notification, if it's over 6, anyway -am 563// info.addPara("%s Gates scanned", pad, tc, Misc.getHighlightColor(), "6 / 6"); 564// } 565// else 566// { 567 info.addPara("%s Gates scanned", pad, tc, Misc.getHighlightColor(), 568 "" + GateEntityPlugin.getNumGatesScanned() + " / 6"); 569// } 570 return true; 571 572 } 573 574 // Scanning equipment 575 // Do this first because the player should talk to Coureuse while still at the GA -dgb 576 if (currentStage == Stage.TALK_TO_COUREUSE) 577 { 578 info.addPara("Get the Gate scanning device from Scylla Coureuse", tc, pad); 579 pad = 0; // the padding passed in is just for before the first item 580 } 581 582 // High Hegemon contact 583 if (currentStage == Stage.TALK_TO_COUREUSE || 584 currentStage == Stage.TALK_TO_YARIBAY ) { 585 info.addPara("Contact Horus Yaribay on Kazeron to get envoy credentials", tc, pad); 586 587 pad = 0; 588 } 589 else if (currentStage == Stage.TALK_TO_HEGEMON) 590 { 591 info.addPara("Horus Yaribay has provided you with official envoy credentials to set up a private meeting with High " 592 + "Hegemon Baikal Daud", tc, pad); 593 //info.addPara("Optional: provide Daud with encrypted Yaribay comm codes.", opad); 594 //info.addPara("Use the gens Yaribay envoy credentials to set up a private meeting with High " 595 // + "Hegemon Baikal Daud. Get him to accept a new arrangement with Provost Baird.", opad); 596 pad = 0; 597 } 598 else if (currentStage == Stage.MEET_DAUD) 599 { 600 info.addPara("Meet with the High Hegemon in Chicomoztoc orbit and secure Baird's deal", tc, pad); 601 pad = 0; 602 } 603 else if (currentStage == Stage.RETURN_WITH_DEAL_AND_SCANS) 604 { 605 info.addPara("Return to Provost Baird at the Galatia Academy with news of the deal made with " 606 + "High Hegemon Daud", tc, pad); 607 pad = 0; 608 } 609 610 // ... Then scan six Gates; this appears below Yaribay/Daud stuff as it's the next objective -dgb 611 if ( ( currentStage == Stage.TALK_TO_YARIBAY || 612 currentStage == Stage.TALK_TO_HEGEMON || 613 currentStage == Stage.MEET_DAUD || 614 currentStage == Stage.DO_SCANS) 615 && GateEntityPlugin.getNumGatesScanned() < 6) 616 // Though this last point is implicit in the Stage, perhaps? Maybe not though, 617 // because you can scan all the gates while doing the Hegemon stuff. So keep this. -dgb 618 { 619 info.addPara("Scan six Gates with the instruments provided by Academician Coureuse", tc, pad); 620 pad = 0; 621 } 622 623 if (currentStage == Stage.RETURN_WITH_DEAL_AND_SCANS) 624 { 625 info.addPara("Return to the Galatia Academy with the six completed Gate scans", tc, pad); 626 } 627 else if (currentStage == Stage.FIRST_JANUS_EXPERIMENT) 628 { 629 info.addPara("Use the prototype Janus Device on a Gate in an uninhabited system outside of the " 630 + "Core worlds", tc, pad); 631 } 632 else if (currentStage == Stage.FIRST_JANUS_RESULTS) 633 { 634 info.addPara("Return to the Galatia Academy to report the results of the first Janus Prototype " 635 + "experiment", tc, pad); 636 } 637 else if (currentStage == Stage.COUREUSE_MISSION) 638 { 639 info.addPara("Contact Academician Scylla Coureuse about what she needs you to do", tc, pad); 640 } 641 else if (currentStage == Stage.TALK_TO_KANTA) 642 { 643 info.addPara("Use Gargoyle's token to arrange a meeting with Warlord Kanta in the Magec system - or find some other way to extract Zal", tc, pad); 644 } 645 else if (currentStage == Stage.FINDING_LOKE) 646 { 647 info.addPara("Find and extract the clone of Loke from the Pather kidnappers", tc, pad); 648 } 649 else if (currentStage == Stage.RETURN_TO_KANTA) 650 { 651 info.addPara("Return Clone Loke to Warlord Kanta", tc, pad); 652 } 653 else if (currentStage == Stage.GO_TO_MAGEC_GATE) 654 { 655 info.addPara("Go to the Magec Gate", tc, pad); 656 } 657 else if (currentStage == Stage.ZAL_TO_GALATIA) 658 { 659 info.addPara("Return to the Galatia Academy with Elissa Zal and the working Janus Device", tc, pad); 660 } 661 662 return false; 663 } 664 665 @Override 666 public String getBaseName() { 667 return "At The Gates"; 668 } 669 670 @Override 671 public String getPostfixForState() { 672 if (startingStage != null) { 673 return ""; 674 } 675 return super.getPostfixForState(); 676 } 677 678 679 @Override 680 public void acceptImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) { 681 super.acceptImpl(dialog, memoryMap); 682 Global.getSector().getListenerManager().addListener(this); 683 } 684 685 @Override 686 protected void notifyEnding() { 687 Global.getSector().getListenerManager().removeListener(this); 688 super.notifyEnding(); 689 } 690 691 // I guess either this doesn't need to be weighted, or I should integrate the weighted choice 692 // into this dang function. I'll do it ... later, maybe. -dgb, TODO 693 public ScanEncounterVariation pickGateEvent() { 694 WeightedRandomPicker<ScanEncounterVariation> picker = new WeightedRandomPicker<ScanEncounterVariation>(genRandom); 695 for (ScanEncounterVariation event : scanEncounterVariations) { 696 picker.add(event, 1f); 697 } 698 /*FactionData data = FACTION_DATA.get(factionId); 699 if (data != null) { 700 float w = Math.max(1f, data.events.length) / Math.max(1f, picker.getTotal()); 701 w *= SPECIFIC_FACTION_SUBJECT_EVENT_LIKELIHOOD; // faction-specific is more likely than generic, overall 702 for (String event : data.events) { 703 picker.add(event, w); 704 } 705 }*/ 706 return picker.pick(); 707 } 708 709 public static String CHECKED_FOR_ENCOUNTER = "$gaATG_checkedForEncounter"; 710 public void reportCurrentLocationChanged(LocationAPI prev, LocationAPI currLoc) { 711 if (getCurrentStage() == null) return; 712 713 // if in the wrong stage for gate encounters: return 714 if (((Enum)getCurrentStage()).ordinal() >= Stage.RETURN_WITH_DEAL_AND_SCANS.ordinal()) return; 715 if (((Enum)getCurrentStage()).ordinal() < Stage.TALK_TO_YARIBAY.ordinal()) return; 716 717 if(!(currLoc instanceof StarSystemAPI)) return; 718 719 // if no gate encounters remain, return. 720 if (scanEncounterVariations.isEmpty()) return; 721 722 StarSystemAPI system = (StarSystemAPI) currLoc; 723 if (system.getMemoryWithoutUpdate().getBoolean(CHECKED_FOR_ENCOUNTER)) return; 724 system.getMemoryWithoutUpdate().set(CHECKED_FOR_ENCOUNTER, true); 725 726 // We don't want the encounter fleet to get destroyed by pulsars or Remnants. 727 // Plus, this should make the Gate "interesting" enough already. 728 if (system.hasTag(Tags.THEME_UNSAFE)) return; 729 if(Misc.hasPulsar(system)) return; 730 731 // if the system is unsuitable - no gate, or gate is scanned: return 732 SectorEntityToken gate = null; 733 for (SectorEntityToken curr : system.getCustomEntitiesWithTag(Tags.GATE)) { 734 if (GateEntityPlugin.isScanned(curr)) continue; 735 if (GateEntityPlugin.isActive(curr)) continue; 736 // plus whatever other checks are needed 737 gate = curr; 738 break; 739 } 740 741 if (gate == null) return; 742 743 // Not every Gate has a cool story, right? 744 if (rollProbability(SYSTEM_NO_GATE_ENCOUNTER_CHANCE)) return; 745 746 // pick what type of encounter to do and spawn it 747 // also add a temporary flag to the system to not spawn *another* encounter here 748 749 ScanEncounterVariation chosenEncounter = null; 750 751 // testing. 752 //chosenEncounter = ScanEncounterVariation.HEGEMONY; 753 754 755 for (MarketAPI market : Global.getSector().getEconomy().getMarkets(system)) { 756 if (scanEncounterVariations.contains(ScanEncounterVariation.HEGEMONY) && 757 market.getFactionId().equals(Factions.HEGEMONY) && 758 rollProbability(FACTION_GATE_ENCOUNTER_CHANCE)) 759 { 760 chosenEncounter = ScanEncounterVariation.HEGEMONY; 761 break; 762 } 763 else if (scanEncounterVariations.contains(ScanEncounterVariation.TRITACHYON) && 764 market.getFactionId().equals(Factions.TRITACHYON) && 765 rollProbability(FACTION_GATE_ENCOUNTER_CHANCE)) 766 { 767 chosenEncounter = ScanEncounterVariation.TRITACHYON; 768 break; 769 } 770 else if (scanEncounterVariations.contains(ScanEncounterVariation.LUDDIC) && 771 market.getFactionId().equals(Factions.LUDDIC_CHURCH) && 772 rollProbability(FACTION_GATE_ENCOUNTER_CHANCE)) 773 { 774 chosenEncounter = ScanEncounterVariation.LUDDIC; 775 break; 776 } 777 else if (scanEncounterVariations.contains(ScanEncounterVariation.LUDDIC) && 778 market.getFactionId().equals(Factions.LUDDIC_CHURCH) && 779 rollProbability(FACTION_GATE_ENCOUNTER_CHANCE)) 780 { 781 chosenEncounter = ScanEncounterVariation.LUDDIC; 782 break; 783 } 784 else if (scanEncounterVariations.contains(ScanEncounterVariation.PIRATE) && 785 market.getFactionId().equals(Factions.PIRATES) && 786 rollProbability(FACTION_GATE_ENCOUNTER_CHANCE)) 787 { 788 chosenEncounter = ScanEncounterVariation.PIRATE; 789 break; 790 } 791 } 792 793 // Choose randomly from the remaining options if none was picked. 794 if( chosenEncounter == null) 795 { 796 chosenEncounter = pickGateEvent(); 797 } 798 799 if( chosenEncounter == null) return; // Uh oh? 800 801 scanEncounterVariations.remove(chosenEncounter); 802/* 803 System.out.println("scan chosen is " + chosenEncounter.toString()); 804 System.out.println("remaining encounters:"); 805 for (ScanEncounterVariation v : scanEncounterVariations) { 806 System.out.println(v.toString()); 807 } 808 */ 809 810 // if (system.getId().equals("corvus")) { 811 // // an alternate way to figure out what's appropriate where 812 // hasHegemony = true; 813 // } 814 815 // of note: since this happens when the player enters a system - i.e. not during mission creation, 816 // but while the actual mission is in progress - it's also ok to do things here directly in code 817 // instead of having to use triggers. The above commented out block is using a trigger (+ runTriggers()) 818 // just because it's an easy way to spawn a fleet. 819 820 if(chosenEncounter == ScanEncounterVariation.DERELICT) 821 { 822 DerelictShipData params = new DerelictShipData(new PerShipData("apogee_Balanced", ShipCondition.BATTERED, 0f), false); 823 824 SectorEntityToken ship = BaseThemeGenerator.addSalvageEntity(system, Entities.WRECK, Factions.NEUTRAL, params); 825 ship.setDiscoverable(true); 826 827 ship.setCircularOrbit(gate, (float) Math.random() * 360f, 40f, 20f); 828 829 // Eh, maybe some base chance of recoverable vs. not? -dgb 830 ShipRecoverySpecialCreator creator = new ShipRecoverySpecialCreator(null, 0, 0, false, null, null); 831 Misc.setSalvageSpecial(ship, creator.createSpecial(ship, null)); 832 833 ship.getMemoryWithoutUpdate().set("$gateScanDerelict", true); 834 } 835 else if(chosenEncounter == ScanEncounterVariation.HEGEMONY) 836 { 837 //gate.addTag("GAATGhegemonyScanFleet"); 838 839 //if (hasHegemony) { // whatever conditions are appropriate 840 beginStageTrigger(getCurrentStage()); 841 triggerCreateFleet(FleetSize.MEDIUM, FleetQuality.HIGHER, Factions.HEGEMONY, FleetTypes.PATROL_MEDIUM, gate); 842 triggerMakeNonHostile(); // should it be hostile? 843 //triggerMakeHostileAndAggressive(); 844 //triggerMakeLowRepImpact(); 845 //triggerFleetPatherNoDefaultTithe(); 846 847 triggerPickLocationAroundEntity(gate, 100f); 848 triggerSpawnFleetAtPickedLocation("$gaATG_hegScanFleet", null); 849 850 triggerFleetSetPatrolActionText("scanning"); 851 triggerFleetSetTravelActionText("repositioning"); 852 triggerOrderFleetPatrol(true, gate); 853 triggerMakeFleetIgnoreOtherFleets(); // don't go chasing pirates, please. 854 triggerMakeFleetGoAwayAfterDefeat(); 855 triggerFleetSetPatrolLeashRange(100f); 856 857 //triggerMakeFleetIgnoredByOtherFleets(); 858 859 //triggerPickSetLocation(gate.getContainingLocation(), gate.getLocation()); // fleet should appear AT the gate. 860 //triggerPickLocationAtClosestToPlayerJumpPoint(probeSystem); 861 //triggerSetEntityToPickedJumpPoint(); 862 //triggerPickLocationTowardsEntity(gate, 15f, getUnits(1.0f)); 863 //triggerFleetMakeImportant(null, Stage.FOLLOW_THE_EXPERIMENTS); 864 //triggerOrderFleetInterceptPlayer(); 865 866 triggerSetFleetMissionRef("$gaATG_ref"); // so they can be made unimportant 867 triggerFleetAddDefeatTrigger("GAATGhegGateScanFleetDefeated"); 868 triggerFleetSetName("Special Task Force"); 869 endTrigger(); 870 871 // this'll execute the trigger added above immediately 872 List<CampaignFleetAPI> fleets = runStageTriggersReturnFleets(getCurrentStage()); 873 if (fleets.isEmpty()) 874 { 875 return; // something went wrong spawning a fleet, unlikely but technically possible 876 } 877 final CampaignFleetAPI fleet = fleets.get(0); 878 879 fleet.addEventListener(new BaseFleetEventListener() { 880 @Override 881 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) { 882 if (reason == FleetDespawnReason.DESTROYED_BY_BATTLE) { 883 // Cool! So now the fleet no longer blocks the Gate, and the Gate is no longer blocked. -dgb 884 fleet.getMemoryWithoutUpdate().unset("$gaATG_hegScanFleet"); 885 encounterGateHegemony.getMemoryWithoutUpdate().unset("$GAATGhegemonyScanFleet"); 886 } 887 } 888 889 @Override 890 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) { 891 if (battle.wasFleetDefeated(fleet, primaryWinner)) { 892 fleet.getMemoryWithoutUpdate().unset("$gaATG_hegScanFleet"); 893 encounterGateHegemony.getMemoryWithoutUpdate().unset("$GAATGhegemonyScanFleet"); 894 } 895 } 896 }); 897 898 encounterHegemonyFleet = fleets.get(0); 899 900 // Let's do this after the potential abort, just to be safe. 901 // If anything above fails, then the Gate isn't blocked -dgb. 902 encounterGateHegemony = gate; 903 setFlag(gate, "$GAATGhegemonyScanFleet", true); 904 } 905 else if(chosenEncounter == ScanEncounterVariation.JAMMER) 906 { 907 setFlag(gate, "$GAATGscanJammer", true); 908 } 909 else if(chosenEncounter == ScanEncounterVariation.ALARM) 910 { 911 setFlag(gate, "$GAATGscanAlarm", true); 912 } 913 else if(chosenEncounter == ScanEncounterVariation.LUDDIC) 914 { 915 beginStageTrigger(getCurrentStage()); 916 triggerCreateFleet(FleetSize.MEDIUM, FleetQuality.LOWER, Factions.LUDDIC_CHURCH, FleetTypes.TRADE_LINER, gate); 917 triggerMakeNonHostile(); 918 //triggerMakeLowRepImpact(); // Yeah uh, blowing away a civilian fleet would look bad. 919 triggerSetFleetSizeFraction(0.5f); 920 triggerSetFleetComposition(2f, 1f, 1f, 10f, 1f); 921 triggerPickLocationAroundEntity(gate, 50f); 922 triggerSpawnFleetAtPickedLocation("$gaATG_luddicScanFleet", null); 923 triggerFleetSetTravelActionText("holding vigil"); 924 triggerFleetSetPatrolActionText("holding vigil"); 925 triggerOrderFleetPatrol(true, gate); 926 triggerMakeFleetIgnoreOtherFleets(); // don't go chasing pirates, please. 927 triggerMakeFleetGoAwayAfterDefeat(); 928 triggerFleetSetPatrolLeashRange(30f); // very close. 929 //triggerMakeFleetIgnoredByOtherFleets(); 930 triggerSetFleetMissionRef("$gaATG_ref"); // so they can be made unimportant 931 triggerFleetAddDefeatTrigger("GAATGluddicScanFleetDefeated"); 932 triggerFleetSetName("Sacred Vigil Flotilla"); 933 endTrigger(); 934 935 // this'll execute the trigger added above immediately 936 List<CampaignFleetAPI> fleets = runStageTriggersReturnFleets(getCurrentStage()); 937 if (fleets.isEmpty()) 938 { 939 return; // something went wrong spawning a fleet, unlikely but technically possible 940 } 941 final CampaignFleetAPI fleet = fleets.get(0); 942 encounterLuddicFleet = fleet; 943 encounterGateLuddic = gate; 944 setFlag(gate, "$GAATGluddicScanGate", true); 945 946 fleet.addEventListener(new BaseFleetEventListener() { 947 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) { 948 if (reason == FleetDespawnReason.DESTROYED_BY_BATTLE) { 949 fleet.getMemoryWithoutUpdate().unset("$gaATG_luddicScanFleet"); 950 encounterGateLuddic.getMemoryWithoutUpdate().unset("$GAATGluddicScanGate"); 951 } 952 } 953 954 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) { 955 if (battle.wasFleetDefeated(fleet, primaryWinner)) { 956 fleet.getMemoryWithoutUpdate().unset("$gaATG_luddicScanFleet"); 957 encounterGateLuddic.getMemoryWithoutUpdate().unset("$GAATGluddicScanGate"); 958 } 959 } 960 }); 961 } 962 else if(chosenEncounter == ScanEncounterVariation.PATHER) 963 { 964 // Just hostile Pathers. Maybe they should share their feelings/motivations with the player. 965 beginStageTrigger(getCurrentStage()); 966 triggerCreateFleet(FleetSize.MEDIUM, FleetQuality.HIGHER, Factions.LUDDIC_PATH, FleetTypes.MERC_PRIVATEER, gate); 967 triggerFleetPatherNoDefaultTithe(); // They want to kill you. 968 triggerPickLocationAroundEntity(gate, 200f); 969 triggerSpawnFleetAtPickedLocation("$gaATG_patherScanFleet", null); 970 triggerOrderFleetPatrol(true, gate); 971 //triggerFleetSetPatrolActionText("guarding"); 972 //triggerMakeFleetIgnoreOtherFleets(); // actually yes, chase the player. Or anyone else, who cares. 973 triggerMakeFleetGoAwayAfterDefeat(); 974 triggerFleetSetPatrolLeashRange(60f); // very close. 975 triggerSetFleetMissionRef("$gaATG_ref"); // so they can be made unimportant 976 //triggerFleetAddDefeatTrigger("GAATGpatherScanFleetDefeated"); // don't need it - they won't block the gate except via hostility. 977 triggerFleetSetName("Ambush Fleet"); 978 endTrigger(); 979 } 980 else if(chosenEncounter == ScanEncounterVariation.PIRATE) 981 { 982 beginStageTrigger(getCurrentStage()); 983 triggerCreateFleet(FleetSize.MEDIUM, FleetQuality.VERY_HIGH, Factions.PIRATES, FleetTypes.PATROL_LARGE, gate); 984 triggerMakeNonHostile(); // Will go hostile after yelling at you, or if you don't talk to them. 985 triggerMakeLowRepImpact(); // Yeah uh, blowing away a civilian fleet would look bad. 986 triggerPickLocationAroundEntity(gate, 250f); 987 triggerSpawnFleetAtPickedLocation("$gaATG_pirateScanFleet", null); 988 triggerFleetSetPatrolActionText("loitering"); 989 triggerFleetSetTravelActionText("maneuvering"); 990 triggerOrderFleetPatrol(true, gate); 991 992 triggerFleetSetPatrolLeashRange(250f); // fairly close. 993 triggerSetFleetMissionRef("$gaATG_ref"); // so they can be made unimportant 994 triggerFleetAddDefeatTrigger("GAATGpirateScanFleetDefeated"); 995 triggerMakeFleetGoAwayAfterDefeat(); 996 endTrigger(); 997 998 // this'll execute the trigger added above immediately 999 List<CampaignFleetAPI> fleets = runStageTriggersReturnFleets(getCurrentStage()); 1000 if (fleets.isEmpty()) 1001 { 1002 return; // something went wrong spawning a fleet, unlikely but technically possible 1003 } 1004 final CampaignFleetAPI fleet = fleets.get(0); 1005 1006 fleet.addEventListener(new BaseFleetEventListener() { 1007 @Override 1008 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) { 1009 if (reason == FleetDespawnReason.DESTROYED_BY_BATTLE) { 1010 fleet.getMemoryWithoutUpdate().unset("$gaATG_pirateScanFleet"); 1011 encounterGatePirate.getMemoryWithoutUpdate().unset("$GAATGpirateScanGate"); 1012 } 1013 } 1014 @Override 1015 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) { 1016 // if our pirates get defeated in any battle... 1017 if (battle.wasFleetDefeated(fleet, primaryWinner)) { 1018 fleet.getMemoryWithoutUpdate().unset("$gaATG_pirateScanFleet"); 1019 encounterGatePirate.getMemoryWithoutUpdate().unset("$GAATGpirateScanGate"); 1020 } 1021 } 1022 }); 1023 1024 fleet.addEventListener(new BaseFleetEventListener() { 1025 1026 }); 1027 1028 encounterGatePirate = gate; 1029 encounterPirateFleet = fleet; 1030 setFlag(gate, "$GAATGpirateScanGate", true); 1031 } 1032 else if(chosenEncounter == ScanEncounterVariation.SCAVENGER) 1033 { 1034 // Just a scavenger suspiciously nearby. Doesn't block the gate. 1035 beginStageTrigger(getCurrentStage()); 1036 triggerCreateFleet(FleetSize.SMALL, FleetQuality.DEFAULT, Factions.INDEPENDENT, FleetTypes.SCAVENGER_MEDIUM, gate); 1037 triggerMakeNonHostile(); 1038 triggerMakeLowRepImpact(); 1039 triggerPickLocationAroundEntity(gate, 100f); 1040 triggerSpawnFleetAtPickedLocation("$gaATG_scavScanFleet", null); 1041 triggerFleetSetPatrolActionText("observing"); 1042 triggerFleetSetTravelActionText("observing"); 1043 triggerOrderFleetPatrol(true, gate); 1044 triggerMakeFleetIgnoreOtherFleets(); // don't go chasing pirates, please. 1045 triggerFleetSetPatrolLeashRange(250f); 1046 triggerMakeFleetIgnoredByOtherFleets(); // would be disappointing if they just got blasted. 1047 triggerSetFleetMissionRef("$gaATG_ref"); // so they can be made unimportant 1048 //triggerFleetAddDefeatTrigger("GAATGluddicScanFleetDefeated"); n/a 1049 triggerFleetSetName("Suspect Scavenger"); 1050 triggerMakeFleetGoAwayAfterDefeat(); 1051 endTrigger(); 1052 1053 List<CampaignFleetAPI> fleets = runStageTriggersReturnFleets(getCurrentStage()); 1054 if (fleets.isEmpty()) return; 1055 } 1056 else if(chosenEncounter == ScanEncounterVariation.TRITACHYON) 1057 { 1058 beginStageTrigger(getCurrentStage()); 1059 triggerCreateFleet(FleetSize.LARGE, FleetQuality.HIGHER, Factions.TRITACHYON, FleetTypes.PATROL_LARGE, gate); 1060 triggerMakeNonHostile(); 1061 //triggerMakeHostileAndAggressive(); 1062 //triggerMakeLowRepImpact(); 1063 //triggerFleetPatherNoDefaultTithe(); 1064 1065 triggerPickLocationAroundEntity(gate, 100f); 1066 triggerSpawnFleetAtPickedLocation("$gaATG_ttScanFleet", null); 1067 triggerFleetSetTravelActionText("repositioning"); 1068 triggerFleetSetPatrolActionText("scanning"); 1069 triggerOrderFleetPatrol(true, gate); 1070 triggerMakeFleetIgnoreOtherFleets(); // don't go chasing pirates, please. 1071 triggerMakeFleetGoAwayAfterDefeat(); 1072 triggerFleetSetPatrolLeashRange(100f); 1073 1074 //triggerMakeFleetIgnoredByOtherFleets(); 1075 1076 triggerSetFleetMissionRef("$gaATG_ref"); // so they can be made unimportant 1077 triggerFleetAddDefeatTrigger("GAATGttGateScanFleetDefeated"); 1078 triggerFleetSetName("Special Projects Detachment"); 1079 endTrigger(); 1080 1081 // this'll execute the trigger added above immediately 1082 List<CampaignFleetAPI> fleets = runStageTriggersReturnFleets(getCurrentStage()); 1083 if (fleets.isEmpty()) 1084 { 1085 return; // something went wrong spawning a fleet, unlikely but technically possible 1086 } 1087 final CampaignFleetAPI fleet = fleets.get(0); 1088 1089 fleet.addEventListener(new BaseFleetEventListener() { 1090 @Override 1091 public void reportFleetDespawnedToListener(CampaignFleetAPI fleet, FleetDespawnReason reason, Object param) { 1092 if (reason == FleetDespawnReason.DESTROYED_BY_BATTLE) { 1093 // Cool! So now the fleet no longer blocks the Gate, and the Gate is no longer blocked. -dgb 1094 fleet.getMemoryWithoutUpdate().unset("$gaATG_ttScanFleet"); 1095 encounterGateTT.getMemoryWithoutUpdate().unset("$GAATGttScanGate"); 1096 } 1097 } 1098 1099 @Override 1100 public void reportBattleOccurred(CampaignFleetAPI fleet, CampaignFleetAPI primaryWinner, BattleAPI battle) { 1101 if (battle.wasFleetDefeated(fleet, primaryWinner)) { 1102 fleet.getMemoryWithoutUpdate().unset("$gaATG_ttScanFleet"); 1103 encounterGateTT.getMemoryWithoutUpdate().unset("$GAATGttScanGate"); 1104 } 1105 } 1106 }); 1107 1108 fleet.addEventListener(new BaseFleetEventListener() { 1109 1110 }); 1111 1112 //encounterHegemonyFleet = fleets.get(0); 1113 1114 encounterGateTT = gate; 1115 encounterTTFleet = fleet; // unused? 1116 setFlag(gate, "$GAATGttScanGate", true); 1117 } 1118 else 1119 { 1120 // none chosen? I guess don't do anything, huh. How'd you get here, anyway? 1121 return; 1122 } 1123 } 1124 1125 protected void spawnKantaVengeanceFleetPirateArmada(SectorEntityToken spawnPoint) { 1126 beginWithinHyperspaceRangeTrigger(magecGate, 3f, false, Stage.GO_TO_MAGEC_GATE); 1127 triggerCreateFleet(FleetSize.HUGE, FleetQuality.HIGHER, Factions.PIRATES, FleetTypes.PATROL_LARGE, spawnPoint); 1128 triggerSetFleetFaction(Factions.PIRATES); 1129 triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER); 1130 triggerAutoAdjustFleetStrengthMajor(); 1131 triggerMakeHostileAndAggressive(); 1132 triggerMakeNoRepImpact(); 1133 triggerFleetAllowLongPursuit(); 1134 triggerSetFleetAlwaysPursue(); 1135 triggerPickLocationAroundEntity(spawnPoint, 100f); 1136 triggerSetFleetMissionRef("$gaATG_ref"); 1137 triggerSpawnFleetAtPickedLocation("$gaATG_kantaVengeanceFleet", null); 1138 triggerOrderFleetInterceptPlayer(); 1139 endTrigger(); 1140 } 1141 1142 protected void spawnKantaVengeanceFleetPirateScout(SectorEntityToken spawnPoint) { 1143 beginWithinHyperspaceRangeTrigger(magecGate, 3f, false, Stage.GO_TO_MAGEC_GATE); 1144 triggerCreateFleet(FleetSize.MEDIUM, FleetQuality.HIGHER, Factions.PIRATES, FleetTypes.PATROL_SMALL, spawnPoint); 1145 triggerSetFleetFaction(Factions.PIRATES); 1146 triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.DEFAULT); 1147 triggerAutoAdjustFleetStrengthMajor(); 1148 triggerMakeHostileAndAggressive(); 1149 triggerMakeNoRepImpact(); 1150 triggerFleetAllowLongPursuit(); 1151 triggerSetFleetAlwaysPursue(); 1152 triggerFleetMakeFaster(true, 0, true); 1153 triggerPickLocationAroundEntity(spawnPoint, 100f); 1154 triggerSetFleetMissionRef("$gaATG_ref"); 1155 triggerSpawnFleetAtPickedLocation("$gaATG_kantaVengeanceFleet", null); 1156 triggerOrderFleetInterceptPlayer(); 1157 endTrigger(); 1158 } 1159 1160 protected void spawnKantaVengeanceFleetMerc(SectorEntityToken spawnPoint) { 1161 beginWithinHyperspaceRangeTrigger(magecGate, 3f, false, Stage.GO_TO_MAGEC_GATE); 1162 triggerCreateFleet(FleetSize.LARGE, FleetQuality.VERY_HIGH, Factions.MERCENARY, FleetTypes.MERC_ARMADA, spawnPoint); 1163 triggerSetFleetFaction(Factions.PIRATES); 1164 triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER); 1165 triggerAutoAdjustFleetStrengthMajor(); 1166 triggerMakeHostileAndAggressive(); 1167 triggerMakeNoRepImpact(); 1168 triggerFleetAllowLongPursuit(); 1169 triggerSetFleetAlwaysPursue(); 1170 triggerFleetMakeFaster(true, 1, true); 1171 triggerPickLocationAroundEntity(spawnPoint, 100f); 1172 triggerSetFleetMissionRef("$gaATG_ref"); 1173 triggerSpawnFleetAtPickedLocation("$gaATG_kantaVengeanceFleet", null); 1174 triggerOrderFleetInterceptPlayer(); 1175 endTrigger(); 1176 } 1177} 1178 1179 1180 1181 1182