* Added a test for #4659 - it's not reproducable (closes #4659).

This commit is contained in:
LevelX2 2020-06-26 17:41:10 +02:00
parent 329f7fd609
commit 166d898168
2 changed files with 56 additions and 14 deletions

View file

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

View file

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