mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
Trigger: reuse Execute for multiple Trigger (#9094)
* Trigger: reuse Execute for multiple Trigger * Update CardState.java copy abilityForTrigger * Update CardState.java * Update Trigger.java * Update CardState.java * Fix Multi Trigger with Idris * Fix Oasis of Renewal ActivationLimit * fix storedAbilityForTrigger * remove hasAbilityForTrigger * Update script --------- Co-authored-by: tool4EvEr <tool4EvEr@>
This commit is contained in:
@@ -140,6 +140,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
// stores the card traits created by static abilities
|
||||
private final Table<StaticAbility, String, SpellAbility> storedSpellAbility = TreeBasedTable.create();
|
||||
private final Table<StaticAbility, String, Trigger> storedTrigger = TreeBasedTable.create();
|
||||
private final Table<StaticAbility, SpellAbility, SpellAbility> storedAbilityForTrigger = HashBasedTable.create();
|
||||
private final Table<StaticAbility, String, ReplacementEffect> storedReplacementEffect = TreeBasedTable.create();
|
||||
private final Table<StaticAbility, String, StaticAbility> storedStaticAbility = TreeBasedTable.create();
|
||||
|
||||
@@ -4974,7 +4975,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
String str = trig.toString() + trig.getId();
|
||||
Trigger result = storedTrigger.get(stAb, str);
|
||||
if (result == null) {
|
||||
result = trig.copy(this, false);
|
||||
SpellAbility ab = null;
|
||||
if (trig.hasParam("Execute") && trig.getOverridingAbility() != null) {
|
||||
ab = storedAbilityForTrigger.get(stAb, trig.getOverridingAbility());
|
||||
if (ab == null) {
|
||||
ab = trig.getOverridingAbility().copy(this, false);
|
||||
storedAbilityForTrigger.put(stAb, trig.getOverridingAbility(), ab);
|
||||
}
|
||||
}
|
||||
result = trig.copy(this, false, false, ab);
|
||||
storedTrigger.put(stAb, str, result);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -79,6 +79,7 @@ public class CardState implements GameObject, IHasSVars, ITranslatable {
|
||||
private FCollection<StaticAbility> staticAbilities = new FCollection<>();
|
||||
private String imageKey = "";
|
||||
private Map<String, String> sVars = Maps.newTreeMap();
|
||||
private Map<String, SpellAbility> abilityForTrigger = Maps.newHashMap();
|
||||
|
||||
private KeywordCollection cachedKeywords = new KeywordCollection();
|
||||
|
||||
@@ -732,6 +733,11 @@ public class CardState implements GameObject, IHasSVars, ITranslatable {
|
||||
setFlavorName(source.getFlavorName());
|
||||
setSVars(source.getSVars());
|
||||
|
||||
abilityForTrigger.clear();
|
||||
for (Map.Entry<String, SpellAbility> e : source.abilityForTrigger.entrySet()) {
|
||||
abilityForTrigger.put(e.getKey(), e.getValue().copy(card, lki));
|
||||
}
|
||||
|
||||
abilities.clear();
|
||||
for (SpellAbility sa : source.abilities) {
|
||||
if (sa.isIntrinsic()) {
|
||||
@@ -758,7 +764,7 @@ public class CardState implements GameObject, IHasSVars, ITranslatable {
|
||||
continue;
|
||||
}
|
||||
if (tr.isIntrinsic()) {
|
||||
triggers.add(tr.copy(card, lki));
|
||||
triggers.add(tr.copy(card, lki, false, tr.hasParam("Execute") ? abilityForTrigger.get(tr.getParam("Execute")) : null));
|
||||
}
|
||||
}
|
||||
ReplacementEffect runRE = null;
|
||||
@@ -951,6 +957,10 @@ public class CardState implements GameObject, IHasSVars, ITranslatable {
|
||||
return cloakUp;
|
||||
}
|
||||
|
||||
public SpellAbility getAbilityForTrigger(String svar) {
|
||||
return abilityForTrigger.computeIfAbsent(svar, s -> AbilityFactory.getAbility(getCard(), s, this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey() {
|
||||
String displayName = flavorName == null ? name : flavorName;
|
||||
|
||||
@@ -544,14 +544,19 @@ public abstract class Trigger extends TriggerReplacementBase {
|
||||
}
|
||||
|
||||
public final Trigger copy(Card newHost, boolean lki) {
|
||||
return copy(newHost, lki, false);
|
||||
return copy(newHost, lki, false, null);
|
||||
}
|
||||
public final Trigger copy(Card newHost, boolean lki, boolean keepTextChanges) {
|
||||
return copy(newHost, lki, keepTextChanges, null);
|
||||
}
|
||||
public final Trigger copy(Card newHost, boolean lki, boolean keepTextChanges, SpellAbility spellAbility) {
|
||||
final Trigger copy = (Trigger) clone();
|
||||
|
||||
copyHelper(copy, newHost, lki || keepTextChanges);
|
||||
|
||||
if (getOverridingAbility() != null) {
|
||||
if (spellAbility != null) {
|
||||
copy.setOverridingAbility(spellAbility);
|
||||
} else if (getOverridingAbility() != null) {
|
||||
copy.setOverridingAbility(getOverridingAbility().copy(newHost, lki));
|
||||
}
|
||||
|
||||
@@ -611,7 +616,11 @@ public abstract class Trigger extends TriggerReplacementBase {
|
||||
public SpellAbility ensureAbility(final IHasSVars sVarHolder) {
|
||||
SpellAbility sa = getOverridingAbility();
|
||||
if (sa == null && hasParam("Execute")) {
|
||||
sa = AbilityFactory.getAbility(getHostCard(), getParam("Execute"), sVarHolder);
|
||||
if (this.isIntrinsic() && sVarHolder instanceof CardState state) {
|
||||
sa = state.getAbilityForTrigger(getParam("Execute"));
|
||||
} else {
|
||||
sa = AbilityFactory.getAbility(getHostCard(), getParam("Execute"), sVarHolder);
|
||||
}
|
||||
setOverridingAbility(sa);
|
||||
}
|
||||
return sa;
|
||||
|
||||
@@ -3,12 +3,8 @@ ManaCost:4 U
|
||||
Types:Enchantment
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigIncubate | TriggerDescription$ When CARDNAME enters, incubate 4. (Create an Incubator token with four +1/+1 counters on it and "{2}: Transform this artifact." It transforms into a 0/0 Phyrexian artifact creature.)
|
||||
SVar:TrigIncubate:DB$ Incubate | Amount$ 4
|
||||
T:Mode$ Transformed | ValidCard$ Permanent.YouCtrl+inZoneBattlefield | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | CheckSVar$ X | SVarCompare$ LT1 | TriggerDescription$ Whenever a permanent you control transforms or a permanent you control enters transformed, you may draw a card. Do this only once each turn.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Permanent.Transformed+YouCtrl | OptionalDecider$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | Secondary$ True | CheckSVar$ X | SVarCompare$ LT1 | TriggerDescription$ Whenever a permanent you control transforms or a permanent you control enters transformed, you may draw a card. Do this only once each turn.
|
||||
SVar:TrigDraw:DB$ Draw | SubAbility$ DBLog
|
||||
SVar:DBLog:DB$ StoreSVar | SVar$ X | Type$ Number | Expression$ 1
|
||||
SVar:X:Number$0
|
||||
T:Mode$ Phase | Phase$ Cleanup | TriggerZones$ Battlefield | Execute$ DBCleanup | Static$ True
|
||||
SVar:DBCleanup:DB$ StoreSVar | SVar$ X | Type$ Number | Expression$ 0
|
||||
T:Mode$ Transformed | ValidCard$ Permanent.YouCtrl+inZoneBattlefield | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | ResolvedLimit$ 1 | TriggerDescription$ Whenever a permanent you control transforms or a permanent you control enters transformed, you may draw a card. Do this only once each turn.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Permanent.Transformed+YouCtrl | OptionalDecider$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | Secondary$ True | ResolvedLimit$ 1 | TriggerDescription$ Whenever a permanent you control transforms or a permanent you control enters transformed, you may draw a card. Do this only once each turn.
|
||||
SVar:TrigDraw:DB$ Draw
|
||||
DeckHas:Ability$Counters|Token & Type$Incubator|Artifact|Phyrexian
|
||||
Oracle:When Corruption of Towashi enters, incubate 4. (Create an Incubator token with four +1/+1 counters on it and "{2}: Transform this artifact." It transforms into a 0/0 Phyrexian artifact creature.)\nWhenever a permanent you control transforms or a permanent you control enters transformed, you may draw a card. Do this only once each turn.
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
Name:Oasis of Renewal
|
||||
ManaCost:B G U
|
||||
Types:Legendary Enchantment
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeekLand | TriggerDescription$ When CARDNAME enters and whenever a land card leaves your graveyard, seek a land card. This ability triggers only once each turn.
|
||||
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Any | ValidCard$ Card.Land+YouOwn | TriggerZones$ Battlefield | Execute$ TrigSeekLand | Secondary$ True | CheckSVar$ X | SVarCompare$ LT1 | TriggerDescription$ When CARDNAME enters and whenever a land card leaves your graveyard, seek a land card. This ability triggers only once each turn.
|
||||
SVar:TrigSeekLand:DB$ Seek | Type$ Card.Land | SubAbility$ DBLogLand
|
||||
SVar:DBLogLand:DB$ StoreSVar | SVar$ X | Type$ Number | Expression$ 1
|
||||
SVar:X:Number$0
|
||||
T:Mode$ Phase | Phase$ Cleanup | TriggerZones$ Battlefield | Execute$ DBLandClean | Static$ True
|
||||
SVar:DBLandClean:DB$ StoreSVar | SVar$ X | Type$ Number | Expression$ 0
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigSeekNonLand | TriggerDescription$ When CARDNAME enters and whenever a nonland card leaves your graveyard, seek a nonland card. This ability triggers only once each turn.
|
||||
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Any | ValidCard$ Card.nonLand+YouOwn | TriggerZones$ Battlefield | Execute$ TrigSeekNonLand | Secondary$ True | CheckSVar$ Y | SVarCompare$ LT1 | TriggerDescription$ When CARDNAME enters and whenever a nonland card leaves your graveyard, seek a nonland card. This ability triggers only once each turn.
|
||||
SVar:TrigSeekNonLand:DB$ Seek | Type$ Card.nonLand | SubAbility$ DBLogNonLand
|
||||
SVar:DBLogNonLand:DB$ StoreSVar | SVar$ Y | Type$ Number | Expression$ 1
|
||||
SVar:Y:Number$0
|
||||
T:Mode$ Phase | Phase$ Cleanup | TriggerZones$ Battlefield | Execute$ DBNonLandClean | Static$ True
|
||||
SVar:DBNonLandClean:DB$ StoreSVar | SVar$ Y | Type$ Number | Expression$ 0
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | ActivationLimit$ 1 | Execute$ TrigSeekLand | TriggerDescription$ When CARDNAME enters and whenever a land card leaves your graveyard, seek a land card. This ability triggers only once each turn.
|
||||
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Any | ValidCard$ Card.Land+YouOwn | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigSeekLand | Secondary$ True | TriggerDescription$ When CARDNAME enters and whenever a land card leaves your graveyard, seek a land card. This ability triggers only once each turn.
|
||||
SVar:TrigSeekLand:DB$ Seek | Type$ Card.Land
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | ActivationLimit$ 1 | Execute$ TrigSeekNonLand | TriggerDescription$ When CARDNAME enters and whenever a nonland card leaves your graveyard, seek a nonland card. This ability triggers only once each turn.
|
||||
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Any | ValidCard$ Card.nonLand+YouOwn | TriggerZones$ Battlefield | ActivationLimit$ 1 | Execute$ TrigSeekNonLand | Secondary$ True | TriggerDescription$ When CARDNAME enters and whenever a nonland card leaves your graveyard, seek a nonland card. This ability triggers only once each turn.
|
||||
SVar:TrigSeekNonLand:DB$ Seek | Type$ Card.nonLand
|
||||
Oracle:When Oasis of Renewal enters and whenever a land card leaves your graveyard, seek a land card. This ability triggers only once each turn.\nWhen Oasis of Renewal enters and whenever a nonland card leaves your graveyard, seek a nonland card. This ability triggers only once each turn.
|
||||
|
||||
@@ -4,12 +4,9 @@ Types:Legendary Creature Human Warlock
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigSurveil | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.
|
||||
SVar:TrigSurveil:DB$ Surveil | Amount$ 2 | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ1 | SubAbility$ DBDiscard
|
||||
SVar:DBDiscard:DB$ Discard | Defined$ Player.Opponent | Mode$ TgtChoose | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ2 | SubAbility$ DBChangeZone
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature | ChangeNum$ 1 | Mandatory$ True | GainControl$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ3 | SelectPrompt$ Select a creature card in a graveyard | Hidden$ True | SubAbility$ DBLog
|
||||
SVar:DBLog:DB$ StoreSVar | SVar$ X | Type$ CountSVar | Expression$ X/Plus.1
|
||||
SVar:X:Number$1
|
||||
T:Mode$ Phase | Phase$ Cleanup | TriggerZones$ Battlefield | Execute$ DBCleanup | Static$ True
|
||||
SVar:DBCleanup:DB$ StoreSVar | SVar$ X | Type$ Number | Expression$ 1
|
||||
SVar:TrigSurveil:DB$ Surveil | Amount$ 2 | ConditionCheckSVar$ Resolved | ConditionSVarCompare$ EQ1 | SubAbility$ DBDiscard
|
||||
SVar:DBDiscard:DB$ Discard | Defined$ Player.Opponent | Mode$ TgtChoose | ConditionCheckSVar$ Resolved | ConditionSVarCompare$ EQ2 | SubAbility$ DBChangeZone
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature | ChangeNum$ 1 | Mandatory$ True | GainControl$ True | ConditionCheckSVar$ Resolved | ConditionSVarCompare$ EQ3 | SelectPrompt$ Select a creature card in a graveyard | Hidden$ True
|
||||
SVar:Resolved:Count$ResolvedThisTurn
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.
|
||||
|
||||
Reference in New Issue
Block a user