Run AbilityCast triggers for mana abilities (#345)

* Run AbilityCast triggers for mana abilities

* Fix for Vazi

* Update cards

* Make mana abilities undoable if they cause a trigger

* Reset undoable

* Cleanup related to Winter's Night
This commit is contained in:
tool4ever
2022-05-15 23:24:40 +02:00
committed by GitHub
parent aaee31e1c6
commit 573e7dfb23
19 changed files with 46 additions and 33 deletions

View File

@@ -60,15 +60,6 @@ public abstract class SpellAbilityEffect {
return sa.getDescription();
}
protected static final void resolveSubAbility(final SpellAbility sa) {
// if mana production has any type of SubAbility, undoable=false
final AbilitySub abSub = sa.getSubAbility();
if (abSub != null) {
sa.setUndoable(false);
AbilityUtils.resolve(abSub);
}
}
/**
* Returns this effect description with needed prelude and epilogue.
* @param params

View File

@@ -23,7 +23,7 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) {
// Spells are not undoable
AbilityManaPart ma = sa.getManaPart();
sa.setUndoable(sa.isAbility() && sa.isUndoable());
sa.setUndoable(sa.isAbility() && sa.isUndoable() && sa.getSubAbility() == null);
final Collection<String> colors = CardUtil.getReflectableManaColors(sa);
@@ -31,8 +31,6 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
final String generated = generatedReflectedMana(sa, colors, player);
ma.produceMana(generated, player, sa);
}
resolveSubAbility(sa);
}

View File

@@ -517,6 +517,12 @@ public class TriggerHandler {
abMana.setUndoable(false);
}
}
if (regtrig instanceof TriggerSpellAbilityCastOrCopy) {
final SpellAbility abMana = (SpellAbility) runParams.get(AbilityKey.CastSA);
if (null != abMana && null != abMana.getManaPart()) {
abMana.setUndoable(false);
}
}
SpellAbility sa = null;
Card host = regtrig.getHostCard();

View File

@@ -90,14 +90,23 @@ public class TriggerSpellAbilityCastOrCopy extends Trigger {
}
if (hasParam("ValidActivatingPlayer")) {
if (si == null || !matchesValid(si.getSpellAbility(true).getActivatingPlayer(), getParam("ValidActivatingPlayer").split(","))) {
Player activator;
if (spellAbility.isManaAbility()) {
activator = (Player) runParams.get(AbilityKey.Activator);
} else if (si == null) {
return false;
} else {
activator = si.getSpellAbility(true).getActivatingPlayer();
}
if (!matchesValidParam("ValidActivatingPlayer", activator)) {
return false;
}
if (hasParam("ActivatorThisTurnCast")) {
final String compare = getParam("ActivatorThisTurnCast");
final String valid = getParamOrDefault("ValidCard", "Card");
List<Card> thisTurnCast = CardUtil.getThisTurnCast(valid, getHostCard(), this);
thisTurnCast = CardLists.filterControlledBy(thisTurnCast, si.getSpellAbility(true).getActivatingPlayer());
thisTurnCast = CardLists.filterControlledBy(thisTurnCast, activator);
int left = thisTurnCast.size();
int right = Integer.parseInt(compare.substring(2));
if (!Expressions.compare(left, compare, right)) {
@@ -121,7 +130,6 @@ public class TriggerSpellAbilityCastOrCopy extends Trigger {
boolean validTgtFound = false;
while (sa != null && !validTgtFound) {
for (final Card tgt : sa.getTargets().getTargetCards()) {
if (matchesValid(tgt, getParam("TargetsValid").split(","))) {
validTgtFound = true;
if (this.hasParam("RememberValidCards")) {

View File

@@ -231,6 +231,18 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
}
if (sp.isManaAbility()) { // Mana Abilities go straight through
Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(sp.getHostCard().getController());
runParams.put(AbilityKey.Cost, sp.getPayCosts());
runParams.put(AbilityKey.Activator, sp.getActivatingPlayer());
runParams.put(AbilityKey.CastSA, sp);
game.getTriggerHandler().runTrigger(TriggerType.SpellAbilityCast, runParams, true);
if (sp.isActivatedAbility()) {
game.getTriggerHandler().runTrigger(TriggerType.AbilityCast, runParams, true);
}
// reset in case a trigger stopped it on a previous activation
sp.setUndoable(true);
AbilityUtils.resolve(sp);
game.getGameLog().add(GameLogEntryType.MANA, source + " - " + sp.getDescription());
sp.resetOnceResolved();
@@ -292,9 +304,8 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
si = push(sp);
// Copied spells aren't cast per se so triggers shouldn't run for them.
Map<AbilityKey, Object> runParams = AbilityKey.newMap();
Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(sp.getHostCard().getController());
runParams.put(AbilityKey.Cost, sp.getPayCosts());
runParams.put(AbilityKey.Player, sp.getHostCard().getController());
runParams.put(AbilityKey.Activator, sp.getActivatingPlayer());
runParams.put(AbilityKey.CastSA, si.getSpellAbility(true));
runParams.put(AbilityKey.CastSACMC, si.getSpellAbility(true).getHostCard().getCMC());

View File

@@ -3,6 +3,6 @@ ManaCost:2 R
Types:Artifact Equipment
K:Equip:2
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddKeyword$ Haste | Description$ Equipped creature has haste.
T:Mode$ AbilityCast | ValidCard$ Creature.EquippedBy+inRealZoneBattlefield | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigCopyAbility | TriggerDescription$ Whenever an ability of equipped creature is activated, if it isn't a mana ability, you may pay {1}. If you do, copy that ability. You may choose new targets for the copy.
T:Mode$ AbilityCast | ValidCard$ Creature.EquippedBy+inRealZoneBattlefield | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigCopyAbility | TriggerDescription$ Whenever an ability of equipped creature is activated, if it isn't a mana ability, you may pay {1}. If you do, copy that ability. You may choose new targets for the copy.
SVar:TrigCopyAbility:AB$ CopySpellAbility | Cost$ 1 | Defined$ TriggeredSpellAbility | MayChooseTarget$ True
Oracle:Equipped creature has haste.\nWhenever an ability of equipped creature is activated, if it isn't a mana ability, you may pay {1}. If you do, copy that ability. You may choose new targets for the copy.\nEquip {2}

View File

@@ -2,6 +2,6 @@ Name:Burning-Tree Shaman
ManaCost:1 R G
Types:Creature Centaur Shaman
PT:3/4
T:Mode$ AbilityCast | ValidActivatingPlayer$ Player | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever a player activates an ability that isn't a mana ability, CARDNAME deals 1 damage to that player.
T:Mode$ AbilityCast | ValidActivatingPlayer$ Player | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever a player activates an ability that isn't a mana ability, CARDNAME deals 1 damage to that player.
SVar:TrigDmg:DB$ DealDamage | NumDmg$ 1 | Defined$ TriggeredActivator
Oracle:Whenever a player activates an ability that isn't a mana ability, Burning-Tree Shaman deals 1 damage to that player.

View File

@@ -3,6 +3,5 @@ ManaCost:3 R
Types:Creature Elemental Warrior
PT:2/4
T:Mode$ AbilityCast | ValidCard$ Elemental.inZoneBattlefield | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you activate an ability of an Elemental, CARDNAME gets +1/+0 until end of turn.
T:Mode$ TapsForMana | ValidCard$ Elemental.inZoneBattlefield | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you activate an ability of an Elemental, CARDNAME gets +1/+0 until end of turn.
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ +1 | NumDef$ +0
Oracle:Whenever you activate an ability of an Elemental, Ceaseless Searblades gets +1/+0 until end of turn.

View File

@@ -2,6 +2,6 @@ Name:Crackdown Construct
ManaCost:4
Types:Artifact Creature Construct
PT:2/2
T:Mode$ AbilityCast | ValidCard$ Artifact.inZoneBattlefield,Creature.inZoneBattlefield | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you activate an ability of an artifact or creature that isn't a mana ability, Crackdown Construct gets +1/+1 until end of turn.
T:Mode$ AbilityCast | ValidCard$ Artifact.inZoneBattlefield,Creature.inZoneBattlefield | ValidSA$ SpellAbility.nonManaAbility | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you activate an ability of an artifact or creature that isn't a mana ability, Crackdown Construct gets +1/+1 until end of turn.
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ +1 | NumDef$ +1
Oracle:Whenever you activate an ability of an artifact or creature that isn't a mana ability, Crackdown Construct gets +1/+1 until end of turn.

View File

@@ -2,7 +2,7 @@ Name:Flamescroll Celebrant
ManaCost:1 R
Types:Creature Human Shaman
PT:2/1
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent activates an ability that isn't a mana ability, CARDNAME deals 1 damage to that player.
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent activates an ability that isn't a mana ability, CARDNAME deals 1 damage to that player.
SVar:TrigDmg:DB$ DealDamage | NumDmg$ 1 | Defined$ TriggeredActivator
A:AB$ Pump | Cost$ 1 R | Defined$ Self | NumAtt$ +2 | SpellDescription$ CARDNAME gets +2/+0 until end of turn.
AlternateMode:Modal

View File

@@ -2,7 +2,7 @@ Name:Grip of Chaos
ManaCost:4 R R
Types:Enchantment
T:Mode$ SpellAbilityCopy | IsSingleTarget$ True | TriggerZones$ Battlefield | Execute$ TrigChangeTarget | TriggerDescription$ Whenever a spell or ability is put onto the stack, if it has a single target, reselect its target at random. (Select from among all legal targets.)
T:Mode$ SpellAbilityCast | IsSingleTarget$ True | TriggerZones$ Battlefield | Execute$ TrigChangeTarget | TriggerDescription$ Whenever a spell or ability is put onto the stack, if it has a single target, reselect its target at random. (Select from among all legal targets.)
T:Mode$ SpellAbilityCast | ValidSA$ SpellAbility.nonManaAbility | IsSingleTarget$ True | TriggerZones$ Battlefield | Execute$ TrigChangeTarget | TriggerDescription$ Whenever a spell or ability is put onto the stack, if it has a single target, reselect its target at random. (Select from among all legal targets.)
SVar:TrigChangeTarget:DB$ ChangeTargets | Defined$ TriggeredSpellAbility | RandomTarget$ True
AI:RemoveDeck:Random
Oracle:Whenever a spell or ability is put onto the stack, if it has a single target, reselect its target at random. (Select from among all legal targets.)

View File

@@ -2,6 +2,6 @@ Name:Harsh Mentor
ManaCost:1 R
Types:Creature Human Cleric
PT:2/2
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | ValidCard$ Artifact.inZoneBattlefield,Creature.inZoneBattlefield,Land.inZoneBattlefield | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent activates an ability of an artifact, creature, or land on the battlefield, if it isn't a mana ability, CARDNAME deals 2 damage to that player.
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | ValidCard$ Artifact.inZoneBattlefield,Creature.inZoneBattlefield,Land.inZoneBattlefield | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent activates an ability of an artifact, creature, or land on the battlefield, if it isn't a mana ability, CARDNAME deals 2 damage to that player.
SVar:TrigDmg:DB$ DealDamage | NumDmg$ 2 | Defined$ TriggeredActivator
Oracle:Whenever an opponent activates an ability of an artifact, creature, or land on the battlefield, if it isn't a mana ability, Harsh Mentor deals 2 damage to that player.

View File

@@ -2,6 +2,6 @@ Name:Illusionist's Bracers
ManaCost:2
Types:Artifact Equipment
K:Equip:3
T:Mode$ AbilityCast | ValidCard$ Creature.EquippedBy+inRealZoneBattlefield | TriggerZones$ Battlefield | Execute$ TrigCopyAbility | OptionalDecider$ You | TriggerDescription$ Whenever an ability of equipped creature is activated, if it isn't a mana ability, copy that ability. You may choose new targets for the copy.
T:Mode$ AbilityCast | ValidCard$ Creature.EquippedBy+inRealZoneBattlefield | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | Execute$ TrigCopyAbility | OptionalDecider$ You | TriggerDescription$ Whenever an ability of equipped creature is activated, if it isn't a mana ability, copy that ability. You may choose new targets for the copy.
SVar:TrigCopyAbility:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True
Oracle:Whenever an ability of equipped creature is activated, if it isn't a mana ability, copy that ability. You may choose new targets for the copy.\nEquip {3}

View File

@@ -2,7 +2,7 @@ Name:Immolation Shaman
ManaCost:1 R
Types:Creature Viashino Shaman
PT:1/3
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | ValidCard$ Artifact.inZoneBattlefield,Creature.inZoneBattlefield,Land.inZoneBattlefield | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent activates an ability of an artifact, creature, or land that isn't a mana ability, CARDNAME deals 1 damage to that player.
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | ValidCard$ Artifact.inZoneBattlefield,Creature.inZoneBattlefield,Land.inZoneBattlefield | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent activates an ability of an artifact, creature, or land that isn't a mana ability, CARDNAME deals 1 damage to that player.
SVar:TrigDmg:DB$ DealDamage | NumDmg$ 1 | Defined$ TriggeredActivator
A:AB$ Pump | Cost$ 3 R R | Defined$ Self | NumAtt$ +3 | NumDef$ +3 | KW$ Menace | SpellDescription$ CARDNAME gets +3/+3 and gains menace until end of turn.
Oracle:Whenever an opponent activates an ability of an artifact, creature, or land that isn't a mana ability, Immolation Shaman deals 1 damage to that player.\n{3}{R}{R}: Immolation Shaman gets +3/+3 and gains menace until end of turn.

View File

@@ -3,7 +3,7 @@ ManaCost:B
Types:Enchantment Aura
K:Enchant creature
A:SP$ Attach | Cost$ B | ValidTgts$ Creature | AILogic$ Curse
T:Mode$ AbilityCast | ValidCard$ Creature.EnchantedBy | HasTapCost$ True | TriggerZones$ Battlefield | Execute$ TrigDestroy1 | TriggerDescription$ Whenever a player activates an ability of enchanted creature with {T} in its activation cost that isn't a mana ability, you may pay {1}. If you do, counter that ability. If you don't, destroy CARDNAME.
T:Mode$ AbilityCast | ValidCard$ Creature.EnchantedBy | ValidSA$ SpellAbility.nonManaAbility | HasTapCost$ True | TriggerZones$ Battlefield | Execute$ TrigDestroy1 | TriggerDescription$ Whenever a player activates an ability of enchanted creature with {T} in its activation cost that isn't a mana ability, you may pay {1}. If you do, counter that ability. If you don't, destroy CARDNAME.
SVar:TrigDestroy1:DB$ Destroy | Defined$ Self | UnlessCost$ 1 | UnlessPayer$ You | UnlessResolveSubs$ WhenPaid | SubAbility$ DBCounter
SVar:DBCounter:DB$ Counter | Defined$ TriggeredSpellAbility
T:Mode$ Attacks | ValidCard$ Card.EnchantedBy | TriggerZones$ Battlefield | Execute$ TrigDestroy2 | TriggerDescription$ Whenever enchanted creature attacks or blocks, you may pay {1}. If you do, tap the creature, remove it from combat, and creatures it was blocking that had become blocked by only that creature this combat become unblocked. If you don't, destroy CARDNAME.

View File

@@ -2,6 +2,6 @@ Name:Kurkesh, Onakke Ancient
ManaCost:2 R R
Types:Legendary Creature Ogre Spirit
PT:4/3
T:Mode$ AbilityCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigCopyAbility | TriggerDescription$ Whenever you activate an ability of an artifact, if it isn't a mana ability, you may pay {R}. If you do, copy that ability. You may choose new targets for the copy.
T:Mode$ AbilityCast | ValidCard$ Artifact | ValidSA$ SpellAbility.nonManaAbility | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigCopyAbility | TriggerDescription$ Whenever you activate an ability of an artifact, if it isn't a mana ability, you may pay {R}. If you do, copy that ability. You may choose new targets for the copy.
SVar:TrigCopyAbility:AB$ CopySpellAbility | Cost$ R | Defined$ TriggeredSpellAbility | MayChooseTarget$ True
Oracle:Whenever you activate an ability of an artifact, if it isn't a mana ability, you may pay {R}. If you do, copy that ability. You may choose new targets for the copy.

View File

@@ -1,6 +1,6 @@
Name:Rings of Brighthearth
ManaCost:3
Types:Artifact
T:Mode$ AbilityCast | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigCopySpell | OptionalDecider$ You | TriggerDescription$ Whenever you activate an ability, if it isn't a mana ability, you may pay {2}. If you do, copy that ability. You may choose new targets for the copy.
T:Mode$ AbilityCast | ValidActivatingPlayer$ You | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | Execute$ TrigCopySpell | OptionalDecider$ You | TriggerDescription$ Whenever you activate an ability, if it isn't a mana ability, you may pay {2}. If you do, copy that ability. You may choose new targets for the copy.
SVar:TrigCopySpell:AB$ CopySpellAbility | Cost$ 2 | Defined$ TriggeredSpellAbility | MayChooseTarget$ True
Oracle:Whenever you activate an ability, if it isn't a mana ability, you may pay {2}. If you do, copy that ability. You may choose new targets for the copy.

View File

@@ -11,7 +11,7 @@ SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ DamageAll | Cost$ SubCounter<2/LOYALTY> | ValidTgts$ Player | TgtPrompt$ Select target player | NumDmg$ 3 | ValidCards$ Creature.tapped | Planeswalker$ True | ValidDescription$ each tapped creature target player controls. | SpellDescription$ CARDNAME deals 3 damage to each tapped creature target player controls
A:AB$ Effect | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Player | EffectOwner$ Targeted | Name$ Emblem - Rowan Kenrith | Image$ emblem_rowan_kenrith | Triggers$ CopyAbility | Duration$ Permanent | AILogic$ Always | SpellDescription$ Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."
SVar:CopyAbility:Mode$ AbilityCast | ValidActivatingPlayer$ You | TriggerZones$ Command | Execute$ TrigCopy | TriggerDescription$ Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy.
SVar:CopyAbility:Mode$ AbilityCast | ValidActivatingPlayer$ You | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Command | Execute$ TrigCopy | TriggerDescription$ Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy.
SVar:TrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True
DeckHints:Name$Will Kenrith
Oracle:[+2]: During target player's next turn, each creature that player controls attacks if able.\n[-2]: Rowan Kenrith deals 3 damage to each tapped creature target player controls.\n[-8]: Target player gets an emblem with "Whenever you activate an ability that isn't a mana ability, copy it. You may choose new targets for the copy."\nPartner with Will Kenrith\nRowan Kenrith can be your commander.

View File

@@ -2,6 +2,6 @@ Name:Runic Armasaur
ManaCost:1 G G
Types:Creature Dinosaur
PT:2/5
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | ValidCard$ Creature.inZoneBattlefield,Land.inZoneBattlefield | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent activates an ability of a creature or land that isn't a mana ability, you may draw a card.
T:Mode$ AbilityCast | ValidActivatingPlayer$ Opponent | ValidCard$ Creature.inZoneBattlefield,Land.inZoneBattlefield | ValidSA$ SpellAbility.nonManaAbility | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent activates an ability of a creature or land that isn't a mana ability, you may draw a card.
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1
Oracle:Whenever an opponent activates an ability of a creature or land that isn't a mana ability, you may draw a card.