From 166d898168f8622e1fed744e21b4e9f471d9985d Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 26 Jun 2020 17:41:10 +0200 Subject: [PATCH] * Added a test for #4659 - it's not reproducable (closes #4659). --- .../mage/test/rollback/DemonicPactTest.java | 52 ++++++++++++++++++- .../delayed/PactDelayedTriggeredAbility.java | 18 ++----- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/rollback/DemonicPactTest.java b/Mage.Tests/src/test/java/org/mage/test/rollback/DemonicPactTest.java index 06e5b4791e3..c741768a7ae 100644 --- a/Mage.Tests/src/test/java/org/mage/test/rollback/DemonicPactTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/rollback/DemonicPactTest.java @@ -1,8 +1,8 @@ - package org.mage.test.rollback; import mage.constants.PhaseStep; import mage.constants.Zone; +import org.junit.Assert; import org.junit.Test; import org.mage.test.serverside.base.CardTestPlayerBase; @@ -74,4 +74,54 @@ public class DemonicPactTest extends CardTestPlayerBase { assertLife(playerB, 16); } + + /** + * Rollback problem with Pact of Negation etc [cards] #4659 + * + * Potential bug here for [Pact of Negation] and similar cards with 0 cost + * and demand to pay or lose the next turn. + * + * So can you check the following scenario where I think the game is buggy: + * an opponent casts pact of negation on my turn, his next turn he requests + * a rollback to beginning of his turn -- bingo I'm a winner and he loses + * the game. The log says I'm the winner and the opponent lost and that is + * immediately after rollback request. + */ + + @Test + public void testPactOfNegationRollback() { + addCard(Zone.HAND, playerA, "Silvercoat Lion", 1); + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + + addCard(Zone.BATTLEFIELD, playerB, "Island", 5); + // Counter target spell. + // At the beginning of your next upkeep, pay {3}{U}{U}. If you don't, you lose the game. + addCard(Zone.HAND, playerB, "Pact of Negation"); // Instant {0} + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Pact of Negation", "Silvercoat Lion", "Silvercoat Lion"); + + setChoice(playerB, "Yes"); + + rollbackTurns(2, PhaseStep.PRECOMBAT_MAIN, playerB, 0); + + setStrictChooseMode(true); + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertAllCommandsUsed(); + + + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertGraveyardCount(playerB, "Pact of Negation", 1); + + Assert.assertTrue("Player A is still in game", playerA.isInGame()); + Assert.assertTrue("Player B is still in game", playerB.isInGame()); + + assertTappedCount("Island", true, 5); + + + } + } diff --git a/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java index 1bb565531ab..5329f3f4385 100644 --- a/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/delayed/PactDelayedTriggeredAbility.java @@ -1,4 +1,3 @@ - package mage.abilities.common.delayed; import mage.constants.Outcome; @@ -19,7 +18,6 @@ public class PactDelayedTriggeredAbility extends DelayedTriggeredAbility { super(new PactEffect(cost)); } - public PactDelayedTriggeredAbility(PactDelayedTriggeredAbility ability) { super(ability); } @@ -39,8 +37,6 @@ public class PactDelayedTriggeredAbility extends DelayedTriggeredAbility { return game.isActivePlayer(this.getControllerId()); } - - @Override public String getRule() { return "At the beginning of your next upkeep " + modes.getText(); @@ -49,8 +45,7 @@ public class PactDelayedTriggeredAbility extends DelayedTriggeredAbility { class PactEffect extends OneShotEffect { - private ManaCosts cost; - + private final ManaCosts cost; public PactEffect(ManaCosts cost) { super(Outcome.Neutral); @@ -60,7 +55,7 @@ class PactEffect extends OneShotEffect { public PactEffect(final PactEffect effect) { super(effect); - this.cost = effect.cost; + this.cost = effect.cost.copy(); } @Override @@ -71,10 +66,10 @@ class PactEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + '?', source, game)) { + if (player != null) { + if (player.chooseUse(Outcome.Benefit, "Pay " + cost.getText() + '?', source, game)) { cost.clearPaid(); - if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)){ + if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), false, null)) { return true; } } @@ -83,7 +78,4 @@ class PactEffect extends OneShotEffect { } return false; } - - - }