mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
* Cast an instant or sorcery spell this turn - fixed rollback error when you cast graveyard spell as first in turn (#7918);
This commit is contained in:
parent
daf77b2ee8
commit
9a4489b47f
3 changed files with 105 additions and 12 deletions
|
@ -0,0 +1,30 @@
|
||||||
|
package org.mage.test.cards.single.mh1;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
public class LavaDartTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_Play() {
|
||||||
|
// Lava Dart deals 1 damage to any target.
|
||||||
|
// Flashback-Sacrifice a Mountain.
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, "Lava Dart"); // {R}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||||
|
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback", playerB);
|
||||||
|
setChoice(playerA, "Mountain"); // sacrifice cost
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertLife(playerB, 20 - 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package org.mage.test.cards.single.stx;
|
||||||
|
|
||||||
|
import mage.abilities.keyword.VigilanceAbility;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.watchers.common.SpellsCastWatcher;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
public class ShowOfConfidenceTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_SpellsCastWatcher() {
|
||||||
|
// When you cast this spell, copy it for each other instant or sorcery spell you've cast this turn. You may choose new targets for the copies.
|
||||||
|
// Put a +1/+1 counter on target creature. It gains vigilance until end of turn.
|
||||||
|
addCard(Zone.HAND, playerA, "Show of Confidence"); // {1}{W}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1);
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, "Lightning Bolt", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
|
||||||
|
//
|
||||||
|
// Each instant and sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost.
|
||||||
|
addCard(Zone.HAND, playerA, "Past in Flames", 1); // {3}{R}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4);
|
||||||
|
|
||||||
|
// prepare NPE error for watcher
|
||||||
|
runCode("prepare watcher's NPE", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||||
|
// possible bug: NPE after wrong computeIfAbsent usage (lists desync)
|
||||||
|
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
|
||||||
|
watcher.getSpellsCastThisTurn(player.getId());
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepare flashback
|
||||||
|
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}", 4);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Past in Flames");
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
// prepare spells count (1x from hand, 1x from grave)
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Flashback {R}", playerB);
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
// cast and copy 3x
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Show of Confidence", "Balduvian Bears");
|
||||||
|
setChoice(playerA, "No"); // no change target (copy 1)
|
||||||
|
setChoice(playerA, "No"); // no change target (copy 2)
|
||||||
|
setChoice(playerA, "No"); // no change target (copy 3)
|
||||||
|
|
||||||
|
// test watcher's copy
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
runCode("test watcher's copy", 1, PhaseStep.PRECOMBAT_MAIN, playerA, (info, player, game) -> {
|
||||||
|
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
|
||||||
|
SpellsCastWatcher copiedWatcher = watcher.copy();
|
||||||
|
Assert.assertEquals("original watcher must see 4 spells", 4, watcher.getSpellsCastThisTurn(player.getId()).size());
|
||||||
|
Assert.assertEquals("copied watcher must see 4 spells", 4, copiedWatcher.getSpellsCastThisTurn(player.getId()).size());
|
||||||
|
});
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
assertAllCommandsUsed();
|
||||||
|
|
||||||
|
assertCounterCount(playerA, "Balduvian Bears", CounterType.P1P1, 4);
|
||||||
|
assertAbility(playerA, "Balduvian Bears", VigilanceAbility.getInstance(), true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,18 +36,8 @@ public class SpellsCastWatcher extends Watcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spell != null) {
|
if (spell != null) {
|
||||||
List<Spell> spells;
|
List<Spell> spells = spellsCast.computeIfAbsent(spell.getControllerId(), x -> new ArrayList<>());
|
||||||
List<Spell> graveyardSpells;
|
List<Spell> graveyardSpells = spellsCastFromGraveyard.computeIfAbsent(spell.getControllerId(), x -> new ArrayList<>());
|
||||||
if (!spellsCast.containsKey(spell.getControllerId())) {
|
|
||||||
spells = new ArrayList<>();
|
|
||||||
spellsCast.put(spell.getControllerId(), spells);
|
|
||||||
graveyardSpells = new ArrayList<>();
|
|
||||||
spellsCastFromGraveyard.put(spell.getControllerId(), graveyardSpells);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
spells = spellsCast.get(spell.getControllerId());
|
|
||||||
graveyardSpells = spellsCastFromGraveyard.get(spell.getControllerId());
|
|
||||||
}
|
|
||||||
spells.add(spell.copy()); // copy needed because attributes like color could be changed later
|
spells.add(spell.copy()); // copy needed because attributes like color could be changed later
|
||||||
if (event.getZone() == Zone.GRAVEYARD) {
|
if (event.getZone() == Zone.GRAVEYARD) {
|
||||||
graveyardSpells.add(spell.copy());
|
graveyardSpells.add(spell.copy());
|
||||||
|
|
Loading…
Reference in a new issue