001package com.fs.starfarer.api.impl.campaign.procgen; 002 003import java.util.ArrayList; 004import java.util.LinkedHashMap; 005import java.util.List; 006import java.util.Map; 007import java.util.Random; 008 009import java.awt.Color; 010 011import org.lwjgl.util.vector.Vector2f; 012 013import com.fs.starfarer.api.Global; 014import com.fs.starfarer.api.campaign.CampaignClockAPI; 015import com.fs.starfarer.api.campaign.CampaignFleetAPI; 016import com.fs.starfarer.api.campaign.FactionAPI; 017import com.fs.starfarer.api.campaign.InteractionDialogAPI; 018import com.fs.starfarer.api.campaign.InteractionDialogPlugin; 019import com.fs.starfarer.api.campaign.LocationAPI; 020import com.fs.starfarer.api.campaign.OptionPanelAPI; 021import com.fs.starfarer.api.campaign.PlanetAPI; 022import com.fs.starfarer.api.campaign.SectorEntityToken; 023import com.fs.starfarer.api.campaign.StarSystemAPI; 024import com.fs.starfarer.api.campaign.TextPanelAPI; 025import com.fs.starfarer.api.campaign.VisualPanelAPI; 026import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin; 027import com.fs.starfarer.api.campaign.econ.Industry; 028import com.fs.starfarer.api.campaign.econ.MarketAPI; 029import com.fs.starfarer.api.campaign.rules.MemoryAPI; 030import com.fs.starfarer.api.characters.MutableCharacterStatsAPI; 031import com.fs.starfarer.api.characters.PersonAPI; 032import com.fs.starfarer.api.combat.EngagementResultAPI; 033import com.fs.starfarer.api.combat.ShipAPI.HullSize; 034import com.fs.starfarer.api.combat.ShipHullSpecAPI; 035import com.fs.starfarer.api.combat.WeaponAPI.AIHints; 036import com.fs.starfarer.api.impl.campaign.AbyssalLightEntityPlugin.AbyssalLightParams; 037import com.fs.starfarer.api.impl.campaign.DebugFlags; 038import com.fs.starfarer.api.impl.campaign.eventide.DuelDialogDelegate; 039import com.fs.starfarer.api.impl.campaign.eventide.DuelPanel; 040import com.fs.starfarer.api.impl.campaign.ids.Entities; 041import com.fs.starfarer.api.impl.campaign.ids.Factions; 042import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 043import com.fs.starfarer.api.impl.campaign.ids.Tags; 044import com.fs.starfarer.api.impl.campaign.intel.PromoteOfficerIntel; 045import com.fs.starfarer.api.impl.campaign.intel.bases.PirateBaseIntel; 046import com.fs.starfarer.api.impl.campaign.intel.events.HostileActivityEventIntel; 047import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTScanFactor; 048import com.fs.starfarer.api.impl.campaign.intel.events.ht.HyperspaceTopographyEventIntel; 049import com.fs.starfarer.api.impl.campaign.intel.inspection.HegemonyInspectionManager; 050import com.fs.starfarer.api.impl.campaign.intel.misc.LuddicShrineIntel; 051import com.fs.starfarer.api.impl.campaign.intel.punitive.PunitiveExpeditionManager; 052import com.fs.starfarer.api.impl.campaign.intel.punitive.PunitiveExpeditionManager.PunExData; 053import com.fs.starfarer.api.impl.campaign.plog.PLEntry; 054import com.fs.starfarer.api.impl.campaign.plog.PLIntel; 055import com.fs.starfarer.api.impl.campaign.plog.PlaythroughLog; 056import com.fs.starfarer.api.impl.campaign.population.CoreImmigrationPluginImpl; 057import com.fs.starfarer.api.loading.FighterWingSpecAPI; 058import com.fs.starfarer.api.loading.WeaponSpecAPI; 059import com.fs.starfarer.api.util.Misc; 060 061public class EventTestPluginImpl implements InteractionDialogPlugin { 062 063 protected static enum OptionId { 064 INIT, 065 PIRATE_RAID, 066 PUNITIVE_EXPEDITION, 067 INSPECTION, 068 PICK_STRENGTH, 069 PRINT_LOG, 070 TOPOGRAPHY_POINTS, 071 HAEI_POINTS, 072 ADD_LOG_INTEL, 073 INCREASE_COLONY_SIZE, 074 FINISH_CONSTRUCTION, 075 FIGHT, 076 TUTORIAL, 077 LEAVE, 078 } 079 080 protected InteractionDialogAPI dialog; 081 protected TextPanelAPI textPanel; 082 protected OptionPanelAPI options; 083 protected VisualPanelAPI visual; 084 085 protected CampaignFleetAPI playerFleet; 086 protected PlanetAPI planet; 087 088 protected PunExData punExData = null; 089 protected boolean sendInspection = false; 090 091 protected static final Color HIGHLIGHT_COLOR = Global.getSettings().getColor("buttonShortcut"); 092 093 public void init(InteractionDialogAPI dialog) { 094 this.dialog = dialog; 095 096 textPanel = dialog.getTextPanel(); 097 options = dialog.getOptionPanel(); 098 visual = dialog.getVisualPanel(); 099 100 playerFleet = Global.getSector().getPlayerFleet(); 101 planet = (PlanetAPI) dialog.getInteractionTarget(); 102 103 visual.setVisualFade(0.25f, 0.25f); 104 105 //visual.showImageVisual(planet.getCustomInteractionDialogImageVisual()); 106 107 visual.showLargePlanet(Global.getSector().getEntityById("mazalot")); 108 109 dialog.setOptionOnEscape("Leave", OptionId.LEAVE); 110 optionSelected(null, OptionId.INIT); 111 } 112 113 public Map<String, MemoryAPI> getMemoryMap() { 114 return null; 115 } 116 117 public void backFromEngagement(EngagementResultAPI result) { 118 // no combat here, so this won't get called 119 } 120 121 122 public void optionSelected(String text, Object optionData) { 123 if (optionData == null) return; 124 125 if (optionData instanceof Integer) { 126 DebugFlags.FAST_RAIDS = true; 127 Integer str = (Integer) optionData; 128 if (punExData != null) { 129 PunitiveExpeditionManager.getInstance().createExpedition(punExData, str); 130 } else if (sendInspection) { 131 HegemonyInspectionManager.getInstance().createInspection(str); 132 } 133 optionSelected(null, OptionId.LEAVE); 134 return; 135 } 136 137 if (optionData instanceof PunExData) { 138 punExData = (PunExData) optionData; 139 optionSelected(null, OptionId.PICK_STRENGTH); 140 return; 141 } 142 143 OptionId option = (OptionId) optionData; 144 145 if (text != null) { 146 //textPanel.addParagraph(text, Global.getSettings().getColor("buttonText")); 147 dialog.addOptionSelectedText(option); 148 //textPanel.addParagraph(""); 149 } 150 151 switch (option) { 152 case INIT: 153 createInitialOptions(); 154 155 156 PersonAPI player = Global.getSector().getPlayerPerson(); 157 MutableCharacterStatsAPI stats = player.getStats(); 158// stats.addXP((long) (6000f * (float) Math.random() + 100f), textPanel, true); 159// stats.spendStoryPoints(2, true, textPanel, false, 1f, null); 160 161 break; 162 case TUTORIAL: 163 final DuelPanel duelPanel = DuelPanel.createTutorial(true, "soe_ambience"); 164 dialog.showCustomVisualDialog(1024, 700, new DuelDialogDelegate(null, duelPanel, dialog, null, true)); 165 break; 166 case FIGHT: 167 final DuelPanel duelPanel2 = DuelPanel.createDefault(true, true, "soe_ambience"); 168 dialog.showCustomVisualDialog(1024, 700, new DuelDialogDelegate("music_soe_fight", duelPanel2, dialog, null, true)); 169 170 //Global.getSector().getIntelManager().addIntel(new TestFleetGroupIntel()); 171 172 //new PerseanLeagueBlockade(params, blockadeParams) 173 174// new GensHannanMachinations(dialog); 175 176// dialog.showCustomVisualDialog(1024, 700, new CustomVisualDialogDelegate() { 177// public CustomUIPanelPlugin getCustomPanelPlugin() { 178// return duelPanel2; 179// } 180// public void init(CustomPanelAPI panel, DialogCallbacks callbacks) { 181// duelPanel2.init(panel, callbacks, dialog); 182// } 183// public float getNoiseAlpha() { 184// return 0; 185// } 186// public void advance(float amount) { 187// 188// } 189// public void reportDismissed(int option) { 190// } 191// }); 192 //dialog.hideTextPanel(); 193 break; 194 case PIRATE_RAID: 195 MarketAPI market = getNearestMarket(false); 196 PirateBaseIntel base = findPirateBase(); 197 if (base != null && market != null && market.getStarSystem() != null) { 198 base.startRaid(market.getStarSystem(), 500f); 199 base.makeKnown(textPanel); 200 //print("Attempted to start raid; likely succeeded, see if there's new intel."); 201 optionSelected(null, OptionId.LEAVE); 202 } 203 //addText("") 204 break; 205 case INCREASE_COLONY_SIZE: 206 market = getNearestMarket(false); 207 if (market != null) { 208 int was = market.getSize(); 209 CoreImmigrationPluginImpl plugin = new CoreImmigrationPluginImpl(market); 210 plugin.increaseMarketSize(); 211 textPanel.addPara("Size of " + market.getName() + " increased from " + was + " to " + market.getSize()); 212 } 213 break; 214 case FINISH_CONSTRUCTION: 215 market = getNearestMarket(false); 216 if (market != null) { 217 for (Industry curr : new ArrayList<Industry>(market.getIndustries())) { 218 if (curr.isBuilding()) { 219 curr.finishBuildingOrUpgrading(); 220 textPanel.addPara("Finished building or upgrading " + curr.getCurrentName()); 221 } 222 } 223 } 224 break; 225 case PUNITIVE_EXPEDITION: 226 options.clearOptions(); 227 for (PunExData data : PunitiveExpeditionManager.getInstance().getData().values()) { 228 if (!PunitiveExpeditionManager.getInstance().getExpeditionReasons(data).isEmpty()) { 229 options.addOption("Punitive expedition: " + data.faction.getDisplayName(), data); 230 } 231 } 232 options.addOption("Leave", OptionId.LEAVE, null); 233 break; 234 case INSPECTION: 235 sendInspection = true; 236 optionSelected(null, OptionId.PICK_STRENGTH); 237 break; 238 case PICK_STRENGTH: 239 textPanel.addPara("Select strength"); 240 options.clearOptions(); 241 options.addOption("100", 100); 242 options.addOption("200", 200); 243 options.addOption("300", 300); 244 options.addOption("400", 400); 245 options.addOption("500", 500); 246 options.addOption("600", 600); 247 options.addOption("800", 800); 248 options.addOption("1000", 1000); 249 options.addOption("Leave", OptionId.LEAVE, null); 250 break; 251 case TOPOGRAPHY_POINTS: 252 HyperspaceTopographyEventIntel.addFactorCreateIfNecessary( 253 new HTScanFactor("Dev mode point increase", 50), dialog); 254 break; 255 case HAEI_POINTS: 256 if (HostileActivityEventIntel.get() != null) { 257 HostileActivityEventIntel intel = HostileActivityEventIntel.get(); 258 intel.setRandom(new Random()); 259 int p = intel.getProgress(); 260 if (p < 500 || p == 599) p = 500; 261 else if (p < 550) p = 550; 262 else p = 599; 263 intel.setProgress(p); 264 textPanel.addPara("Progress set to " + p); 265 } 266 //HostileActivityEventIntel.get().addFactor(new BaseOneTimeFactor(50), dialog); 267 break; 268 case PRINT_LOG: 269 270 271 for (int i = 0; i < 10; i++) { 272 Vector2f loc = Misc.getPointWithinRadius(playerFleet.getLocation(), 10000f); 273 //Vector2f loc = Misc.getPointWithinRadius(playerFleet.getLocation(), 2000f); 274 if (Misc.getAbyssalDepth(loc) >= 1f) { 275 AbyssalLightParams params = new AbyssalLightParams(); 276 SectorEntityToken e2 = Global.getSector().getHyperspace().addCustomEntity(Misc.genUID(), null, Entities.ABYSSAL_LIGHT, Factions.NEUTRAL, params); 277 278 if ((float) Math.random() > 0.5f) { 279 params.color = new Color(225,200,255,255); 280 //params.color = new Color(255,200,200,255); 281 e2.addTag(Tags.DWELLER_LIGHT); 282 long seed = Misc.random.nextLong(); 283 e2.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SEED, seed); 284 } 285 e2.setLocation(loc.x, loc.y); 286 } 287 } 288 289// SectorEntityToken e2 = Global.getSector().getHyperspace().addCustomEntity(Misc.genUID(), null, Entities.ABYSSAL_LIGHT, Factions.NEUTRAL); 290// e2.setLocation(playerFleet.getLocation().x, playerFleet.getLocation().y); 291 292 293 //new GensHannanMachinations(dialog); 294 295// if (Global.getSector().getCurrentLocation() instanceof StarSystemAPI) { 296// new HostileActivityIntel((StarSystemAPI) Global.getSector().getCurrentLocation()); 297// } 298 299 //BaseEventIntel event = new BaseEventIntel(); 300 //HyperspaceTopographyEventIntel event = new HyperspaceTopographyEventIntel(dialog.getTextPanel(), true); 301 //Global.getSector().addScript(this); 302 //Global.getSector().getIntelManager().addIntel(event); 303 //Global.getSector().getListenerManager().addListener(this); 304 305 checkFactionUseOfStuff(); 306 307 textPanel.addPara("Player log:"); 308 String log = ""; 309 for (PLEntry e : PlaythroughLog.getInstance().getEntries()) { 310 CampaignClockAPI clock = Global.getSector().getClock().createClock(e.getTimestamp()); 311 log += clock.getShortDate() + " " + e.getText() + "\n"; 312 } 313 textPanel.setFontVictor(); 314 textPanel.addPara(log); 315 textPanel.setFontInsignia(); 316 317 LocationAPI loc = Global.getSector().getCurrentLocation(); 318 String tags = ""; 319 for (String tag : Global.getSector().getCurrentLocation().getTags()) { 320 tags += " " + tag + "\n"; 321 } 322 textPanel.addPara("\nTags for " + loc.getName() + ":\n" + tags); 323 if (loc instanceof StarSystemAPI) { 324 textPanel.addPara("\nSystem type: " + ((StarSystemAPI)loc).getType()); 325 } 326 327 break; 328 case ADD_LOG_INTEL: 329 PLIntel intel = new PLIntel(); 330 Global.getSector().getIntelManager().addIntel(intel, false, textPanel); 331 332 LuddicShrineIntel.addShrineIntelIfNeeded("beholder_station", textPanel); 333 LuddicShrineIntel.addShrineIntelIfNeeded("chicomoztoc", textPanel); 334 LuddicShrineIntel.addShrineIntelIfNeeded("gilead", textPanel); 335 LuddicShrineIntel.addShrineIntelIfNeeded("jangala", textPanel); 336 LuddicShrineIntel.addShrineIntelIfNeeded("killa", textPanel); 337 LuddicShrineIntel.addShrineIntelIfNeeded("volturn", textPanel); 338 339 PromoteOfficerIntel intel2 = new PromoteOfficerIntel(textPanel); 340 Global.getSector().getIntelManager().addIntel(intel2, false, textPanel); 341 342// dialog.showCustomProductionPicker(new BaseCustomProductionPickerDelegateImpl()); 343 344 //Global.getSector().getIntelManager().addIntel(intel, false, textPanel); 345 346// for (int i = 0; i < 12 * 3; i++) { 347// for (int j = 0; j < 10; j++) { 348// PlaythroughLog.getInstance().reportEconomyTick(i); 349// } 350// PlaythroughLog.getInstance().reportEconomyMonthEnd(); 351// } 352 break; 353 case LEAVE: 354 //Global.getSector().setPaused(false); 355 dialog.dismiss(); 356 break; 357 } 358 } 359 360 protected MarketAPI getNearestMarket(boolean playerOnly) { 361 MarketAPI nearest = null; 362 float minDist = Float.MAX_VALUE; 363 CampaignFleetAPI pf = Global.getSector().getPlayerFleet(); 364 for (MarketAPI curr : Global.getSector().getEconomy().getMarketsCopy()) { 365 if (curr.isHidden()) continue; 366 if (playerOnly && !curr.isPlayerOwned()) continue; 367 368 float dist = Misc.getDistanceLY(pf, curr.getPrimaryEntity()); 369 boolean nearer = dist < minDist; 370 if (dist == minDist && dist == 0 && nearest != null) { 371 float d1 = Misc.getDistance(pf, curr.getPrimaryEntity()); 372 float d2 = Misc.getDistance(pf, nearest.getPrimaryEntity()); 373 nearer = d1 < d2; 374 } 375 if (nearer) { 376 nearest = curr; 377 minDist = dist; 378 } 379 } 380 return nearest; 381 } 382 383 protected void print(String str) { 384 textPanel.appendToLastParagraph("\n" + str); 385 System.out.println(str); 386 } 387 388 protected void createInitialOptions() { 389 options.clearOptions(); 390 391 options.addOption("Fight!", OptionId.FIGHT); 392// options.addOption("Fight tutorial", OptionId.TUTORIAL); 393 394 MarketAPI market = getNearestMarket(false); 395 if (market != null) { 396 options.addOption("Send pirate raid to " + market.getContainingLocation().getName(), OptionId.PIRATE_RAID, null); 397 } 398 options.addOption("Send a punitive expedition", OptionId.PUNITIVE_EXPEDITION); 399 options.addOption("Send an AI inspection", OptionId.INSPECTION); 400 options.addOption("Hyperspace Topography +50 points", OptionId.TOPOGRAPHY_POINTS); 401 options.addOption("Hostile Activity: reseed RNG and cycle progress through 400/450/499", OptionId.HAEI_POINTS); 402 options.addOption("Print player log", OptionId.PRINT_LOG); 403 options.addOption("Add player log intel", OptionId.ADD_LOG_INTEL); 404 405 if (market != null) { 406 options.addOption("Increase size of " + market.getName() + " to " + (market.getSize() + 1), OptionId.INCREASE_COLONY_SIZE); 407 options.addOption("Finish construction on " + market.getName(), OptionId.FINISH_CONSTRUCTION); 408 } 409 410 options.addOption("Leave", OptionId.LEAVE, null); 411 } 412 413 414 protected OptionId lastOptionMousedOver = null; 415 public void optionMousedOver(String optionText, Object optionData) { 416 417 } 418 419 public void advance(float amount) { 420 421 } 422 423 public Object getContext() { 424 return null; 425 } 426 427 public PirateBaseIntel findPirateBase() { 428 for (IntelInfoPlugin p : Global.getSector().getIntelManager().getIntel(PirateBaseIntel.class)) { 429 PirateBaseIntel intel = (PirateBaseIntel) p; 430 if (intel.isEnded() || intel.isEnding()) continue; 431 return intel; 432 } 433 return null; 434 } 435 436 437 public void checkFactionUseOfStuff() { 438 List<FactionAPI> factions = Global.getSector().getAllFactions(); 439 440 System.out.println(); 441 System.out.println("----------------------- FIGHTERS -----------------------"); 442 System.out.println(); 443 444 Map<String, String> oneFactionFighters = new LinkedHashMap<String, String>(); 445 for (FighterWingSpecAPI spec : Global.getSettings().getAllFighterWingSpecs()) { 446 if (spec.hasTag(Tags.RESTRICTED)) continue; 447 int count = 0; 448 String id = spec.getId(); 449 String fId = null; 450 List<String> all = new ArrayList<String>(); 451 for (FactionAPI f : factions) { 452 if (f.isPlayerFaction()) continue; 453 if (f.getKnownFighters().contains(id)) { 454 count++; 455 fId = f.getId(); 456 all.add(fId); 457 } 458 } 459 if (count == 0) { 460 //System.out.println("Fighter wing [" + id + "] has no increased sell frequency anywhere"); 461 System.out.println("FIGHTER WING [" + id + "] IS NOT USED BY ANY FACTION"); 462 } 463 if (count == 1) { 464 oneFactionFighters.put(id, fId); 465 } 466 467 if (count != 0) { 468 System.out.println("Fighter wing [" + id + "] is known by: [" + Misc.getAndJoined(all) + "]"); 469 } 470 } 471 472 System.out.println(); 473 System.out.println("----------------------- WEAPONS -----------------------"); 474 System.out.println(); 475 476 for (WeaponSpecAPI spec : Global.getSettings().getAllWeaponSpecs()) { 477 if (spec.hasTag(Tags.RESTRICTED)) continue; 478 if (spec.hasTag(Tags.NO_SELL)) continue; 479 if (spec.getAIHints().contains(AIHints.SYSTEM)) continue; 480 String id = spec.getWeaponId(); 481 int count = 0; 482 List<String> all = new ArrayList<String>(); 483 for (FactionAPI f : factions) { 484 if (f.isPlayerFaction()) continue; 485 Float p = f.getWeaponSellFrequency().get(id); 486 if (p != null && p > 1f) { 487 count++; 488 } 489 if (f.knowsWeapon(id)) { 490 all.add(f.getId()); 491 } 492 } 493 if (count <= 0) { 494 System.out.println("Weapon [" + id + "] is not sold with higher frequency; known by: [" + Misc.getAndJoined(all) + "]"); 495 } 496 } 497 498 499 System.out.println(); 500 System.out.println("----------------------- SHIPS -----------------------"); 501 System.out.println(); 502 503 Map<String, String> oneFactionShips = new LinkedHashMap<String, String>(); 504 for (ShipHullSpecAPI spec : Global.getSettings().getAllShipHullSpecs()) { 505 if (spec.hasTag(Tags.RESTRICTED)) continue; 506 if (spec.hasTag(Tags.NO_SELL)) continue; 507 if (spec.getHullSize() == HullSize.FIGHTER) continue; 508 String id = spec.getHullId(); 509 if (id.endsWith("_default_D")) continue; 510 if (id.endsWith("_default_D")) continue; 511 if (id.startsWith("module_")) continue; 512 int count = 0; 513 String fId = null; 514 List<String> all = new ArrayList<String>(); 515 for (FactionAPI f : factions) { 516 if (f.isPlayerFaction()) continue; 517 if (f.getKnownShips().contains(id)) { 518 count++; 519 fId = f.getId(); 520 all.add(fId); 521 } 522 } 523// if (count <= 0) { 524// System.out.println("SHIP [" + id + "] IS NOT USED BY ANY FACTION"); 525// } 526 527 if (count == 1) { 528 oneFactionShips.put(id, fId); 529 } 530 531 if (count > 0) { 532 System.out.println("Ship [" + id + "] is known by: [" + Misc.getAndJoined(all) + "]"); 533 } 534 } 535 536// System.out.println(); 537// 538// for (String id : oneFactionShips.keySet()) { 539// System.out.println("Ship [" + id + "] is only known by [" + oneFactionShips.get(id) + "]"); 540// } 541 } 542 543} 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562