From 14f7c02b1f131d7a2be2ddeee1043d2024a92771 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 31 Jan 2021 21:26:27 -0500 Subject: [PATCH] [KHM] fixed Codespell Cleric not triggering correctly --- .../src/mage/cards/c/CodespellCleric.java | 55 ++++++++++++++--- .../cards/single/khm/CodespellClericTest.java | 61 +++++++++++++++++++ .../common/CastSpellLastTurnWatcher.java | 15 ----- 3 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/khm/CodespellClericTest.java diff --git a/Mage.Sets/src/mage/cards/c/CodespellCleric.java b/Mage.Sets/src/mage/cards/c/CodespellCleric.java index 3f7421ac5a..15b743e83d 100644 --- a/Mage.Sets/src/mage/cards/c/CodespellCleric.java +++ b/Mage.Sets/src/mage/cards/c/CodespellCleric.java @@ -1,6 +1,7 @@ package mage.cards.c; import mage.MageInt; +import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.condition.Condition; @@ -11,13 +12,15 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; +import mage.constants.WatcherScope; import mage.counters.CounterType; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetCreaturePermanent; -import mage.watchers.common.CastSpellLastTurnWatcher; +import mage.watchers.Watcher; -import java.util.UUID; +import java.util.*; /** * @author TheElk801 @@ -42,7 +45,7 @@ public final class CodespellCleric extends CardImpl { "if it was the second spell you cast this turn, put a +1/+1 counter on target creature." ); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability); + this.addAbility(ability, new CodespellClericWatcher()); } private CodespellCleric(final CodespellCleric card) { @@ -60,9 +63,47 @@ enum CodespellClericCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - CastSpellLastTurnWatcher watcher = game.getState().getWatcher(CastSpellLastTurnWatcher.class); - return watcher != null && watcher.getPermanentSpellOrder( - (Permanent) source.getEffects().get(0).getValue("permanentEnteredBattlefield"), game - ) == 2; + CodespellClericWatcher watcher = game.getState().getWatcher(CodespellClericWatcher.class); + return watcher != null && watcher.checkSpell(source, game); + } +} + +class CodespellClericWatcher extends Watcher { + + private final Map> spellMap = new HashMap<>(); + private static final List emptyList = new ArrayList<>(); + + CodespellClericWatcher() { + super(WatcherScope.GAME); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.SPELL_CAST) { + spellMap.computeIfAbsent(event.getPlayerId(), x -> new ArrayList<>()) + .add(new MageObjectReference(event.getSourceId(), game)); + } + } + + @Override + public void reset() { + super.reset(); + spellMap.clear(); + } + + boolean checkSpell(Ability source, Game game) { + Permanent permanent = (Permanent) source.getEffects().get(0).getValue("permanentEnteredBattlefield"); + if (permanent == null) { + return false; + } + int index = 0; + for (MageObjectReference mor : spellMap.getOrDefault(source.getControllerId(), emptyList)) { + index++; + if (mor.getSourceId() == permanent.getId() + && mor.getZoneChangeCounter() + 1 == permanent.getZoneChangeCounter(game)) { + return index == 2; + } + } + return false; } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/CodespellClericTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/CodespellClericTest.java new file mode 100644 index 0000000000..cab1138719 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/khm/CodespellClericTest.java @@ -0,0 +1,61 @@ +package org.mage.test.cards.single.khm; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.counters.CounterType; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * @author TheElk801 + */ +public class CodespellClericTest extends CardTestPlayerBase { + + private static final String cleric = "Codespell Cleric"; + private static final String relic = "Darksteel Relic"; + + @Test + public void testFirstSpell() { + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, cleric); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, cleric); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertCounterCount(playerA, cleric, CounterType.P1P1, 0); + } + + @Test + public void testSecondSpell() { + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, relic); + addCard(Zone.HAND, playerA, cleric); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, cleric); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertCounterCount(playerA, cleric, CounterType.P1P1, 1); + } + + @Test + public void testThirdSpell() { + addCard(Zone.BATTLEFIELD, playerA, "Plains"); + addCard(Zone.HAND, playerA, relic, 2); + addCard(Zone.HAND, playerA, cleric); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, relic); + addTarget(playerA, cleric); + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, cleric); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertCounterCount(playerA, cleric, CounterType.P1P1, 0); + } +} diff --git a/Mage/src/main/java/mage/watchers/common/CastSpellLastTurnWatcher.java b/Mage/src/main/java/mage/watchers/common/CastSpellLastTurnWatcher.java index 5fe0c10784..c2fe4644a8 100644 --- a/Mage/src/main/java/mage/watchers/common/CastSpellLastTurnWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/CastSpellLastTurnWatcher.java @@ -4,7 +4,6 @@ import mage.MageObjectReference; import mage.constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; -import mage.game.permanent.Permanent; import mage.watchers.Watcher; import java.util.*; @@ -70,18 +69,4 @@ public class CastSpellLastTurnWatcher extends Watcher { } return 0; } - - public int getPermanentSpellOrder(Permanent permanent, Game game) { - if (permanent == null) { - return -1; - } - int index = 0; - for (MageObjectReference mor : spellsCastThisTurnInOrder) { - index++; - if (mor.getSourceId() == permanent.getId() && mor.getZoneChangeCounter() + 1 == permanent.getZoneChangeCounter(game)) { - return index; - } - } - return -1; - } }