forked from External/mage
Fix Sanctuary Blade ability causing a trigger (#11682)
* Fix Sanctuary Blade ability causing a trigger * Remove unnecessary logic and correct test * Re-add strict choose mode --------- Co-authored-by: Matthew Wilson <matthew_w@vaadin.com>
This commit is contained in:
parent
dfa6019c3e
commit
784a5fb1e4
4 changed files with 197 additions and 3 deletions
|
|
@ -1,6 +1,6 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import mage.abilities.common.AttachedToCreatureSourceTriggeredAbility;
|
||||
import mage.abilities.common.AsBecomesAttachedToCreatureSourceAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.Effect;
|
||||
|
|
@ -25,11 +25,11 @@ public final class SanctuaryBlade extends CardImpl {
|
|||
|
||||
public SanctuaryBlade(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
|
||||
|
||||
|
||||
this.subtype.add(SubType.EQUIPMENT);
|
||||
|
||||
// As Sanctuary Blade becomes attached to a creature, choose a color.
|
||||
this.addAbility(new AttachedToCreatureSourceTriggeredAbility(new ChooseColorEffect(Outcome.Benefit), false));
|
||||
this.addAbility(new AsBecomesAttachedToCreatureSourceAbility(new ChooseColorEffect(Outcome.Benefit), "choose a color."));
|
||||
|
||||
// Equipped creature gets +2/+0 and has protection from the last chosen color.
|
||||
Effect boostEffect = new BoostEquippedEffect(2, 0);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
package org.mage.test.cards.abilities.equipped;
|
||||
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* Tests that the wording "as {this} becomes equipped to a creature..." is working correctly.
|
||||
* As per rules 603.6d and 614.1c, these should be treated as a static ability with a
|
||||
* replacement effect. They should NOT cause a trigger to be put on the stack.
|
||||
*
|
||||
* @author DominionSpy
|
||||
*/
|
||||
public class AsBecomesAttachedTest extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Sanctuary Blade {2}
|
||||
* Artifact - Equipment
|
||||
* As Sanctuary Blade becomes attached to a creature, choose a color.
|
||||
* Equipped creature gets +2/+0 and has protection from the last chosen color.
|
||||
* Equip {3}
|
||||
*/
|
||||
@Test
|
||||
public void test_SanctuaryBladeAbility() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2 + 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Sanctuary Blade");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Llanowar Elves");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Elvish Mystic");
|
||||
|
||||
// As Sanctuary Blade becomes attached to a creature, choose a color.
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip", "Llanowar Elves");
|
||||
setChoice(playerA, "White");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
|
||||
// Check that there is no trigger on the stack after the equip ability has resolved
|
||||
checkStackSize("stack is empty", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
|
||||
checkAbility("llanowar elves must have protection", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Llanowar Elves", ProtectionAbility.class, true);
|
||||
|
||||
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Equip", "Elvish Mystic");
|
||||
setChoice(playerA, "Blue");
|
||||
waitStackResolved(1, PhaseStep.POSTCOMBAT_MAIN, 1);
|
||||
|
||||
// Do the same check for switching from one creature to another
|
||||
checkStackSize("stack is empty", 1, PhaseStep.POSTCOMBAT_MAIN, playerA, 0);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertAbility(playerA, "Llanowar Elves", ProtectionAbility.from(ObjectColor.WHITE), false);
|
||||
assertAbility(playerA, "Elvish Mystic", ProtectionAbility.from(ObjectColor.BLUE), true);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package mage.abilities.common;
|
||||
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.effects.BecomesAttachedToCreatureSourceEffect;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.constants.Zone;
|
||||
|
||||
/**
|
||||
* Based on {@link mage.abilities.common.AsEntersBattlefieldAbility}.
|
||||
* This allows rule wording such as "as {this} becomes attached to a creature..."
|
||||
* For this, there should not be a trigger, as in the case of the wording "when..."
|
||||
* As per rule 603.6d, this should be a static ability.
|
||||
* See [[Sanctuary Blade]].
|
||||
*
|
||||
* @author DominionSpy
|
||||
*/
|
||||
public class AsBecomesAttachedToCreatureSourceAbility extends StaticAbility {
|
||||
|
||||
public AsBecomesAttachedToCreatureSourceAbility(Effect effect) {
|
||||
this(effect, null);
|
||||
}
|
||||
|
||||
public AsBecomesAttachedToCreatureSourceAbility(Effect effect, String text) {
|
||||
super(Zone.BATTLEFIELD, new BecomesAttachedToCreatureSourceEffect(effect, null, text));
|
||||
}
|
||||
|
||||
protected AsBecomesAttachedToCreatureSourceAbility(final AsBecomesAttachedToCreatureSourceAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsBecomesAttachedToCreatureSourceAbility copy() {
|
||||
return new AsBecomesAttachedToCreatureSourceAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEffect(Effect effect) {
|
||||
if (!getEffects().isEmpty()) {
|
||||
Effect attachEffect = this.getEffects().get(0);
|
||||
if (attachEffect instanceof BecomesAttachedToCreatureSourceEffect) {
|
||||
((BecomesAttachedToCreatureSourceEffect) attachEffect).addEffect(effect);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.addEffect(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "As {this} becomes attached to a creature, " + super.getRule();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package mage.abilities.effects;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.constants.Duration;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
/**
|
||||
* Based on {@link EntersBattlefieldEffect}.
|
||||
* This allows rule wording such as "as {this} becomes attached to a creature..."
|
||||
* For this, there should not be a trigger, as in the case of the wording "when..."
|
||||
* As per rule 614.1c, this should be a replacement effect.
|
||||
* See [[Sanctuary Blade]].
|
||||
*
|
||||
* @author DominionSpy
|
||||
*/
|
||||
public class BecomesAttachedToCreatureSourceEffect extends ReplacementEffectImpl {
|
||||
|
||||
protected Effects baseEffects = new Effects();
|
||||
protected String text;
|
||||
protected Condition condition;
|
||||
|
||||
public BecomesAttachedToCreatureSourceEffect(Effect baseEffect) {
|
||||
this(baseEffect, "");
|
||||
}
|
||||
|
||||
public BecomesAttachedToCreatureSourceEffect(Effect baseEffect, String text) {
|
||||
this(baseEffect, null, text);
|
||||
}
|
||||
|
||||
public BecomesAttachedToCreatureSourceEffect(Effect baseEffect, Condition condition, String text) {
|
||||
super(Duration.WhileOnBattlefield, baseEffect.getOutcome(), false);
|
||||
this.baseEffects.add(baseEffect);
|
||||
this.text = text;
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
protected BecomesAttachedToCreatureSourceEffect(final BecomesAttachedToCreatureSourceEffect effect) {
|
||||
super(effect);
|
||||
this.baseEffects = effect.baseEffects.copy();
|
||||
this.text = effect.text;
|
||||
this.condition = effect.condition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BecomesAttachedToCreatureSourceEffect copy() {
|
||||
return new BecomesAttachedToCreatureSourceEffect(this);
|
||||
}
|
||||
|
||||
public void addEffect(Effect effect) {
|
||||
baseEffects.add(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return GameEvent.EventType.ATTACH == event.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getSourceId().equals(source.getSourceId())) {
|
||||
return condition == null || condition.apply(game, source);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
for (Effect effect : baseEffects) {
|
||||
if (effect instanceof ContinuousEffect) {
|
||||
game.addEffect((ContinuousEffect) effect, source);
|
||||
} else {
|
||||
effect.setValue("appliedEffects", event.getAppliedEffects());
|
||||
effect.apply(game, source);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return (text == null || text.isEmpty()) ? baseEffects.getText(mode) : text;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue