rework DrawNthCardTriggeredAbility, add test (closes #13885)

This commit is contained in:
theelk801 2025-07-30 10:52:43 -04:00
parent 6b2317839b
commit 3d1400905b
2 changed files with 72 additions and 6 deletions

View file

@ -0,0 +1,32 @@
package org.mage.test.cards.triggers;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author TheElk801
*/
public class DrawNCardsTest extends CardTestPlayerBase {
private static final String snacker = "Sneaky Snacker";
private static final String mists = "Reach Through Mists";
private static final String looting = "Faithless Looting";
@Test
public void testSnacker() {
addCard(Zone.BATTLEFIELD, playerA, "Volcanic Island", 1 + 1);
addCard(Zone.GRAVEYARD, playerA, snacker);
addCard(Zone.HAND, playerA, mists);
addCard(Zone.HAND, playerA, looting);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mists);
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, looting);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertTapped(snacker, true);
}
}

View file

@ -6,12 +6,14 @@ import mage.abilities.effects.Effect;
import mage.abilities.hint.Hint; import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint; import mage.abilities.hint.ValueHint;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.WatcherScope;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.watchers.common.CardsDrawnThisTurnWatcher; import mage.watchers.Watcher;
import java.util.*;
/** /**
* @author TheElk801 * @author TheElk801
@ -48,6 +50,7 @@ public class DrawNthCardTriggeredAbility extends TriggeredAbilityImpl {
this.addHint(hint); this.addHint(hint);
} }
setTriggerPhrase(generateTriggerPhrase()); setTriggerPhrase(generateTriggerPhrase());
this.addWatcher(new DrawNthCardWatcher());
} }
protected DrawNthCardTriggeredAbility(final DrawNthCardTriggeredAbility ability) { protected DrawNthCardTriggeredAbility(final DrawNthCardTriggeredAbility ability) {
@ -75,8 +78,7 @@ public class DrawNthCardTriggeredAbility extends TriggeredAbilityImpl {
} }
break; break;
case OPPONENT: case OPPONENT:
Player controller = game.getPlayer(controllerId); if (!game.getOpponents(getControllerId()).contains(event.getPlayerId())) {
if (controller == null || !controller.hasOpponent(event.getPlayerId(), game)) {
return false; return false;
} }
break; break;
@ -86,8 +88,7 @@ public class DrawNthCardTriggeredAbility extends TriggeredAbilityImpl {
default: default:
throw new IllegalArgumentException("TargetController " + targetController + " not supported"); throw new IllegalArgumentException("TargetController " + targetController + " not supported");
} }
CardsDrawnThisTurnWatcher watcher = game.getState().getWatcher(CardsDrawnThisTurnWatcher.class); return DrawNthCardWatcher.checkEvent(event.getPlayerId(), event.getId(), game) + 1 == cardNumber;
return watcher != null && watcher.getCardsDrawnThisTurn(event.getPlayerId()) == cardNumber;
} }
public String generateTriggerPhrase() { public String generateTriggerPhrase() {
@ -110,3 +111,36 @@ public class DrawNthCardTriggeredAbility extends TriggeredAbilityImpl {
return new DrawNthCardTriggeredAbility(this); return new DrawNthCardTriggeredAbility(this);
} }
} }
class DrawNthCardWatcher extends Watcher {
private final Map<UUID, List<UUID>> playerDrawEventMap = new HashMap<>();
DrawNthCardWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.DREW_CARD) {
playerDrawEventMap
.computeIfAbsent(event.getPlayerId(), x -> new ArrayList<>())
.add(event.getId());
}
}
@Override
public void reset() {
super.reset();
playerDrawEventMap.clear();
}
static int checkEvent(UUID playerId, UUID eventId, Game game) {
return game
.getState()
.getWatcher(DrawNthCardWatcher.class)
.playerDrawEventMap
.getOrDefault(playerId, Collections.emptyList())
.indexOf(eventId);
}
}