protected void spawnWreck(StarSystemAPI system) {
WeightedRandomPicker<String> factions = SalvageSpecialAssigner.getNearbyFactions(null, system.getLocation(), 15f, 5f, 5f);
String faction = factions.pick();
String variantId = DerelictShipEntityPlugin.pickLargeVariantId(faction, new Random());
ShipCondition condition = Math.random() > 0.5f ? ShipCondition.PRISTINE : ShipCondition.GOOD;
DerelictShipEntityPlugin.DerelictShipData params = new DerelictShipEntityPlugin.DerelictShipData(new ShipRecoverySpecial.PerShipData(variantId, condition), false);
params.durationDays = duration;
entity = (CustomCampaignEntityAPI) BaseThemeGenerator.addSalvageEntity(system, Entities.WRECK, Factions.NEUTRAL, params);
entity.addTag(Tags.EXPIRES);
DerelictShipEntityPlugin plugin = new DerelictShipEntityPlugin();
plugin.init(entity, params);
Misc.setSalvageSpecial(entity, (Object) new VayraGhostShipSpecial.VayraGhostShipSpecialData((CustomCampaignEntityAPI) entity));
entity.setName("Derelict Ship (" + Global.getSettings().getVariant(variantId).getFullDesignationWithHullName() + ")");
}
public static class VayraGhostShipSpecialData implements SalvageSpecialInteraction.SalvageSpecialData {
public Danger danger;
public Type type;
public CustomCampaignEntityAPI entity;
public ShipVariantAPI variant;
public VayraGhostShipSpecialData(CustomCampaignEntityAPI entity) {
this.entity = entity;
DerelictShipEntityPlugin plugin = (DerelictShipEntityPlugin) entity.getCustomPlugin();
PerShipData shipData = plugin.getData().ship;
this.variant = shipData.variant;
if (this.variant == null) {
this.variant = Global.getSettings().getVariant(shipData.variantId);
}
shipData.variantId = null;
this.variant = this.variant.clone();
this.danger = DANGERS.pick();
log.info("picked danger level " + this.danger);
if (this.danger.equals(Danger.NONE)) {
this.type = null;
log.info("not picking a danger type");
} else {
this.type = TYPES.pick();
log.info("picked danger type " + this.type);
}
}
@Override
public SalvageSpecialInteraction.SalvageSpecialPlugin createSpecialPlugin() {
return new VayraGhostShipSpecial();
}
}
@Override
public void optionSelected(String optionText, Object optionData) {
if (CONFIRM.equals(optionData)) {
(a whole bunch of stuff/other options go here)
} else if (NEVER_AGAIN.equals(optionData)) {
setDone(true);
setShowAgain(false);
setEndWithContinue(false);
}
if (recoverable) {
SalvageSpecialAssigner.ShipRecoverySpecialCreator creator = new SalvageSpecialAssigner.ShipRecoverySpecialCreator(null, 0, 0, false, null, null);
ShipRecoverySpecialData specialData = (ShipRecoverySpecialData) creator.createSpecial(entity, null);
Misc.setSalvageSpecial(entity, specialData);
ShipRecoverySpecial special = new ShipRecoverySpecial();
special.init(dialog, specialData);
setDone(true);
setShowAgain(false);
}
}
@Vayra: this probably isn't the best thread for it because it's too involved, so might be better to have a separate thread for any follow-up. That said, the way you're creating the ship recovery special is missing some stuff. Here's an example creating one for a derelict:
ShipRecoverySpecialData data = new ShipRecoverySpecialData(null);
DerelictShipEntityPlugin plugin = (DerelictShipEntityPlugin) entity.getCustomPlugin();
data.addShip(plugin.getData().ship.clone());
Misc.setSalvageSpecial(entity, data);
The part you're missing is calling .addShip() for the ShipRecoverySpecialData.
The other issue is the flow of it - you're already in a "special" interaction, and when it ends, it'll unset the "special" data in the entity memory, since you've called setShowAgain(false). You want to call setShowAgain(true), so that it keeps the special data around (the code is assuming it's the old data, but it'll be the data you switched in using Misc.setSalvageSpecial.
However, even with that, I don't believe it'll chain to showing that special - it'll move on straight to salvage, per the sal_specialFinished rule. What you'll want to do is create another rule for the SalvageSpecialFinished trigger (and set a variable in entity memory from your "if (recoverable) {" block so you can tell when to use this rule), and have that rule "FireBest CheckSalvageSpecial" so that on finishing salvage, it loops back around to check for the special again, this time it being the newly-set ship recovery special.
Hope that makes sense!
if (recoverable) {
log.info("recovering ghost ship");
SalvageSpecialAssigner.ShipRecoverySpecialCreator creator = new SalvageSpecialAssigner.ShipRecoverySpecialCreator(null, 0, 0, false, null, null);
ShipRecoverySpecialData specialData = (ShipRecoverySpecialData) creator.createSpecial(entity, null);
specialData.addShip(data.shipData);
Misc.setSalvageSpecial(entity, specialData);
ShipRecoverySpecial special = new ShipRecoverySpecial();
special.init(dialog, specialData);
entity.getMemory().set(CHECK_SPECIAL, true);
setDone(true);
setEndWithContinue(true);
setShowAgain(true);
} else if (destroy) {
log.info("destroying ghost ship");
entity.getMemory().set(DESTROY_SHIP, true);
setDone(true);
setEndWithContinue(true);
setShowAgain(false);
}
Rules - Picked: vayra_ghostShipFinishedNoContinue
Rules - Looking for best match
Rules - Memory:
Rules - Found 2 rules for trigger [CheckSalvageSpecial]
Rules - Checking rule: sal_checkSpecialFound
Rules - Conditions: $salvageSpecialData != null
Rules - All conditions passed, score 1
Rules - Checking rule: sal_checkSpecialNoneFound
Rules - Conditions:
Rules - All conditions passed, score 0
Rules - Number of matches with same score: 1, picking one randomly.
Rules - Picked: sal_checkSpecialFound
Rules - Looking for best match
Rules - Memory:
Rules - Found 3 rules for trigger [SalvageSpecialFinishedNoContinue]
Rules - Checking rule: sal_specialFinishedNoContinue
Rules - Conditions:
Rules - All conditions passed, score 0
Rules - Checking rule: vayra_ghostShipFinishedNoContinue
Rules - Conditions: $vayra_checkSalvageSpecialAgain score:1000
Rules - All conditions passed, score 1000
Rules - Checking rule: vayra_ghostShipFinishedNoContinueDestroyed
Rules - Conditions: $vayra_destroyGhostShip score:1000
Rules - Failed condition: $vayra_destroyGhostShip score:1000
Rules - Number of matches with same score: 1, picking one randomly.
Rules - Picked: vayra_ghostShipFinishedNoContinue
Rules - Looking for best match
Rules - Memory:
Rules - Found 2 rules for trigger [CheckSalvageSpecial]
Rules - Checking rule: sal_checkSpecialFound
Rules - Conditions: $salvageSpecialData != null
Rules - Failed condition: $salvageSpecialData != null
Rules - Checking rule: sal_checkSpecialNoneFound
Rules - Conditions:
Rules - All conditions passed, score 0
Rules - Number of matches with same score: 1, picking one randomly.
Rules - Picked: sal_checkSpecialNoneFound
Rules - Looking for best match
Rules - Memory:
Rules - Found 4 rules for trigger [BeginSalvage]
Rules - Checking rule: sal_showRatingAndCost
Rules - Conditions:
Rules - All conditions passed, score 0
Rules - Checking rule: saic_openDialog
Rules - Conditions: $saic_eventRef != null score:1000
Rules - Failed condition: $saic_eventRef != null score:1000
Rules - Checking rule: cryo_infoText
Rules - Conditions: $customType == derelict_cryosleeper score:1000
Rules - Failed condition: $customType == derelict_cryosleeper score:1000
Rules - Checking rule: psi_beatDefenders
Rules - Conditions: $psi_planet score:1000
Rules - Failed condition: $psi_planet score:1000
Rules - Number of matches with same score: 1, picking one randomly.
Rules - Picked: sal_showRatingAndCost
However, the other one appears to trigger, find the special but not do anything about it, clear the special, trigger again, and since there's no longer a special, proceed directly to salvaging (with or without a 'continue' in between):
Are you adding it to your large mod or making a new one? Sounds very interesting.
What does this do necessarily? Does it create some fleet that disappears? Is it a mission?
salvage team: *loading gun* ship's haunted