mirror of
https://github.com/correl/mage.git
synced 2024-11-25 11:09:53 +00:00
* Fixed a bug that the win method for a player did not handle the range correctly and did erroneously end the game while still multiple players alive (related to #6553).
This commit is contained in:
parent
365754b6f7
commit
d2b8928e60
3 changed files with 76 additions and 8 deletions
|
@ -27,6 +27,8 @@ public final class ApproachOfTheSecondSun extends CardImpl {
|
||||||
public ApproachOfTheSecondSun(UUID ownerId, CardSetInfo setInfo) {
|
public ApproachOfTheSecondSun(UUID ownerId, CardSetInfo setInfo) {
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{W}");
|
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{W}");
|
||||||
|
|
||||||
|
// If this spell was cast from your hand and you've cast another spell named Approach of the Second Sun this game,
|
||||||
|
// you win the game. Otherwise, put Approach of the Second Sun into its owner's library seventh from the top and you gain 7 life.
|
||||||
getSpellAbility().addEffect(new ApproachOfTheSecondSunEffect());
|
getSpellAbility().addEffect(new ApproachOfTheSecondSunEffect());
|
||||||
getSpellAbility().addWatcher(new ApproachOfTheSecondSunWatcher());
|
getSpellAbility().addWatcher(new ApproachOfTheSecondSunWatcher());
|
||||||
}
|
}
|
||||||
|
@ -46,7 +48,7 @@ class ApproachOfTheSecondSunEffect extends OneShotEffect {
|
||||||
public ApproachOfTheSecondSunEffect() {
|
public ApproachOfTheSecondSunEffect() {
|
||||||
super(Outcome.Win);
|
super(Outcome.Win);
|
||||||
this.staticText
|
this.staticText
|
||||||
= "If this spell was cast from your hand and you've cast another spell named Approach of the Second Sun this game, you win the game. "
|
= "If this spell was cast from your hand and you've cast another spell named {this} this game, you win the game. "
|
||||||
+ "Otherwise, put {this} into its owner's library seventh from the top and you gain 7 life.";
|
+ "Otherwise, put {this} into its owner's library seventh from the top and you gain 7 life.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +95,7 @@ class ApproachOfTheSecondSunEffect extends OneShotEffect {
|
||||||
|
|
||||||
class ApproachOfTheSecondSunWatcher extends Watcher {
|
class ApproachOfTheSecondSunWatcher extends Watcher {
|
||||||
|
|
||||||
private Map<UUID, Integer> approachesCast = new HashMap<>();
|
private final Map<UUID, Integer> approachesCast = new HashMap<>();
|
||||||
|
|
||||||
public ApproachOfTheSecondSunWatcher() {
|
public ApproachOfTheSecondSunWatcher() {
|
||||||
super(WatcherScope.GAME);
|
super(WatcherScope.GAME);
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.mage.test.multiplayer;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import mage.constants.MultiplayerAttackOption;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.RangeOfInfluence;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.FreeForAll;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.GameException;
|
||||||
|
import mage.game.mulligan.MulliganType;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestMultiPlayerBase;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author LevelX2
|
||||||
|
*/
|
||||||
|
public class PlayerWinsTest extends CardTestMultiPlayerBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
|
||||||
|
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ONE, MulliganType.GAME_DEFAULT.getMulligan(0), 40);
|
||||||
|
// Player order: A -> D -> C -> B
|
||||||
|
playerA = createPlayer(game, playerA, "PlayerA");
|
||||||
|
playerB = createPlayer(game, playerB, "PlayerB");
|
||||||
|
playerC = createPlayer(game, playerC, "PlayerC");
|
||||||
|
playerD = createPlayer(game, playerD, "PlayerD");
|
||||||
|
return game;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests multiplayer effects Player order: A -> D -> C -> B
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void ApproachOfTheSecondSunTest() {
|
||||||
|
|
||||||
|
// If this spell was cast from your hand and you've cast another spell named Approach of the Second Sun this game,
|
||||||
|
// you win the game. Otherwise, put Approach of the Second Sun into its owner's library seventh from the top and you gain 7 life.
|
||||||
|
addCard(Zone.HAND, playerA, "Approach of the Second Sun", 2); // Sorcery {6}{W}
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 7);
|
||||||
|
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun");
|
||||||
|
castSpell(5, PhaseStep.PRECOMBAT_MAIN, playerA, "Approach of the Second Sun");
|
||||||
|
|
||||||
|
setStopAt(5, PhaseStep.POSTCOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertLife(playerA, 47);
|
||||||
|
assertLife(playerC, 40);
|
||||||
|
Assert.assertTrue("Player D has lost the game", !playerD.isInGame());
|
||||||
|
Assert.assertTrue("Player B has lost the game", !playerB.isInGame());
|
||||||
|
Assert.assertTrue("Player C is in the game", playerC.isInGame());
|
||||||
|
Assert.assertTrue("Player A is in the game", playerA.isInGame());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2526,14 +2526,16 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
opponent.lostForced(game);
|
opponent.lostForced(game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if no more opponents alive, you win and the game ends
|
// if no more opponents alive (independant from range), you win and the game ends
|
||||||
int opponentsAlive = 0;
|
int opponentsAlive = 0;
|
||||||
for (UUID opponentId : game.getOpponents(playerId)) {
|
for (UUID playerIdToCheck : game.getPlayerList()) {
|
||||||
Player opponent = game.getPlayer(opponentId);
|
if (game.isOpponent(this, playerIdToCheck)) { // Check without range
|
||||||
|
Player opponent = game.getPlayer(playerIdToCheck);
|
||||||
if (opponent != null && !opponent.hasLost()) {
|
if (opponent != null && !opponent.hasLost()) {
|
||||||
opponentsAlive++;
|
opponentsAlive++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (opponentsAlive == 0 && !hasWon()) {
|
if (opponentsAlive == 0 && !hasWon()) {
|
||||||
logger.debug("player won -> No more opponents alive game won: " + this.getName());
|
logger.debug("player won -> No more opponents alive game won: " + this.getName());
|
||||||
game.informPlayers(this.getLogName() + " has won the game");
|
game.informPlayers(this.getLogName() + " has won the game");
|
||||||
|
@ -2541,7 +2543,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
game.end();
|
game.end();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.debug("player won -> but already lost before: " + this.getName());
|
logger.debug("player won -> but already lost before or other players still alive: " + this.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue