mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +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) {
|
||||
List<Spell> spells;
|
||||
List<Spell> graveyardSpells;
|
||||
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());
|
||||
}
|
||||
List<Spell> spells = spellsCast.computeIfAbsent(spell.getControllerId(), x -> new ArrayList<>());
|
||||
List<Spell> graveyardSpells = spellsCastFromGraveyard.computeIfAbsent(spell.getControllerId(), x -> new ArrayList<>());
|
||||
spells.add(spell.copy()); // copy needed because attributes like color could be changed later
|
||||
if (event.getZone() == Zone.GRAVEYARD) {
|
||||
graveyardSpells.add(spell.copy());
|
||||
|
|
Loading…
Reference in a new issue