001package com.fs.starfarer.api.impl.campaign.rulecmd.salvage; 002 003import java.util.List; 004import java.util.Map; 005 006import com.fs.starfarer.api.Global; 007import com.fs.starfarer.api.campaign.CampaignFleetAPI; 008import com.fs.starfarer.api.campaign.CargoAPI; 009import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType; 010import com.fs.starfarer.api.campaign.CargoPickerListener; 011import com.fs.starfarer.api.campaign.CargoStackAPI; 012import com.fs.starfarer.api.campaign.CoreInteractionListener; 013import com.fs.starfarer.api.campaign.CustomCampaignEntityPlugin; 014import com.fs.starfarer.api.campaign.CustomEntitySpecAPI; 015import com.fs.starfarer.api.campaign.FactionAPI; 016import com.fs.starfarer.api.campaign.InteractionDialogAPI; 017import com.fs.starfarer.api.campaign.JumpPointAPI; 018import com.fs.starfarer.api.campaign.LocationAPI; 019import com.fs.starfarer.api.campaign.OptionPanelAPI; 020import com.fs.starfarer.api.campaign.RuleBasedDialog; 021import com.fs.starfarer.api.campaign.SectorEntityToken; 022import com.fs.starfarer.api.campaign.TextPanelAPI; 023import com.fs.starfarer.api.campaign.econ.MarketAPI; 024import com.fs.starfarer.api.campaign.listeners.ListenerUtil; 025import com.fs.starfarer.api.campaign.rules.MemoryAPI; 026import com.fs.starfarer.api.impl.campaign.CampaignObjective; 027import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActionEnvelope; 028import com.fs.starfarer.api.impl.campaign.CoreReputationPlugin.RepActions; 029import com.fs.starfarer.api.impl.campaign.DebugFlags; 030import com.fs.starfarer.api.impl.campaign.ids.Commodities; 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.Items; 034import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 035import com.fs.starfarer.api.impl.campaign.ids.Tags; 036import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTNeutrinoBurstFactor; 037import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTPoints; 038import com.fs.starfarer.api.impl.campaign.intel.events.ht.HyperspaceTopographyEventIntel; 039import com.fs.starfarer.api.impl.campaign.intel.misc.CommSnifferIntel; 040import com.fs.starfarer.api.impl.campaign.rulecmd.AddRemoveCommodity; 041import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin; 042import com.fs.starfarer.api.impl.campaign.rulecmd.FireBest; 043import com.fs.starfarer.api.impl.campaign.shared.WormholeManager; 044import com.fs.starfarer.api.impl.campaign.velfield.SlipstreamVisibilityManager; 045import com.fs.starfarer.api.loading.Description; 046import com.fs.starfarer.api.loading.Description.Type; 047import com.fs.starfarer.api.ui.LabelAPI; 048import com.fs.starfarer.api.ui.TooltipMakerAPI; 049import com.fs.starfarer.api.util.Misc; 050import com.fs.starfarer.api.util.Misc.Token; 051 052/** 053 * NotifyEvent $eventHandle <params> 054 * 055 */ 056public class Objectives extends BaseCommandPlugin { 057 058 public static String BURST_RANGE = "$COB_burstRange"; 059 060 public static int WORMHOLE_FUEL = 100; 061 public static String WORMHOLE_TYPE_STR = "wormhole"; 062 063 public static float BURST_RANGE_MAKESHIFT = 10; 064 public static float BURST_RANGE_DOMAIN = 15; 065 public static float BURST_RANGE_SCAVENGER_MIN = 5; // used by HT_CMD 066 public static float BURST_RANGE_SCAVENGER_MAX = 10; // used by HT_CMD 067 068 public static float SALVAGE_FRACTION = 0.5f; 069 070 protected CampaignFleetAPI playerFleet; 071 protected SectorEntityToken entity; 072 protected FactionAPI playerFaction; 073 protected FactionAPI entityFaction; 074 protected TextPanelAPI text; 075 protected OptionPanelAPI options; 076 protected CargoAPI playerCargo; 077 protected MemoryAPI memory; 078 protected InteractionDialogAPI dialog; 079 protected Map<String, MemoryAPI> memoryMap; 080 protected FactionAPI faction; 081 082 public Objectives() { 083 084 } 085 086 public Objectives(SectorEntityToken entity) { 087 init(entity); 088 } 089 090 protected void init(SectorEntityToken entity) { 091 memory = entity.getMemoryWithoutUpdate(); 092 this.entity = entity; 093 playerFleet = Global.getSector().getPlayerFleet(); 094 playerCargo = playerFleet.getCargo(); 095 096 playerFaction = Global.getSector().getPlayerFaction(); 097 entityFaction = entity.getFaction(); 098 099 faction = entity.getFaction(); 100 101 if (entity.hasTag(Tags.MAKESHIFT)) { 102 memory.set(BURST_RANGE, (int)BURST_RANGE_MAKESHIFT, 0); 103 } else { 104 memory.set(BURST_RANGE, (int)BURST_RANGE_DOMAIN, 0); 105 } 106 107// DebugFlags.OBJECTIVES_DEBUG = false; 108// DebugFlags.OBJECTIVES_DEBUG = true; 109 } 110 111 public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, Map<String, MemoryAPI> memoryMap) { 112 113 this.dialog = dialog; 114 this.memoryMap = memoryMap; 115 116 String command = params.get(0).getString(memoryMap); 117 if (command == null) return false; 118 119 entity = dialog.getInteractionTarget(); 120 init(entity); 121 122 memory = getEntityMemory(memoryMap); 123 124 text = dialog.getTextPanel(); 125 options = dialog.getOptionPanel(); 126 127 if (command.equals("printCost")) { 128 String type = params.get(1).getString(memoryMap); 129 printCost(type); 130 } else if (command.equals("showSalvage")) { 131 printSalvage(); 132 } else if (command.equals("selectWormholeAnchor")) { 133 selectWormholeAnchor(); 134 } else if (command.equals("hasWormholeAnchor")) { 135 return hasWormholeAnchor(); 136 } else if (command.equals("hasRepImpact")) { 137 return hasRepImpact(); 138 } else if (command.equals("showRepairCost")) { 139 printRepairCost(true); 140 } else if (command.equals("showBurstCost")) { 141 boolean hasRecent = HyperspaceTopographyEventIntel.hasRecentReadingsNearPlayer(); 142 printBurstCost(canBurst() && !hasRecent); 143 } else if (command.equals("showRepairCostNoPrompt")) { 144 printRepairCost(false); 145 } else if (command.equals("printHackDesc")) { 146 printHackDesc(); 147 } else if (command.equals("canBuild")) { 148 String type = params.get(1).getString(memoryMap); 149 return canBuild(type); 150 } else if (command.equals("canActivate")) { 151 return canActivate(entity.getCustomEntityType()); 152 } else if (command.equals("canBurst")) { 153 return canBurst(); 154 } else if (command.equals("build")) { 155 String type = params.get(1).getString(memoryMap); 156 build(type, Factions.PLAYER); 157 } else if (command.equals("printDescription")) { 158 updateMemory(); 159 String type = entity.getCustomEntityType(); 160 printDescription(type); 161 } else if (command.equals("isHacked")) { 162 return isHacked(); 163 } else if (command.equals("doAction")) { 164 String action = params.get(1).getString(memoryMap); 165 if (action.equals("hack")) { 166 hack(); 167 } else if (action.equals("reset")) { 168 reset(); 169 } else if (action.equals("unhack")) { 170 unhack(); 171 } else if (action.equals("control")) { 172 control(Factions.PLAYER); 173 } else if (action.equals("salvage")) { 174 salvage(Factions.PLAYER); 175 } else if (action.equals("burst")) { 176 doBurst(); 177 } 178 } 179 return true; 180 } 181 182 protected void doBurst() { 183 CargoAPI cargo = playerCargo; 184 String [] res = getBurstResources(); 185 int [] quantities = getBurstQuantities(); 186 for (int i = 0; i < res.length; i++) { 187 String commodityId = res[i]; 188 int quantity = quantities[i]; 189 cargo.removeCommodity(commodityId, quantity); 190 AddRemoveCommodity.addCommodityLossText(commodityId, quantity, text); 191 } 192 193 float range = memory.getFloat(BURST_RANGE); 194 SlipstreamVisibilityManager.updateSlipstreamVisibility(entity.getLocationInHyperspace(), range); 195 196 int points = 0; 197 if (entity.hasTag(Tags.MAKESHIFT)) { 198 points = HTPoints.NEUTRINO_BURST_MAKESHIFT; 199 } else { 200 points = HTPoints.NEUTRINO_BURST_DOMAIN; 201 } 202 203 204 boolean hasRecent = HyperspaceTopographyEventIntel.hasRecentReadingsNearPlayer(); 205 if (!hasRecent && points > 0) { 206 HyperspaceTopographyEventIntel.addFactorCreateIfNecessary(new HTNeutrinoBurstFactor(points), dialog); 207 if (HyperspaceTopographyEventIntel.get() != null) { 208 HyperspaceTopographyEventIntel.get().addRecentReadings(entity.getLocationInHyperspace()); 209 } 210 } 211 } 212 213 protected boolean hasRepImpact() { 214 for (MarketAPI curr : Global.getSector().getEconomy().getMarkets(entity.getContainingLocation())) { 215 if (curr.getFaction() == entity.getFaction() && 216 !curr.getFaction().isNeutralFaction() && 217 !curr.getFaction().isPlayerFaction()) { 218 return true; 219 } 220 } 221 return false; 222 } 223 224 public void salvage(final String factionId) { 225 226 CargoAPI salvage = Global.getFactory().createCargo(true); 227 String [] r = getResources(); 228 int [] q = getSalvageQuantities(); 229 230 for (int i = 0; i < r.length; i++) { 231 salvage.addCommodity(r[i], q[i]); 232 } 233 234 dialog.getVisualPanel().showLoot("Salvaged", salvage, false, true, true, new CoreInteractionListener() { 235 public void coreUIDismissed() { 236 dialog.dismiss(); 237 dialog.hideTextPanel(); 238 dialog.hideVisualPanel(); 239 240 LocationAPI loc = entity.getContainingLocation(); 241 SectorEntityToken built = loc.addCustomEntity(null, 242 null, 243 Entities.STABLE_LOCATION, // type of object, defined in custom_entities.json 244 Factions.NEUTRAL); // faction 245 if (entity.getOrbit() != null) { 246 built.setOrbit(entity.getOrbit().makeCopy()); 247 } else { 248 built.setLocation(entity.getLocation().x, entity.getLocation().y); 249 } 250 loc.removeEntity(entity); 251 updateOrbitingEntities(loc, entity, built); 252 253 built.getMemoryWithoutUpdate().set(MemFlags.RECENTLY_SALVAGED, true, 30f); 254 255 if (Factions.PLAYER.equals(factionId) && hasRepImpact() && 256 !entity.getFaction().isPlayerFaction() && 257 !entity.getFaction().isNeutralFaction()) { 258 RepActions action = RepActions.COMBAT_AGGRESSIVE; 259 if (entity.hasTag(Tags.MAKESHIFT)) { 260 action = RepActions.COMBAT_AGGRESSIVE_TOFF; 261 } 262 Global.getSector().adjustPlayerReputation( 263 new RepActionEnvelope(action, null, null, null, false, true, "Change caused by destruction of " + entity.getCustomEntitySpec().getDefaultName().toLowerCase()), 264 faction.getId()); 265 } 266 267 ListenerUtil.reportObjectiveDestroyed(entity, built, Global.getSector().getFaction(factionId)); 268 } 269 }); 270 options.clearOptions(); 271 dialog.setPromptText(""); 272 273 } 274 275 public void updateOrbitingEntities(LocationAPI loc, SectorEntityToken prev, SectorEntityToken built) { 276 if (loc == null) return; 277 for (SectorEntityToken other : loc.getAllEntities()) { 278 if (other == prev) continue; 279 if (other.getOrbit() == null) continue; 280 if (other.getOrbitFocus() == prev) { 281 other.setOrbitFocus(built); 282 } 283 } 284 } 285 286 public boolean isNonFunctional() { 287 return entity.getMemoryWithoutUpdate().getBoolean(MemFlags.OBJECTIVE_NON_FUNCTIONAL); 288 } 289 290 public void control(String factionId) { 291 if (dialog != null) { 292 if (Factions.PLAYER.equals(factionId) && isNonFunctional()) { 293 removeRepairCosts(text); 294 } 295 if (Factions.PLAYER.equals(factionId) && hasRepImpact() && 296 !entity.getFaction().isPlayerFaction() && !entity.getFaction().isNeutralFaction()) { 297 RepActions action = RepActions.COMBAT_AGGRESSIVE; 298 //action = RepActions.COMBAT_AGGRESSIVE_TOFF; 299 Global.getSector().adjustPlayerReputation( 300 new RepActionEnvelope(action, null, null, text, false, true), 301 faction.getId()); 302 } 303 } 304 FactionAPI prev = entity.getFaction(); 305 entity.setFaction(factionId); 306 faction = entity.getFaction(); 307 308 if (!entity.hasTag(Tags.COMM_RELAY) && faction.isPlayerFaction()) { 309 unhack(); 310 } 311 312 entity.getMemoryWithoutUpdate().unset(MemFlags.OBJECTIVE_NON_FUNCTIONAL); 313 314 if (dialog != null) { 315 ((RuleBasedDialog) dialog.getPlugin()).updateMemory(); 316 updateMemory(); 317 318 printOwner(); 319 } 320 321 322 ListenerUtil.reportObjectiveChangedHands(entity, prev, faction); 323 } 324 325 public void unhack() { 326 CommSnifferIntel intel = CommSnifferIntel.getExistingSnifferIntelForRelay(entity); 327 if (intel != null) { 328 intel.uninstall(); 329 updateMemory(); 330 } else { 331 CustomCampaignEntityPlugin plugin = entity.getCustomPlugin(); 332 if (plugin instanceof CampaignObjective) { 333 CampaignObjective o = (CampaignObjective) plugin; 334 o.setHacked(false); 335 } 336 updateMemory(); 337 } 338 } 339 340 public void hack() { 341 CustomCampaignEntityPlugin plugin = entity.getCustomPlugin(); 342 if (plugin instanceof CampaignObjective) { 343 CampaignObjective o = (CampaignObjective) plugin; 344 o.setHacked(true); 345 } 346 updateMemory(); 347 } 348 349 public void reset() { 350 CustomCampaignEntityPlugin plugin = entity.getCustomPlugin(); 351 if (plugin instanceof CampaignObjective) { 352 CampaignObjective o = (CampaignObjective) plugin; 353 o.setReset(true); 354 } 355 // so that a false sensor reading doesn't spawn immediately after "introducing false readings" 356 Global.getSector().getPlayerFleet().getMemoryWithoutUpdate().set(MemFlags.FLEET_NOT_CHASING_GHOST, true, 357 0.5f + Misc.random.nextFloat() * 1f); 358 updateMemory(); 359 } 360 361 public boolean isHacked() { 362 CustomCampaignEntityPlugin plugin = entity.getCustomPlugin(); 363 if (plugin instanceof CampaignObjective) { 364 CampaignObjective o = (CampaignObjective) plugin; 365 return o.isHacked(); 366 } 367 return false; 368 } 369 370 public void build(String type, String factionId) { 371 if (entity.hasTag(Tags.NON_CLICKABLE)) return; 372 if (entity.hasTag(Tags.FADING_OUT_AND_EXPIRING)) return; 373 374 LocationAPI loc = entity.getContainingLocation(); 375 SectorEntityToken built = loc.addCustomEntity(null, 376 null, 377 type, // type of object, defined in custom_entities.json 378 factionId); // faction 379 if (entity.getOrbit() != null) { 380 built.setOrbit(entity.getOrbit().makeCopy()); 381 } 382 built.setLocation(entity.getLocation().x, entity.getLocation().y); 383 loc.removeEntity(entity); 384 updateOrbitingEntities(loc, entity, built); 385 386 //entity.setContainingLocation(null); 387 built.getMemoryWithoutUpdate().set("$originalStableLocation", entity); 388 389 if (text != null) { 390 removeBuildCosts(); 391 Global.getSoundPlayer().playUISound("ui_objective_constructed", 1f, 1f); 392 } 393 } 394 395 396 public boolean canBuild(String type) { 397 if (DebugFlags.OBJECTIVES_DEBUG) { 398 return true; 399 } 400 401 402 CargoAPI cargo = playerCargo; 403 String [] res = getResources(); 404 int [] quantities = getQuantities(); 405 406 if (type.equals(WORMHOLE_TYPE_STR)) { 407 res = getWormholeResources(); 408 quantities = getWormholeQuantities(); 409 } 410 411 for (int i = 0; i < res.length; i++) { 412 String commodityId = res[i]; 413 int quantity = quantities[i]; 414 if (quantity > cargo.getQuantity(CargoItemType.RESOURCES, commodityId)) { 415 return false; 416 } 417 } 418 return true; 419 } 420 421 public void removeBuildCosts() { 422 if (DebugFlags.OBJECTIVES_DEBUG) { 423 return; 424 } 425 426 CargoAPI cargo = playerCargo; 427 String [] res = getResources(); 428 int [] quantities = getQuantities(); 429 for (int i = 0; i < res.length; i++) { 430 String commodityId = res[i]; 431 int quantity = quantities[i]; 432 cargo.removeCommodity(commodityId, quantity); 433 } 434 } 435 436 public void removeRepairCosts(TextPanelAPI text) { 437 if (DebugFlags.OBJECTIVES_DEBUG) { 438 return; 439 } 440 441 CargoAPI cargo = playerCargo; 442 String [] res = getRepairResources(); 443 int [] quantities = getRepairQuantities(); 444 for (int i = 0; i < res.length; i++) { 445 String commodityId = res[i]; 446 int quantity = quantities[i]; 447 cargo.removeCommodity(commodityId, quantity); 448 AddRemoveCommodity.addCommodityLossText(commodityId, quantity, text); 449 } 450 } 451 452 public boolean canActivate(String type) { 453 if (DebugFlags.OBJECTIVES_DEBUG) { 454 return true; 455 } 456 457 CargoAPI cargo = playerCargo; 458 String [] res = getRepairResources(); 459 int [] quantities = getRepairQuantities(); 460 for (int i = 0; i < res.length; i++) { 461 String commodityId = res[i]; 462 int quantity = quantities[i]; 463 if (quantity > cargo.getQuantity(CargoItemType.RESOURCES, commodityId)) { 464 return false; 465 } 466 } 467 return true; 468 } 469 470 public boolean canBurst() { 471 if (DebugFlags.OBJECTIVES_DEBUG) { 472 return true; 473 } 474 475 CargoAPI cargo = playerCargo; 476 String [] res = getBurstResources(); 477 int [] quantities = getBurstQuantities(); 478 for (int i = 0; i < res.length; i++) { 479 String commodityId = res[i]; 480 int quantity = quantities[i]; 481 if (quantity > cargo.getQuantity(CargoItemType.RESOURCES, commodityId)) { 482 return false; 483 } 484 } 485 return true; 486 } 487 488 489 public void updateMemory() { 490 //memory.set("$cob_hacked", isHacked(), 0f); 491 //memory.set(BaseCampaignObjectivePlugin.HACKED, isHacked(), 0f); 492 } 493 494 public void printDescription(String type) { 495 Description desc = Global.getSettings().getDescription(type, Type.CUSTOM); 496 if (desc != null) { 497 text.addParagraph(desc.getText1()); 498 } 499 500 CustomEntitySpecAPI spec = Global.getSettings().getCustomEntitySpec(type); 501 CustomCampaignEntityPlugin plugin = spec.getPlugin(); 502 SectorEntityToken temp = entity.getContainingLocation().createToken(0, 0); 503 for (String tag : spec.getTags()) { 504 temp.addTag(tag); 505 } 506 plugin.init(temp, null); 507 508 boolean objective = entity.hasTag(Tags.OBJECTIVE); 509 if (objective) { 510 plugin = entity.getCustomPlugin(); 511 } 512 513 Class c = null; 514 if (plugin instanceof CampaignObjective) { 515 CampaignObjective o = (CampaignObjective) plugin; 516 c = o.getClass(); 517 518 TooltipMakerAPI info = text.beginTooltip(); 519 o.printEffect(info, 0f); 520 text.addTooltip(); 521 522 o.printNonFunctionalAndHackDescription(text); 523 } 524 525 printOwner(); 526 527 for (SectorEntityToken curr : entity.getContainingLocation().getEntitiesWithTag(Tags.OBJECTIVE)) { 528 if (curr.hasTag(Tags.OBJECTIVE)) { 529 if (curr.getFaction() == null || !curr.getFaction().isPlayerFaction() || 530 curr.getCustomEntitySpec() == null) { 531 continue; 532 } 533 534 CustomCampaignEntityPlugin ccep = curr.getCustomPlugin(); 535 if (ccep instanceof CampaignObjective) { 536 CampaignObjective o = (CampaignObjective) ccep; 537 if (c == o.getClass()) { 538 if (entity == curr) { 539 text.addPara("Another one in this star system would have no effect " + 540 "beyond providing redundancy in case this one is lost."); 541 } else { 542 text.addPara("There's already " + 543 curr.getCustomEntitySpec().getAOrAn() + " " + 544 curr.getCustomEntitySpec().getNameInText() + " under your control " + 545 "in this star system. Another one would have no effect " + 546 "beyond providing redundancy if one is lost."); 547 } 548 break; 549 } 550 } 551 } 552 } 553 554 } 555 556 public void printOwner() { 557 boolean objective = entity.hasTag(Tags.OBJECTIVE); 558 if (objective) { 559 if (!faction.isNeutralFaction()) { 560 if (entity.getFaction().isPlayerFaction() && !Misc.isPlayerFactionSetUp()) { 561 text.addPara("This " + entity.getCustomEntitySpec().getShortName() + " is under your control.", 562 entity.getFaction().getBaseUIColor(), "your"); 563 } else { 564 text.addPara("This " + entity.getCustomEntitySpec().getShortName() + " is under %s control.", 565 entity.getFaction().getBaseUIColor(), entity.getFaction().getPersonNamePrefix()); 566 } 567 } else { 568 text.addPara("This " + entity.getCustomEntitySpec().getShortName() + " is not claimed by any faction."); 569 } 570 } 571 } 572 573 574 575 public void printHackDesc() { 576// if (entity.hasTag(Tags.COMM_RELAY)) { 577// text.addPara("The comm sniffer will remain active until it is detected and cleared out by the " + 578// "maintenance subroutines. The odds of this happening increase drastically when " + 579// "multiple comm sniffers are installed on different relays in the comm network."); 580// } else { 581// text.addPara("The hack will eventually be picked up and cleared out by the maintenance subroutines, but should " + 582// "remain effective for at least three months."); 583// } 584 } 585 586 public void printRepairCost(boolean withPrompt) { 587 Misc.showCost(text, null, null, getRepairResources(), getRepairQuantities()); 588 if (withPrompt) { 589 text.addPara("Proceed with reactivation?"); 590 } 591 } 592 593 public void printBurstCost(boolean withPrompt) { 594 Misc.showCost(text, null, null, getBurstResources(), getBurstQuantities()); 595 boolean hasRecent = HyperspaceTopographyEventIntel.hasRecentReadingsNearPlayer(); 596 if (hasRecent) { 597 LabelAPI label = text.addPara("You've recently acquired topographic data within %s light-years of your current location," 598 + " and a neutrino burst here " 599 + "will not meaningfully contribute to your understanding of " 600 + "hyperspace topology. It will, however, still " 601 + "reveal all nearby slipstreams.", Misc.getHighlightColor(), 602 "" + (int)HyperspaceTopographyEventIntel.RECENT_READINGS_RANGE_LY); 603 label.setHighlightColors(Misc.getHighlightColor(), Misc.getNegativeHighlightColor(), Misc.getNegativeHighlightColor()); 604 label.setHighlight("" + (int)HyperspaceTopographyEventIntel.RECENT_READINGS_RANGE_LY, 605 "will not meaningfully contribute", "hyperspace topology"); 606 } 607 //RECENT_READINGS_RANGE_LY 608 if (withPrompt) { 609 text.addPara("Proceed with neutrino burst?"); 610 } 611 } 612 613 public void printSalvage() { 614 Misc.showCost(text, "Potential salvage", false, null, null, getResources(), getSalvageQuantities()); 615 616 text.addPara("Proceed with salvage operation?"); 617 } 618 619 public void printCost(String type) { 620 if (type.equals(WORMHOLE_TYPE_STR)) { 621 Misc.showCost(text, null, null, getWormholeResources(), getWormholeQuantities()); 622 return; 623 } 624 printDescription(type); 625 626 Misc.showCost(text, null, null, getResources(), getQuantities()); 627 628 if (canBuild(type)) { 629 text.addPara("Proceed with construction?"); 630 } else { 631 text.addPara("You do not have the necessary resources to build this structure."); 632 } 633 } 634 635 public String [] getWormholeResources() { 636 return new String[] {Commodities.FUEL}; 637 } 638 639 public int [] getWormholeQuantities() { 640 return new int[] {WORMHOLE_FUEL}; 641 } 642 643 public String [] getResources() { 644 if (entity.hasTag(Tags.MAKESHIFT) || entity.hasTag(Tags.STABLE_LOCATION)) { 645 return new String[] {Commodities.HEAVY_MACHINERY, Commodities.METALS, Commodities.RARE_METALS}; 646 } 647 return new String[] {Commodities.HEAVY_MACHINERY, Commodities.METALS, Commodities.RARE_METALS, Commodities.VOLATILES}; 648 } 649 650 651 public int [] getSalvageQuantities() { 652 int [] q = getQuantities(); 653 int [] result = new int [q.length]; 654 655 for (int i = 0; i < result.length; i++) { 656 result[i] = (int) (q[i] * SALVAGE_FRACTION); 657 } 658 return result; 659 } 660 public int [] getQuantities() { 661 if (entity.hasTag(Tags.MAKESHIFT) || entity.hasTag(Tags.STABLE_LOCATION)) { 662 return new int[] {15, 30, 5}; 663 } 664 return new int[] {50, 200, 20, 20}; 665 } 666 667 public String [] getRepairResources() { 668 return new String[] {Commodities.HEAVY_MACHINERY }; 669 } 670 671 672 public int [] getRepairQuantities() { 673 return new int[] {5}; 674 } 675 676 677 public int [] getBurstQuantities() { 678 return new int[] {HTPoints.NEUTRINO_BURST_VOLATILES_COST}; 679 } 680 681 public String [] getBurstResources() { 682 return new String[] {Commodities.VOLATILES}; 683 } 684 685 public boolean hasWormholeAnchor() { 686 return !getWormholeAnchors().isEmpty(); 687 } 688 public CargoAPI getWormholeAnchors() { 689 CargoAPI copy = Global.getFactory().createCargo(false); 690 for (CargoStackAPI stack : playerCargo.getStacksCopy()) { 691 if (stack.isSpecialStack() && Items.WORMHOLE_ANCHOR.equals(stack.getSpecialDataIfSpecial().getId())) { 692 copy.addFromStack(stack); 693 } 694 } 695 copy.sort(); 696 return copy; 697 } 698 699 public void selectWormholeAnchor() { 700 CargoAPI copy = getWormholeAnchors(); 701 702 final float width = 310f; 703 dialog.showCargoPickerDialog("Select wormhole anchor to deploy", "Deploy", "Cancel", true, width, copy, 704 new CargoPickerListener() { 705 public void pickedCargo(CargoAPI cargo) { 706 if (cargo.isEmpty()) { 707 cancelledCargoSelection(); 708 return; 709 } 710 711 cargo.sort(); 712 for (CargoStackAPI stack : cargo.getStacksCopy()) { 713 if (stack.isSpecialStack()) { 714 JumpPointAPI jp = WormholeManager.get().addWormhole(stack.getSpecialDataIfSpecial(), entity, dialog); 715 716 if (!DebugFlags.OBJECTIVES_DEBUG) { 717 playerCargo.removeCommodity(Commodities.FUEL, WORMHOLE_FUEL); 718 AddRemoveCommodity.addCommodityLossText(Commodities.FUEL, WORMHOLE_FUEL, text); 719 } 720 721 FireBest.fire(null, dialog, memoryMap, "WormholeDeploymentFinished"); 722 723 if (jp != null) { 724 MiscCMD.addWormholeIntelIfNeeded(jp, text, true); 725 } 726 break; 727 } 728 } 729 } 730 public void cancelledCargoSelection() { 731 } 732 public void recreateTextPanel(TooltipMakerAPI panel, CargoAPI cargo, CargoStackAPI pickedUp, boolean pickedUpFromSource, CargoAPI combined) { 733 panel.addPara("Deploying and activating a wormhole anchor, turning it into an active terminus, " 734 + "will consume %s fuel. Your fleet is carrying %s fuel.", 735 0f, Misc.getHighlightColor(), 736 "" + WORMHOLE_FUEL, 737 "" + (int)playerCargo.getFuel()); 738 739 boolean makeUnstable = WormholeManager.willWormholeBecomeUnstable(entity); 740 if (makeUnstable) { 741 panel.addPara("Once the operation is completed, the wormhole will take about half a cycle to stablize," 742 + "before it can be used.", 10f, Misc.getHighlightColor(), "half a cycle"); 743 } else { 744 panel.addPara("Usually, the wormhole will take about a cycle to stablize, but you have " 745 + "calibration data that will allow it to be used immediately.", 10f); 746 } 747 } 748 }); 749 } 750} 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765