001package com.fs.starfarer.api.impl.campaign.rulecmd.salvage; 002 003import java.util.List; 004import java.util.Map; 005import java.util.Random; 006 007import com.fs.starfarer.api.Global; 008import com.fs.starfarer.api.campaign.AICoreOfficerPlugin; 009import com.fs.starfarer.api.campaign.CampaignFleetAPI; 010import com.fs.starfarer.api.campaign.FactionAPI; 011import com.fs.starfarer.api.campaign.FactionAPI.ShipPickParams; 012import com.fs.starfarer.api.campaign.GenericPluginManagerAPI.GenericPlugin; 013import com.fs.starfarer.api.campaign.InteractionDialogAPI; 014import com.fs.starfarer.api.campaign.SectorEntityToken; 015import com.fs.starfarer.api.campaign.rules.MemKeys; 016import com.fs.starfarer.api.campaign.rules.MemoryAPI; 017import com.fs.starfarer.api.characters.PersonAPI; 018import com.fs.starfarer.api.combat.ShipVariantAPI; 019import com.fs.starfarer.api.fleet.FleetMemberAPI; 020import com.fs.starfarer.api.fleet.ShipRolePick; 021import com.fs.starfarer.api.impl.campaign.BaseGenericPlugin; 022import com.fs.starfarer.api.impl.campaign.DebugFlags; 023import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflater; 024import com.fs.starfarer.api.impl.campaign.fleets.DefaultFleetInflaterParams; 025import com.fs.starfarer.api.impl.campaign.fleets.FleetFactoryV3; 026import com.fs.starfarer.api.impl.campaign.fleets.FleetParamsV3; 027import com.fs.starfarer.api.impl.campaign.ids.Commodities; 028import com.fs.starfarer.api.impl.campaign.ids.Entities; 029import com.fs.starfarer.api.impl.campaign.ids.Factions; 030import com.fs.starfarer.api.impl.campaign.ids.FleetTypes; 031import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 032import com.fs.starfarer.api.impl.campaign.ids.ShipRoles; 033import com.fs.starfarer.api.impl.campaign.ids.Tags; 034import com.fs.starfarer.api.impl.campaign.procgen.DefenderDataOverride; 035import com.fs.starfarer.api.impl.campaign.procgen.SalvageEntityGenDataSpec; 036import com.fs.starfarer.api.impl.campaign.procgen.SalvageEntityGenDataSpec.DropData; 037import com.fs.starfarer.api.impl.campaign.procgen.themes.MiscellaneousThemeGenerator; 038import com.fs.starfarer.api.impl.campaign.procgen.themes.RemnantOfficerGeneratorPlugin; 039import com.fs.starfarer.api.impl.campaign.procgen.themes.SalvageEntityGeneratorOld; 040import com.fs.starfarer.api.impl.campaign.rulecmd.BaseCommandPlugin; 041import com.fs.starfarer.api.util.Misc; 042import com.fs.starfarer.api.util.Misc.Token; 043 044/** 045 * Actually just generates automated defenses, not salvage. SalvageEntity does that. 046 * 047 * SalvageGenFromSeed 048 */ 049public class SalvageGenFromSeed extends BaseCommandPlugin { 050 051 public static class SDMParams { 052 public SectorEntityToken entity; 053 public String factionId; 054 public SDMParams() { 055 } 056 } 057 058 059 public static interface SalvageDefenderModificationPlugin extends GenericPlugin { 060 float getStrength(SDMParams p, float strength, Random random, boolean withOverride); 061 float getProbability(SDMParams p, float probability, Random random, boolean withOverride); 062 float getQuality(SDMParams p, float quality, Random random, boolean withOverride); 063 float getMaxSize(SDMParams p, float maxSize, Random random, boolean withOverride); 064 float getMinSize(SDMParams p, float minSize, Random random, boolean withOverride); 065 066 void modifyFleet(SDMParams p, CampaignFleetAPI fleet, Random random, boolean withOverride); 067 void reportDefeated(SDMParams p, SectorEntityToken entity, CampaignFleetAPI fleet); 068 } 069 070 public static final String DEFEATED_DERELICT_STR = "$defeatedDerelictStr"; 071 public static final float DEFEATED_TO_ADDED_FACTOR = 0.2f; 072 public static final float DEFEATED_TO_QUALITY_FACTOR = 0.005f; 073 074 public static class SalvageDefenderModificationPluginImpl extends BaseGenericPlugin implements SalvageDefenderModificationPlugin { 075 public float getStrength(SDMParams p, float strength, Random random, boolean withOverride) { 076 if (withOverride) return strength; 077 if (Factions.DERELICT.equals(p.factionId)) { 078 // Limbo stuff is not affected 079 if (p.entity.getMemoryWithoutUpdate().getBoolean("$limboWormholeCache") || 080 p.entity.getMemoryWithoutUpdate().getBoolean("$limboMiningStation")) { 081 return strength; 082 } 083 084 085 float bonus = Global.getSector().getMemoryWithoutUpdate().getFloat(DEFEATED_DERELICT_STR) * DEFEATED_TO_ADDED_FACTOR; 086 087 String type = p.entity.getCustomEntityType(); 088 float limit = 300f; 089 if (Entities.DERELICT_SURVEY_PROBE.equals(type)) { 090 limit = 60; 091 } else if (Entities.DERELICT_SURVEY_SHIP.equals(type)) { 092 limit = 90; 093 } else if (Entities.DERELICT_MOTHERSHIP.equals(type) || Entities.DERELICT_CRYOSLEEPER.equals(type)) { 094 limit = 150; 095 } 096 097 // if (Global.getSettings().isDevMode()) { 098 // bonus = limit; 099 // } 100 101 if (bonus > limit) bonus = limit; 102 return strength + (int) bonus; 103 } 104 return strength; 105 } 106 public float getMinSize(SDMParams p, float minSize, Random random, boolean withOverride) { 107 if (withOverride) return minSize; 108 return minSize; 109 } 110 public float getMaxSize(SDMParams p, float maxSize, Random random, boolean withOverride) { 111 if (withOverride) return maxSize; 112 if (Factions.DERELICT.equals(p.factionId)) { 113 float bonus = Global.getSector().getMemoryWithoutUpdate().getFloat(DEFEATED_DERELICT_STR) * DEFEATED_TO_ADDED_FACTOR; 114 String type = p.entity.getCustomEntityType(); 115 float bonusSize = 1; 116 if (Entities.DERELICT_SURVEY_PROBE.equals(type)) { 117 if (bonus >= 5) bonusSize = 2; 118 } 119 120 return Math.max(maxSize, bonusSize); 121 } 122 return maxSize; 123 } 124 public float getProbability(SDMParams p, float probability, Random random, boolean withOverride) { 125 if (withOverride) return probability; 126 if (Factions.DERELICT.equals(p.factionId)) { 127 String type = p.entity.getCustomEntityType(); 128 float limit = 0f; 129 if (Entities.DERELICT_SURVEY_PROBE.equals(type)) { 130 limit = 60; 131 } else if (Entities.DERELICT_SURVEY_SHIP.equals(type)) { 132 limit = 90; 133 } 134 if (limit <= 0 || probability >= 1f) return probability; 135 136 float bonus = Global.getSector().getMemoryWithoutUpdate().getFloat(DEFEATED_DERELICT_STR) * DEFEATED_TO_ADDED_FACTOR; 137 if (bonus > limit) bonus = limit; 138 139 return probability * (1f - 0.5f * bonus / limit); 140 } 141 return probability; 142 } 143 public void reportDefeated(SDMParams p, SectorEntityToken entity, CampaignFleetAPI fleet) { 144 if (Factions.DERELICT.equals(p.factionId)) { 145 float total = Global.getSector().getMemoryWithoutUpdate().getFloat(DEFEATED_DERELICT_STR); 146 for (FleetMemberAPI member : Misc.getSnapshotMembersLost(fleet)) { 147 //total += FleetFactoryV2.getMemberWeight(member); 148 total += member.getFleetPointCost(); 149 } 150 Global.getSector().getMemoryWithoutUpdate().set(DEFEATED_DERELICT_STR, total); 151 } 152 } 153 public void modifyFleet(SDMParams p, CampaignFleetAPI fleet, Random random, boolean withOverride) { 154 if (Factions.OMEGA.equals(fleet.getFaction().getId())) { 155 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 156 ShipVariantAPI copy = member.getVariant().clone(); 157 member.setVariant(copy, false, false); 158 copy.addTag(Tags.SHIP_LIMITED_TOOLTIP); 159 } 160 161 DropData d; 162 d = new DropData(); 163 d.chances = 5; 164 d.maxChances = 7; 165 d.group = "omega_weapons_small"; 166 fleet.addDropRandom(d); 167 168 d = new DropData(); 169 d.chances = 3; 170 d.maxChances = 4; 171 d.group = "omega_weapons_medium"; 172 fleet.addDropRandom(d); 173 174 long seed = Misc.getSalvageSeed(p.entity); 175 fleet.getMemoryWithoutUpdate().set(MemFlags.SALVAGE_SEED, Misc.getRandom(seed, 11).nextLong()); 176 } else 177 if (Entities.ALPHA_SITE_WEAPONS_CACHE.equals(p.entity.getCustomEntityType())) { 178 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE); 179 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 180 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random); 181 member.setCaptain(person); 182 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(member); 183 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR()); 184 } 185 if (fleet.getInflater() instanceof DefaultFleetInflater) { 186 DefaultFleetInflater dfi = (DefaultFleetInflater) fleet.getInflater(); 187 ((DefaultFleetInflaterParams)dfi.getParams()).allWeapons = true; 188 } 189 } else 190 if (p.entity != null && p.entity.getMemoryWithoutUpdate().contains(MiscellaneousThemeGenerator.PLANETARY_SHIELD_PLANET)) { 191 FleetMemberAPI flagship = null; 192 for (ShipRolePick pick : fleet.getFaction().pickShip(ShipRoles.COMBAT_CAPITAL, ShipPickParams.all(), null, random)) { 193 FleetMemberAPI member = fleet.getFleetData().addFleetMember(pick.variantId); 194 flagship = member; 195 // the name is used as part of the random seed for autofit, so, want it to be consistent 196 member.setShipName(fleet.getFaction().pickRandomShipName(random)); 197 } 198 199 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE); 200 201 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 202 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR()); 203 member.setFlagship(member == flagship); 204 205 //PersonAPI person = OfficerManagerEvent.createOfficer(fleet.getFaction(), 20, SkillPickPreference.NON_CARRIER, random); 206 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random); 207 member.setCaptain(person); 208 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(member); 209 } 210 211 //PersonAPI person = OfficerManagerEvent.createOfficer(fleet.getFaction(), 20, SkillPickPreference.NON_CARRIER, random); 212 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random); 213 fleet.setCommander(person); 214 fleet.getFlagship().setCaptain(person); 215 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(fleet.getFlagship()); 216 217 if (fleet.getInflater() instanceof DefaultFleetInflater) { 218 DefaultFleetInflater dfi = (DefaultFleetInflater) fleet.getInflater(); 219 ((DefaultFleetInflaterParams)dfi.getParams()).allWeapons = true; 220 //dfi.setSeed(Misc.random.nextLong()); 221 } 222 } else 223 if (Entities.DERELICT_CRYOSLEEPER.equals(p.entity.getCustomEntityType())) { 224 fleet.getFleetData().clear(); 225 for (ShipRolePick pick : fleet.getFaction().pickShip(ShipRoles.COMBAT_CAPITAL, ShipPickParams.all(), null, random)) { 226 fleet.getFleetData().addFleetMember(pick.variantId); 227 } 228 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE); 229 //PersonAPI person = OfficerManagerEvent.createOfficer(fleet.getFaction(), 20, true, SkillPickPreference.NON_CARRIER, random); 230 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random); 231 // so it's not the standard alpha core portrait but an older-looking one 232 person.setPortraitSprite(fleet.getFaction().createRandomPerson().getPortraitSprite()); 233 fleet.setCommander(person); 234 fleet.getFlagship().setCaptain(person); 235 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(fleet.getFlagship()); 236 237 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 238 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR()); 239 } 240 } else 241 if (Entities.SPEC_LIMBO_WORMHOLE_CACHE.equals(p.entity.getCustomDescriptionId())) { 242 //fleet.getFleetData().clear(); 243 for (ShipRolePick pick : fleet.getFaction().pickShip(ShipRoles.COMBAT_CAPITAL, ShipPickParams.all(), null, random)) { 244 fleet.getFleetData().addFleetMember(pick.variantId); 245 } 246 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.GAMMA_CORE); 247 //PersonAPI person = OfficerManagerEvent.createOfficer(fleet.getFaction(), 20, true, SkillPickPreference.NON_CARRIER, random); 248 PersonAPI person = plugin.createPerson(Commodities.GAMMA_CORE, fleet.getFaction().getId(), random); 249 // so it's not the standard alpha core portrait but an older-looking one 250 //person.setPortraitSprite(fleet.getFaction().createRandomPerson().getPortraitSprite()); 251 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 252 if (member.isCapital()) { 253 fleet.getFleetData().setFlagship(member); 254 break; 255 } 256 } 257 fleet.setCommander(person); 258 fleet.getFlagship().setCaptain(person); 259 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(fleet.getFlagship()); 260 261 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 262 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR()); 263 } 264 } else 265 if (Entities.DERELICT_MOTHERSHIP.equals(p.entity.getCustomEntityType()) || 266 Entities.DERELICT_SURVEY_SHIP.equals(p.entity.getCustomEntityType()) || 267 Entities.DERELICT_SURVEY_PROBE.equals(p.entity.getCustomEntityType()) 268 ) { 269 270 float bonus = Global.getSector().getMemoryWithoutUpdate().getFloat(DEFEATED_DERELICT_STR) * DEFEATED_TO_ADDED_FACTOR; 271 float coreMult = Math.max(0f, (bonus / 100f) - 0.1f); 272 if (coreMult > 1f) coreMult = 1f; 273 274 if (coreMult > 0) { 275 RemnantOfficerGeneratorPlugin gen = new RemnantOfficerGeneratorPlugin(true, coreMult); 276 if (coreMult >= 1f) { 277 gen.setForceIntegrateCores(true); 278 } 279 gen.addCommanderAndOfficers(fleet, null, random); 280 } 281 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 282 if (member.isStation()) { 283 AICoreOfficerPlugin plugin = Misc.getAICoreOfficerPlugin(Commodities.ALPHA_CORE); 284 PersonAPI person = plugin.createPerson(Commodities.ALPHA_CORE, fleet.getFaction().getId(), random); 285 // so it's not the standard alpha core portrait but an older-looking one 286 person.setPortraitSprite(fleet.getFaction().createRandomPerson().getPortraitSprite()); 287 member.setCaptain(person); 288 RemnantOfficerGeneratorPlugin.integrateAndAdaptCoreForAIFleet(member); 289 } 290 member.getRepairTracker().setCR(member.getRepairTracker().getMaxCR()); 291 } 292 293 } 294 } 295 @Override 296 public int getHandlingPriority(Object params) { 297 if (!(params instanceof SDMParams)) return 0; 298 SDMParams p = (SDMParams) params; 299 300 if (p.entity != null && p.entity.getMemoryWithoutUpdate().contains(MiscellaneousThemeGenerator.PLANETARY_SHIELD_PLANET)) { 301 return 1; 302 } 303 if (Factions.DERELICT.equals(p.factionId)) { 304 return 1; 305 } 306 if (Factions.OMEGA.equals(p.factionId)) { 307 return 1; 308 } 309 if (Factions.REMNANTS.equals(p.factionId)) { 310 return 1; 311 } 312 313 return -1; 314 } 315 public float getQuality(SDMParams p, float quality, Random random, boolean withOverride) { 316 if (withOverride) return quality; 317 if (Factions.DERELICT.equals(p.factionId)) { 318 float bonus = Global.getSector().getMemoryWithoutUpdate().getFloat(DEFEATED_DERELICT_STR) * DEFEATED_TO_QUALITY_FACTOR; 319 return quality + bonus; 320 } 321 return quality; 322 } 323 } 324 325 public boolean execute(String ruleId, InteractionDialogAPI dialog, List<Token> params, final Map<String, MemoryAPI> memoryMap) { 326 if (dialog == null) return false; 327 328 SectorEntityToken entity = dialog.getInteractionTarget(); 329 String specId = entity.getCustomEntityType(); 330 if (specId == null || entity.getMemoryWithoutUpdate().contains(MemFlags.SALVAGE_SPEC_ID_OVERRIDE)) { 331 specId = entity.getMemoryWithoutUpdate().getString(MemFlags.SALVAGE_SPEC_ID_OVERRIDE); 332 } 333 SalvageEntityGenDataSpec spec = SalvageEntityGeneratorOld.getSalvageSpec(specId); 334 335 MemoryAPI memory = memoryMap.get(MemKeys.LOCAL); 336 if (memoryMap.containsKey(MemKeys.ENTITY)) { 337 memory = memoryMap.get(MemKeys.ENTITY); 338 } 339 340 long seed = memory.getLong(MemFlags.SALVAGE_SEED); 341 //seed = new Random().nextLong(); 342// if (Global.getSettings().isDevMode()) { 343// seed = new Random().nextLong(); 344// } 345 346 // don't use seed directly so that results from different uses of it aren't tied together 347 Random random = Misc.getRandom(seed, 0); 348 349 DefenderDataOverride override = null; 350 if (memory.contains(MemFlags.SALVAGE_DEFENDER_OVERRIDE)) { 351 override = (DefenderDataOverride) memory.get(MemFlags.SALVAGE_DEFENDER_OVERRIDE); 352 } 353 354 Random fleetRandom = Misc.getRandom(seed, 1); 355// if (Global.getSettings().isDevMode()) { 356// fleetRandom = Misc.random; 357// } 358 359 //fleetRandom = new Random(); 360 float strength = spec.getMinStr() + Math.round((spec.getMaxStr() - spec.getMinStr()) * fleetRandom.nextFloat()); 361 float prob = spec.getProbDefenders(); 362 363 if (override != null) { 364 strength = override.minStr + Math.round((override.maxStr - override.minStr) * fleetRandom.nextFloat()); 365 prob = override.probDefenders; 366 } 367 368 String factionId = entity.getFaction().getId(); 369 if (spec.getDefFaction() != null) { 370 factionId = spec.getDefFaction(); 371 } 372 if (override != null && override.defFaction != null) { 373 factionId = override.defFaction; 374 } 375 376 SDMParams p = new SDMParams(); 377 p.entity = entity; 378 p.factionId = factionId; 379 380 SalvageDefenderModificationPlugin plugin = Global.getSector().getGenericPlugins().pickPlugin( 381 SalvageDefenderModificationPlugin.class, p); 382 383 if (plugin != null) { 384 strength = plugin.getStrength(p, strength, random, override != null); 385 prob = plugin.getProbability(p, prob, random, override != null); 386 } 387 388 float probStation = spec.getProbStation(); 389 if (override != null) { 390 probStation = override.probStation; 391 } 392 String stationRole = null; 393 if (fleetRandom.nextFloat() < probStation) { 394 stationRole = spec.getStationRole(); 395 if (override != null && override.stationRole != null) { 396 stationRole = override.stationRole; 397 } 398 } 399 400 //prob = 1f; 401 //strength = 0; 402 403 if (((int) strength > 0 || stationRole != null) && 404 random.nextFloat() < prob && 405 !memory.getBoolean("$defenderFleetDefeated")) { 406 memory.set("$hasDefenders", true, 0); 407 408 if (!memory.contains("$defenderFleet") || DebugFlags.FORCE_REGEN_AUTOMATED_DEFENSES) { 409 float quality = spec.getDefQuality(); 410 if (plugin != null) { 411 quality = plugin.getQuality(p, quality, fleetRandom, override != null); 412 } 413 414 FleetParamsV3 fParams = new FleetParamsV3(null, null, 415 factionId, 416 quality, 417 FleetTypes.PATROL_SMALL, 418 (int) strength, 419 0, 0, 0, 0, 0, 0); 420 fParams.random = fleetRandom; 421 //fParams.withOfficers = false; 422 FactionAPI faction = Global.getSector().getFaction(factionId); 423 fParams.withOfficers = faction.getCustomBoolean(Factions.CUSTOM_OFFICERS_ON_AUTOMATED_DEFENSES); 424 425 fParams.maxShipSize = (int) spec.getMaxDefenderSize(); 426 if (override != null) { 427 fParams.maxShipSize = override.maxDefenderSize; 428 } 429 430 if (plugin != null) { 431 fParams.maxShipSize = (int) (plugin.getMaxSize(p, fParams.maxShipSize, random, override != null)); 432 } 433 434 fParams.minShipSize = (int) spec.getMinDefenderSize(); 435 if (override != null) { 436 fParams.minShipSize = override.minDefenderSize; 437 } 438 if (plugin != null) { 439 fParams.minShipSize = (int) (plugin.getMinSize(p, fParams.minShipSize, random, override != null)); 440 } 441 442 //fParams.allowEmptyFleet = true; 443 444 CampaignFleetAPI defenders = FleetFactoryV3.createFleet(fParams); 445 446 if (!defenders.isEmpty()) { 447 defenders.getInflater().setRemoveAfterInflating(false); 448 449 //defenders.setName(entity.getName() + ": " + "Automated Defenses"); 450 defenders.setName("Automated Defenses"); 451 452 if (stationRole != null) { 453 defenders.getFaction().pickShipAndAddToFleet(stationRole, ShipPickParams.all(), defenders, fleetRandom); 454 defenders.getFleetData().sort(); 455 } 456 457 defenders.clearAbilities(); 458 459 if (plugin != null) { 460 //System.out.println("NEXT: " + fleetRandom.nextLong()); 461 plugin.modifyFleet(p, defenders, fleetRandom, override != null); 462 } 463 464 defenders.getFleetData().sort(); 465 466 memory.set("$defenderFleet", defenders, 0); 467 468 } else { 469 memory.set("$hasDefenders", false, 0); 470 } 471 } 472 473 474 CampaignFleetAPI defenders = memory.getFleet("$defenderFleet"); 475 if (defenders != null) { 476 boolean hasStation = false; 477 boolean hasNonStation = false; 478 for (FleetMemberAPI member : defenders.getFleetData().getMembersListCopy()) { 479 if (member.isStation()) { 480 hasStation = true; 481 } else { 482 hasNonStation = true; 483 } 484 } 485 memory.set("$hasStation", hasStation, 0); 486 memory.set("$hasNonStation", hasNonStation, 0); 487 488 defenders.setLocation(entity.getLocation().x, entity.getLocation().y); 489 490 //Global.getSector().getCampaignUI().restartEncounterMusic(entity); 491 } 492 } else { 493 memory.set("$hasDefenders", false, 0); 494 memory.set("$hasStation", false, 0); 495 } 496 497 //memory.set("$hasSalvageSpecial", false, 0); 498 //memory.set("$salvageSpecialData", null, 0); 499 //memory.set("$salvageSpecialData", new DomainSurveyDerelictSpecialData(SpecialType.SCRAMBLED), 0); 500 501 502 return true; 503 } 504 505 506} 507 508 509 510