Fix corner case with Jace, Wielder of Mysteries (#7050)

This commit is contained in:
tool4ever
2025-02-20 20:03:24 +01:00
committed by GitHub
parent c5fe9b2667
commit 9054e01273
6 changed files with 16 additions and 37 deletions

View File

@@ -1844,19 +1844,10 @@ public class GameAction {
public void checkGameOverCondition() {
// award loses as SBE
List<Player> losers = null;
FCollectionView<Player> allPlayers = game.getPlayers();
for (Player p : allPlayers) {
if (p.checkLoseCondition()) { // this will set appropriate outcomes
if (losers == null) {
losers = Lists.newArrayListWithCapacity(3);
}
losers.add(p);
}
}
GameEndReason reason = null;
List<Player> losers = null;
FCollectionView<Player> allPlayers = game.getPlayers();
// Has anyone won by spelleffect?
for (Player p : allPlayers) {
if (!p.hasWon()) {
@@ -1882,24 +1873,17 @@ public class GameAction {
break;
}
// loop through all the non-losing players that can't win
// see if all of their opponents are in that "about to lose" collection
if (losers != null) {
if (reason == null) {
for (Player p : allPlayers) {
if (losers.contains(p)) {
continue;
}
if (p.cantWin()) {
if (losers.containsAll(p.getOpponents())) {
// what to do here?!?!?!
System.err.println(p.toString() + " is about to win, but can't!");
if (p.checkLoseCondition()) { // this will set appropriate outcomes
if (losers == null) {
losers = Lists.newArrayListWithCapacity(3);
}
losers.add(p);
}
}
}
// need a separate loop here, otherwise ConcurrentModificationException is raised
if (losers != null) {
for (Player p : losers) {
game.onPlayerLost(p);

View File

@@ -23,15 +23,12 @@ package forge.game;
public enum GameEndReason {
/** The All opponents lost. */
AllOpponentsLost,
// Noone won
/** The Draw. */
Draw, // Having little idea how they can reach a draw, so I didn't enumerate
// possible reasons here
// Special conditions, they force one player to win and thus end the game
/** The Wins game spell effect. */
WinsGameSpellEffect, // ones that could be both hardcoded (felidar) and
// scripted ( such as Mayael's Aria )
/** Noone won */
Draw,
/** Special conditions, they force one player to win and thus end the game */
WinsGameSpellEffect,
/** Used to end multiplayer games where the all humans have lost or conceded while AIs cannot end match by themselves.*/
AllHumansLost,

View File

@@ -15,7 +15,6 @@ import forge.game.trigger.TriggerType;
import forge.util.Lang;
import forge.util.TextUtil;
public class AlterAttributeEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {

View File

@@ -1,6 +1,5 @@
package forge.game.ability.effects;
import java.util.List;
import java.util.Map;

View File

@@ -1,6 +1,5 @@
package forge.game.ability.effects;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.player.Player;
@@ -18,6 +17,9 @@ public class GameWinEffect extends SpellAbilityEffect {
for (final Player p : getTargetPlayers(sa)) {
p.altWinBySpellEffect(card.getName());
}
// CR 104.1. A game ends immediately when a player wins
card.getGame().getAction().checkGameOverCondition();
}
}

View File

@@ -2040,14 +2040,12 @@ public class Player extends GameEntity implements Comparable<Player> {
public final boolean loseConditionMet(final GameLossReason state, final String spellName) {
if (state != GameLossReason.OpponentWon) {
// Replacement effects
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
repParams.put(AbilityKey.LoseReason, state);
if (game.getReplacementHandler().run(ReplacementType.GameLoss, repParams) != ReplacementResult.NotReplaced) {
return false;
}
}
//final String spellName = sa != null ? sa.getHostCard().getName() : null;
setOutcome(PlayerOutcome.loss(state, spellName));
return true;
}