[KHM] fixed Codespell Cleric not triggering correctly

This commit is contained in:
Evan Kranzler 2021-01-31 21:26:27 -05:00
parent b45c176a84
commit 14f7c02b1f
3 changed files with 109 additions and 22 deletions

View file

@ -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<UUID, List<MageObjectReference>> spellMap = new HashMap<>();
private static final List<MageObjectReference> 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;
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}