001package com.fs.starfarer.api.impl.campaign.missions.academy; 002 003import java.awt.Color; 004import java.util.List; 005import java.util.Map; 006 007import com.fs.starfarer.api.Global; 008import com.fs.starfarer.api.campaign.CampaignFleetAPI; 009import com.fs.starfarer.api.campaign.InteractionDialogAPI; 010import com.fs.starfarer.api.campaign.NascentGravityWellAPI; 011import com.fs.starfarer.api.campaign.PlanetAPI; 012import com.fs.starfarer.api.campaign.SectorEntityToken; 013import com.fs.starfarer.api.campaign.StarSystemAPI; 014import com.fs.starfarer.api.campaign.econ.MarketAPI; 015import com.fs.starfarer.api.campaign.rules.MemoryAPI; 016import com.fs.starfarer.api.characters.PersonAPI; 017import com.fs.starfarer.api.impl.campaign.ids.Entities; 018import com.fs.starfarer.api.impl.campaign.ids.Factions; 019import com.fs.starfarer.api.impl.campaign.ids.FleetTypes; 020import com.fs.starfarer.api.impl.campaign.ids.People; 021import com.fs.starfarer.api.impl.campaign.ids.Ranks; 022import com.fs.starfarer.api.impl.campaign.ids.Skills; 023import com.fs.starfarer.api.impl.campaign.ids.Tags; 024import com.fs.starfarer.api.impl.campaign.missions.hub.ReqMode; 025import com.fs.starfarer.api.impl.campaign.world.TTBlackSite; 026import com.fs.starfarer.api.ui.TooltipMakerAPI; 027import com.fs.starfarer.api.util.Misc; 028import com.fs.starfarer.api.util.Misc.Token; 029 030public class GAProjectZiggurat extends GABaseMission { //implements ShipRecoveryListener { 031 032 public static enum Stage { 033 GET_KELISE_LEAD, 034 SELL_BLACKMAIL_MATERIAL, 035 SOLD_BLACKMAIL_MATERIAL, 036 TALK_TO_CALLISTO, 037 GO_TO_RELAY_SYSTEM, 038 GO_TO_NASCENT_WELL, 039 INVESTIGATE_SITE, 040 //RECOVER_ZIGGURAT, 041 RETURN_TO_ACADEMY, 042 COMPLETED, 043 } 044 045 //public static String RECOVERED_ZIGGURAT = "$gaPZ_recoveredZiggurat"; 046 public static String SCANNED_ZIGGURAT = "$gaPZ_scannedZiggurat"; 047 048 protected PersonAPI callisto; 049 protected MarketAPI culann; 050 protected MarketAPI donn; 051 protected PersonAPI baird; 052 protected PersonAPI arroyo; 053 protected PersonAPI gargoyle; 054 protected PersonAPI culannAdmin; 055 protected NascentGravityWellAPI well; 056 protected StarSystemAPI relaySystem; 057 protected StarSystemAPI alphaSite; 058 protected CampaignFleetAPI zigFleet; 059 protected SectorEntityToken relay; 060 protected PlanetAPI baseRuins; 061 062 protected boolean pointAtArroyo = false; 063 protected boolean pointAtCulannAdmin = false; 064 protected int culannBribe; 065 protected int paymentForCommFakes; 066 protected int paymentForCommFakesHigh; 067 protected int rkTithe; 068 069 private SectorEntityToken hamatsu; 070 071 072 @Override 073 protected boolean create(MarketAPI createdAt, boolean barEvent) { 074 // if already accepted by the player, abort 075 if (!setGlobalReference("$gaPZ_ref", "$gaPZ_inProgress")) { 076 return false; 077 } 078 079 baird = getImportantPerson(People.BAIRD); 080 if (baird == null) return false; 081 082 callisto = getImportantPerson(People.IBRAHIM); 083 if (callisto == null) return false; 084 085 gargoyle = getImportantPerson(People.GARGOYLE); 086 if (gargoyle == null) return false; 087 088 culann = Global.getSector().getEconomy().getMarket("culann"); 089 if (culann == null) return false; 090 091 donn = Global.getSector().getEconomy().getMarket("donn"); 092 if (donn == null) return false; 093 094 arroyo = getImportantPerson(People.ARROYO); 095 if (arroyo == null) return false; 096 097 culannAdmin = getPersonAtMarketPost(culann, Ranks.POST_ADMINISTRATOR); 098 if (culannAdmin == null) return false; 099 100 well = (NascentGravityWellAPI) Global.getSector().getMemoryWithoutUpdate().get(TTBlackSite.NASCENT_WELL_KEY); 101 if (well == null || !well.isAlive()) return false; 102 103 float dir = Misc.getAngleInDegrees(culann.getLocationInHyperspace(), well.getLocationInHyperspace()); 104 105 requireSystemTags(ReqMode.NOT_ANY, Tags.THEME_UNSAFE, Tags.THEME_CORE, Tags.SYSTEM_ALREADY_USED_FOR_STORY); 106 preferSystemInDirectionFrom(culann.getLocationInHyperspace(), dir, 30f); 107 preferSystemWithinRangeOf(culann.getLocationInHyperspace(), 15f, 30f); 108 preferSystemWithinRangeOf(culann.getLocationInHyperspace(), 15f, 40f); 109 preferSystemUnexplored(); 110 preferSystemNotPulsar(); 111 requirePlanetNotGasGiant(); 112 requirePlanetNotStar(); 113 preferPlanetUnsurveyed(); 114 baseRuins = pickPlanet(true); 115 if (baseRuins == null) return false; 116 117 relaySystem = baseRuins.getStarSystem(); 118 if (relaySystem == null) return false; 119 120 relay = spawnEntity(Entities.GENERIC_PROBE, new LocData(EntityLocationType.HIDDEN, null, relaySystem)); 121 if (relay == null) return false; 122 relay.setCustomDescriptionId("gaPZ_relay"); 123 124 125 alphaSite = (StarSystemAPI) well.getTarget().getContainingLocation(); 126 127 for (CampaignFleetAPI fleet : alphaSite.getFleets()) { 128 if (fleet.getMemoryWithoutUpdate().getBoolean("$ziggurat")) { 129 zigFleet = fleet; 130 break; 131 } 132 } 133 if (zigFleet == null) return false; 134 135 requireSystemIs(alphaSite); 136 requireEntityMemoryFlags("$hamatsu"); 137 // hamatsu could be null if player salvaged it after dipping into alpha site then backing out 138 hamatsu = pickEntity(); 139 140 141 paymentForCommFakes = genRoundNumber(10000, 15000); 142 paymentForCommFakesHigh = genRoundNumber(40000, 60000); 143 culannBribe = genRoundNumber(20000, 30000); 144 rkTithe = genRoundNumber(80000, 120000); 145 146 setStartingStage(Stage.GET_KELISE_LEAD); 147 addSuccessStages(Stage.COMPLETED); 148 149 setStoryMission(); 150 151 connectWithGlobalFlag(Stage.GET_KELISE_LEAD, Stage.SELL_BLACKMAIL_MATERIAL, "$gaPZ_sellBlackmail"); 152 connectWithGlobalFlag(Stage.SELL_BLACKMAIL_MATERIAL, Stage.SOLD_BLACKMAIL_MATERIAL, "$gaPZ_soldBlackmail"); 153 connectWithGlobalFlag(Stage.GET_KELISE_LEAD, Stage.TALK_TO_CALLISTO, "$gaPZ_talkToCallisto"); 154 connectWithGlobalFlag(Stage.SOLD_BLACKMAIL_MATERIAL, Stage.TALK_TO_CALLISTO, "$gaPZ_talkToCallisto"); 155 connectWithGlobalFlag(Stage.TALK_TO_CALLISTO, Stage.GO_TO_RELAY_SYSTEM, "$gaPZ_goToRelaySystem"); 156 connectWithGlobalFlag(Stage.GO_TO_RELAY_SYSTEM, Stage.GO_TO_NASCENT_WELL, "$gaPZ_goToWell"); 157 setStageOnEnteredLocation(Stage.INVESTIGATE_SITE, alphaSite); 158 //setStageOnGlobalFlag(Stage.RECOVER_ZIGGURAT, "$gaPZ_recoverZig"); 159 setStageOnGlobalFlag(Stage.RETURN_TO_ACADEMY, SCANNED_ZIGGURAT); 160 setStageOnGlobalFlag(Stage.COMPLETED, "$gaPZ_completed"); 161 162 //makeImportant(baird, null, Stage.TALK_TO_BAIRD); 163 //setStageOnMemoryFlag(Stage.COMPLETED, baird.getMarket(), "$gaPZ_completed"); 164 165 makeImportant(culann, null, Stage.GET_KELISE_LEAD); 166 makeImportant(donn, null, Stage.SELL_BLACKMAIL_MATERIAL); 167 makeImportant(arroyo, null, Stage.SOLD_BLACKMAIL_MATERIAL); 168 makeImportant(callisto, null, Stage.TALK_TO_CALLISTO); 169 makeImportant(relay, "$gaPZ_relayImportant", Stage.GO_TO_RELAY_SYSTEM); 170 makeImportant(well, null, Stage.GO_TO_NASCENT_WELL); 171 makeImportant(zigFleet, "$gaPZ_ziggurat", Stage.INVESTIGATE_SITE); 172 makeImportant(baird, "$gaPZ_returnHere", Stage.RETURN_TO_ACADEMY); 173 174 setFlag(relay, "$gaPZ_relay", false); 175 setFlag(culannAdmin, "$gaPZ_culannAdmin", false, Stage.GET_KELISE_LEAD); 176 setFlag(baseRuins, "$gaPZ_baseRuins", false, Stage.GO_TO_RELAY_SYSTEM, Stage.GO_TO_NASCENT_WELL); 177 178 179 // Rogue Luddic Knight encounter as the player nears Arcadia 180 beginWithinHyperspaceRangeTrigger(callisto.getMarket(), 3f, true, Stage.TALK_TO_CALLISTO); 181 triggerCreateFleet(FleetSize.VERY_LARGE, FleetQuality.HIGHER, Factions.LUDDIC_CHURCH, FleetTypes.PATROL_LARGE, culann.getLocationInHyperspace()); 182 triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER); 183 triggerMakeHostileAndAggressive(); 184 triggerMakeLowRepImpact(); 185 triggerFleetMakeFaster(true, 2, true); 186 triggerSetFleetAlwaysPursue(); 187 triggerPickLocationTowardsEntity(callisto.getMarket().getStarSystem().getHyperspaceAnchor(), 30f, getUnits(1.5f)); 188 triggerSpawnFleetAtPickedLocation("$gaPZ_rogueKnight", null); 189 triggerOrderFleetInterceptPlayer(); 190 triggerOrderFleetEBurn(1f); 191 triggerFleetMakeImportant(null, Stage.TALK_TO_CALLISTO); 192 endTrigger(); 193 194 // TriTach merc, phase fleet 195 beginEnteredLocationTrigger(relaySystem, Stage.GO_TO_RELAY_SYSTEM); 196 triggerCreateFleet(FleetSize.LARGE, FleetQuality.SMOD_2, Factions.MERCENARY, FleetTypes.MERC_BOUNTY_HUNTER, culann.getLocationInHyperspace()); 197 triggerSetFleetOfficers(OfficerNum.MORE, OfficerQuality.HIGHER); 198 triggerFleetAddCommanderSkill(Skills.PHASE_CORPS, 1); 199 triggerSetFleetFaction(Factions.TRITACHYON); 200 triggerMakeHostileAndAggressive(); 201 triggerMakeLowRepImpact(); 202 triggerSetFleetDoctrineComp(0, 0, 5); 203 triggerFleetMakeFaster(true, 1, true); 204 triggerPickLocationAtInSystemJumpPoint(relaySystem); 205 triggerSpawnFleetAtPickedLocation("$gaPZ_ttMerc", null); 206 triggerOrderFleetInterceptPlayer(); 207 triggerFleetMakeImportant(null, Stage.GO_TO_RELAY_SYSTEM); 208 endTrigger(); 209 210 211 beginStageTrigger(Stage.COMPLETED); 212// triggerSetGlobalMemoryValueAfterDelay(genDelay(2f), "$gaPZ_missionCompleted", true); 213// triggerSetGlobalMemoryValueAfterDelay(genDelay(2f), SCANNED_ZIGGURAT, true); 214 triggerSetGlobalMemoryValue("$gaPZ_missionCompleted", true); 215 triggerSetGlobalMemoryValue(SCANNED_ZIGGURAT, true); 216 triggerMakeNonStoryCritical(culann, donn, callisto.getMarket(), arroyo.getMarket(), gargoyle.getMarket()); 217 endTrigger(); 218 219 return true; 220 } 221 222 protected boolean callAction(String action, String ruleId, InteractionDialogAPI dialog, List<Token> params, 223 Map<String, MemoryAPI> memoryMap) { 224 225 if ("makeArroyoImportant".equals(action)) { 226 if (!pointAtArroyo) { 227 makeImportant(arroyo, null, Stage.GET_KELISE_LEAD); 228 makePrimaryObjective(arroyo); 229 makeUnimportant(culann); 230 makeUnimportant(culannAdmin); 231 pointAtArroyo = true; 232 } 233 return true; 234 } else if ("makeCulannAdminImportant".equals(action)) { 235 if (!pointAtCulannAdmin) { 236 makeImportant(culannAdmin, null, Stage.GET_KELISE_LEAD); 237 makePrimaryObjective(culannAdmin); 238 makeUnimportant(arroyo); 239 pointAtCulannAdmin = true; 240 } 241 return true; 242 } 243 return false; 244 } 245 246 @Override 247 protected void notifyEnded() { 248 super.notifyEnded(); 249 250 Global.getSector().getMemoryWithoutUpdate().unset("$gaPZ_pointedToCulannAdmin"); 251 } 252 253 protected void updateInteractionDataImpl() { 254 set("$gaPZ_stage", getCurrentStage()); 255 set("$gaPZ_culannBribe", Misc.getWithDGS(culannBribe)); 256 set("$gaPZ_paymentForCommFakes", Misc.getWithDGS(paymentForCommFakes)); 257 set("$gaPZ_paymentForCommFakesHigh", Misc.getWithDGS(paymentForCommFakesHigh)); 258 set("$gaPZ_rkTithe", Misc.getWithDGS(rkTithe)); 259 set("$gaPZ_relaySystem", relaySystem.getNameWithNoType()); 260 } 261 262 @Override 263 public void addDescriptionForNonEndStage(TooltipMakerAPI info, float width, float height) { 264 float opad = 10f; 265 Color h = Misc.getHighlightColor(); 266 if (currentStage == Stage.GET_KELISE_LEAD || 267 currentStage == Stage.SELL_BLACKMAIL_MATERIAL || 268 currentStage == Stage.GO_TO_RELAY_SYSTEM || 269 currentStage == Stage.TALK_TO_CALLISTO || 270 currentStage == Stage.SOLD_BLACKMAIL_MATERIAL) { 271 info.addPara("Get a lead on the whereabouts of Kelise Astraia, who is associated with " 272 + "a secret Tri-Tachyon research base called \"Alpha Site\".", opad); 273 } 274 if (currentStage == Stage.GET_KELISE_LEAD) { 275 addStandardMarketDesc("She was formerly employed as a weapons engineer " + culann.getOnOrAt(), 276 culann, info, opad); 277 if (pointAtArroyo) { 278 info.addPara("You've talked to Gargoyle, who advised you to talk to Rayan Arroyo, " 279 + "\"a Tri-Tach goon from top to bottom\", who is likely to have the right connections " 280 + "to help with the investigation.", opad); 281 addStandardMarketDesc("Arroyo is located " + arroyo.getMarket().getOnOrAt(), arroyo.getMarket(), info, opad); 282 } 283 if (pointAtCulannAdmin) { 284 info.addPara("You've learned that the administrator of Culann Starforge will have access to " 285 + "personnel records that may shed light on Kelise's whereabouts.", opad); 286 addStandardMarketDesc("", culannAdmin.getMarket(), info, opad); 287 } 288 } else if (currentStage == Stage.SELL_BLACKMAIL_MATERIAL) { 289 info.addPara("Rayan Arroyo has agreed to help locate her, in exchange for a favor - selling bad " 290 + "comm fakes to any reasonably highly placed pirate leader, which would serve " 291 + "his ends as part of a disinformation campaign.", opad); 292 addStandardMarketDesc("A reasonable place to find such a pirate would be " + 293 donn.getOnOrAt(), donn, info, opad); 294 } else if (currentStage == Stage.SOLD_BLACKMAIL_MATERIAL) { 295 info.addPara("You've sold the blackmail materials to a pirate leader, in exchange for which Arroyo " 296 + "has agreed to help you find Kelise Astraia.", opad); 297 info.addPara(getGoTalkToPersonText(arroyo) + ".", opad); 298 } else if (currentStage == Stage.TALK_TO_CALLISTO) { 299 info.addPara("You've learned that Kelise chartered - and paid for unknown special modifications to - " 300 + "the ISS Hamatsu, a Venture-class starship, before flying it out of the system. The ship's owner is one " + 301 callisto.getNameString() + ". She may have more information.", opad); 302 info.addPara(getGoTalkToPersonText(callisto) + ".", opad); 303 } else if (currentStage == Stage.GO_TO_RELAY_SYSTEM) { 304 info.addPara("You've learned that the flight plan of the ISS Hamatsu - the ship chartered by Kelise Astraia - " 305 + "led to the " + relaySystem.getNameWithLowercaseTypeShort() + ".", opad); 306 } else if (currentStage == Stage.GO_TO_NASCENT_WELL) { 307 info.addPara("You've found a hidden relay in the " + relaySystem.getNameWithLowercaseTypeShort() + ", " 308 + "that was likely used for communications with \"Alpha Site\". " 309 + "Investigate the hyperspace coordinates that the relay was transmitting to.", opad); 310 311 if (well.isInCurrentLocation() && Misc.getDistanceToPlayerLY(well) < 0.2f) { 312 info.addPara("Use %s to traverse the nascent gravity well located at the coordinates.", 313 opad, Misc.getHighlightColor(), "Transverse Jump"); 314 } 315 316 } else if (currentStage == Stage.INVESTIGATE_SITE) { 317 info.addPara("Learn what Tri-Tachyon was doing at Alpha Site.", opad); 318 info.addPara("Optional: look for the ISS Hamatsu and, if found, return it " 319 + "to " + callisto.getNameString() + ".", opad); 320// addStandardMarketDesc("Optional: look for the ISS Hamatsu and, if found, return it " 321// + "to " + callisto.getNameString() + " on", callisto.getMarket(), info, opad); 322 info.addPara("Optional: locate Kelise Astraia.", opad); 323// } else if (currentStage == Stage.RECOVER_ZIGGURAT) { 324// info.addPara("Recover the Ziggurat-class phase vessel, which was apparently developed in " 325// + "secret by Tri-Tachyon at Alpha Site.", opad); 326 } else if (currentStage == Stage.RETURN_TO_ACADEMY) { 327 info.addPara("Return to the Galatia Academy with the scan data and report your findings to Provost " + 328 getPerson().getNameString() + ".", opad); 329 } 330 } 331 332 @Override 333 public boolean addNextStepText(TooltipMakerAPI info, Color tc, float pad) { 334 Color h = Misc.getHighlightColor(); 335 if (currentStage == Stage.GET_KELISE_LEAD) { 336 info.addPara("Get a lead on the whereabouts of Kelise Astraia", tc, pad); 337 return true; 338 } else if (currentStage == Stage.SELL_BLACKMAIL_MATERIAL) { 339 info.addPara("Sell Arroyo's comm fakes to any highly-placed pirate", tc, pad); 340 return true; 341 } else if (currentStage == Stage.SOLD_BLACKMAIL_MATERIAL) { 342 info.addPara(getGoTalkToPersonText(arroyo), tc, pad); 343 return true; 344 } else if (currentStage == Stage.TALK_TO_CALLISTO) { 345 info.addPara(getGoTalkToPersonText(callisto), tc, pad); 346 return true; 347 } else if (currentStage == Stage.GO_TO_RELAY_SYSTEM) { 348 info.addPara(getGoToSystemTextShort(relaySystem), tc, pad); 349 return true; 350 } else if (currentStage == Stage.GO_TO_NASCENT_WELL) { 351 info.addPara("Investigate hyperspace area the relay was transmitting to", tc, pad); 352 return true; 353 } else if (currentStage == Stage.INVESTIGATE_SITE) { 354 info.addPara("Investigate Alpha Site", tc, pad); 355 return true; 356// } else if (currentStage == Stage.RECOVER_ZIGGURAT) { 357// info.addPara("Recover the Ziggurat-class phase vessel", tc, pad); 358// return true; 359 } else if (currentStage == Stage.RETURN_TO_ACADEMY) { 360 info.addPara("Return to the Galatia Academy and report to Provost Baird", tc, pad); 361 return true; 362 } 363 return false; 364 } 365 366 @Override 367 public String getBaseName() { 368 return "Project Ziggurat"; 369 } 370 371 @Override 372 public String getPostfixForState() { 373 if (startingStage != null) { 374 return ""; 375 } 376 return super.getPostfixForState(); 377 } 378 379 @Override 380 public void setCurrentStage(Object next, InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) { 381 super.setCurrentStage(next, dialog, memoryMap); 382 if (next == Stage.RETURN_TO_ACADEMY) { 383 // "At The Gates" is offered in response to this variable being set. 384 // It can be set either by scanning the Ziggurat without doing this mission, OR 385 // by finishing this mission. 386 // What we want to avoid is a scenario when this variable remains set before the mission is finished 387 // and the player returns to the GA and is potentially offered At The Gates before PZ is completed. 388 Global.getSector().getMemoryWithoutUpdate().unset(SCANNED_ZIGGURAT); 389 } else if (next == Stage.GO_TO_RELAY_SYSTEM) { 390 // just talked to Callisto 391 if (hamatsu != null) { 392 Misc.makeImportant(hamatsu, getReason()); 393 } 394 } 395 } 396 397// @Override 398// public void acceptImpl(InteractionDialogAPI dialog, Map<String, MemoryAPI> memoryMap) { 399// super.acceptImpl(dialog, memoryMap); 400// Global.getSector().getListenerManager().addListener(this); 401// } 402// 403// public void reportShipsRecovered(List<FleetMemberAPI> ships, InteractionDialogAPI dialog) { 404// if (!(dialog instanceof RuleBasedInteractionDialogPluginImpl)) return; 405// 406// for (FleetMemberAPI member : ships) { 407// if (member.getHullId().equals("ziggurat")) { 408// Global.getSector().getListenerManager().removeListener(this); 409// Global.getSector().getMemoryWithoutUpdate().set(RECOVERED_ZIGGURAT, true, 0); 410// checkStageChangesAndTriggers(dialog, ((RuleBasedInteractionDialogPluginImpl)dialog).getMemoryMap()); 411// Global.getSector().getMemoryWithoutUpdate().unset(RECOVERED_ZIGGURAT); 412// } 413// } 414// } 415 416 417} 418 419 420 421 422