fixed some Idol of Endurance bugs, updated tests

This commit is contained in:
Evan Kranzler 2020-06-30 19:20:59 -04:00
parent 833ca03293
commit 00c5162682
2 changed files with 85 additions and 10 deletions

View file

@ -91,16 +91,20 @@ class IdolOfEnduranceExileEffect extends OneShotEffect {
.filter(Objects::nonNull)
.map(card -> new MageObjectReference(card, game))
.collect(Collectors.toSet());
game.getState().setValue("" + mor.getSourceId() + mor.getZoneChangeCounter(), morSet);
game.addDelayedTriggeredAbility(new IdolOfEnduranceDelayedTrigger(morSet), source);
String exileId = "idolOfEndurance_" + mor.getSourceId() + mor.getZoneChangeCounter();
if (game.getState().getValue(exileId) == null) {
game.getState().setValue(exileId, new HashSet<MageObjectReference>());
}
((Set) game.getState().getValue(exileId)).addAll(morSet);
game.addDelayedTriggeredAbility(new IdolOfEnduranceDelayedTrigger(exileId), source);
return true;
}
}
class IdolOfEnduranceDelayedTrigger extends DelayedTriggeredAbility {
IdolOfEnduranceDelayedTrigger(Set<MageObjectReference> morSet) {
super(new IdolOfEnduranceLeaveEffect(morSet), Duration.Custom, true, false);
IdolOfEnduranceDelayedTrigger(String exileId) {
super(new IdolOfEnduranceLeaveEffect(exileId), Duration.Custom, true, false);
this.usesStack = false;
this.setRuleVisible(false);
}
@ -133,15 +137,16 @@ class IdolOfEnduranceDelayedTrigger extends DelayedTriggeredAbility {
class IdolOfEnduranceLeaveEffect extends OneShotEffect {
private final Set<MageObjectReference> morSet = new HashSet<>();
private final String exileId;
IdolOfEnduranceLeaveEffect(Set<MageObjectReference> morSet) {
IdolOfEnduranceLeaveEffect(String exileId) {
super(Outcome.Benefit);
this.morSet.addAll(morSet);
this.exileId = exileId;
}
private IdolOfEnduranceLeaveEffect(final IdolOfEnduranceLeaveEffect effect) {
super(effect);
this.exileId = effect.exileId;
}
@Override
@ -152,6 +157,14 @@ class IdolOfEnduranceLeaveEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Object object = game.getState().getValue(exileId);
if (!(object instanceof Set)) {
return false;
}
Set<MageObjectReference> morSet = (Set<MageObjectReference>) object;
return player != null && player.moveCards(
morSet.stream()
.map(mor -> mor.getCard(game))
@ -198,7 +211,9 @@ class IdolOfEnduranceCastFromExileEffect extends AsThoughEffectImpl {
if (watcher == null || !watcher.checkPermission(affectedControllerId, source, game)) {
return false;
}
Object value = game.getState().getValue("" + source.getSourceId() + source.getSourceObjectZoneChangeCounter());
Object value = game.getState().getValue(
"idolOfEndurance_" + source.getSourceId() + source.getSourceObjectZoneChangeCounter()
);
if (!(value instanceof Set)) {
discard();
return false;

View file

@ -11,12 +11,15 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class IdolOfEnduranceTest extends CardTestPlayerBase {
private static final String idol = "Idol of Endurance";
private static final String dsnchnt = "Disenchant";
private static final String key = "Voltaic Key";
private static final String sqr = "Squire";
private static final String glrskr = "Glory Seeker";
private static final String pnhrmcn = "Panharmonicon";
private static final String bnyrdwrm = "Boneyard Wurm";
@Test
public void testIdol() {
public void testIdolCast() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.HAND, playerA, idol);
addCard(Zone.GRAVEYARD, playerA, sqr);
@ -35,7 +38,7 @@ public class IdolOfEnduranceTest extends CardTestPlayerBase {
}
@Test
public void testIdol2() {
public void testIdolCast2() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
addCard(Zone.HAND, playerA, idol);
addCard(Zone.GRAVEYARD, playerA, sqr);
@ -59,6 +62,63 @@ public class IdolOfEnduranceTest extends CardTestPlayerBase {
assertPermanentCount(playerA, glrskr, 0);
}
@Test
public void testIdolLeaves() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
addCard(Zone.HAND, playerA, idol);
addCard(Zone.HAND, playerA, dsnchnt);
addCard(Zone.GRAVEYARD, playerA, sqr);
addCard(Zone.GRAVEYARD, playerA, glrskr);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, idol);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W}");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, sqr);
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, dsnchnt, idol);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, sqr, 1);
assertPermanentCount(playerA, idol, 0);
assertGraveyardCount(playerA, glrskr, 1);
}
@Test
public void testIdolPanharmonicon() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
addCard(Zone.BATTLEFIELD, playerA, pnhrmcn);
addCard(Zone.BATTLEFIELD, playerA, bnyrdwrm, 2);
addCard(Zone.HAND, playerA, idol);
addCard(Zone.HAND, playerA, dsnchnt);
addCard(Zone.GRAVEYARD, playerA, sqr);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, idol);
// Boneyard Wurm will die between triggers
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{W}");
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, playerA);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, bnyrdwrm);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, dsnchnt, idol);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertPermanentCount(playerA, bnyrdwrm, 1);
assertPermanentCount(playerA, idol, 0);
assertGraveyardCount(playerA, sqr, 1);
assertGraveyardCount(playerA, bnyrdwrm, 1);
}
@Test
public void testIdolTwice() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 8);