From bfd6af7f2be17bd06312d336e6a012a63f8255e2 Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Tue, 23 Oct 2012 21:53:07 +0000 Subject: [PATCH] fix to NPE from players leaving game. Trigger handler should check all non-active players --- .../forge/card/trigger/TriggerHandler.java | 64 +++++++++++-------- src/main/java/forge/game/MatchController.java | 2 +- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/main/java/forge/card/trigger/TriggerHandler.java b/src/main/java/forge/card/trigger/TriggerHandler.java index 512add6e96b..5c2b810e427 100644 --- a/src/main/java/forge/card/trigger/TriggerHandler.java +++ b/src/main/java/forge/card/trigger/TriggerHandler.java @@ -39,6 +39,7 @@ import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbilityRestriction; import forge.card.spellability.Target; import forge.control.input.Input; +import forge.game.GameState; import forge.game.phase.PhaseType; //import forge.util.TextUtil; import forge.game.player.ComputerUtil; @@ -270,8 +271,9 @@ public class TriggerHandler { if (this.suppressedModes.contains(mode)) { return; } - - final Player playerAP = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn(); + final GameState game = Singletons.getModel().getGame(); + + final Player playerAP = game.getPhaseHandler().getPlayerTurn(); if (playerAP == null) { // This should only happen outside of games, so it's safe to just // abort. @@ -285,8 +287,8 @@ public class TriggerHandler { // This is done to allow the list of triggers to be modified while // triggers are running. final ArrayList delayedTriggersWorkingCopy = new ArrayList(this.delayedTriggers); - List allCards = Singletons.getModel().getGame().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES); - allCards.addAll(Singletons.getModel().getGame().getCardsIn(ZoneType.Stack)); + List allCards = game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES); + allCards.addAll(game.getCardsIn(ZoneType.Stack)); boolean checkStatics = false; // Static triggers @@ -301,23 +303,23 @@ public class TriggerHandler { } if (checkStatics) { - Singletons.getModel().getGame().getAction().checkStaticAbilities(); + game.getAction().checkStaticAbilities(); } else if (runParams.containsKey("Destination")){ // Check static abilities when a card enters the battlefield String type = (String) runParams.get("Destination"); if (type.equals("Battlefield")) { - Singletons.getModel().getGame().getAction().checkStaticAbilities(); + game.getAction().checkStaticAbilities(); } } // AP allCards = playerAP.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES); - allCards.addAll(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsIn(ZoneType.Stack), playerAP)); + allCards.addAll(CardLists.filterControlledBy(game.getCardsIn(ZoneType.Stack), playerAP)); // add cards that move to hidden zones if (runParams.containsKey("Destination") && runParams.containsKey("Card")) { Card card = (Card) runParams.get("Card"); if (playerAP.equals(card.getController()) && !allCards.contains(card) - && (Singletons.getModel().getGame().getZoneOf(card) == null || Singletons.getModel().getGame().getZoneOf(card).getZoneType().isHidden())) { + && (game.getZoneOf(card) == null || game.getZoneOf(card).getZoneType().isHidden())) { allCards.add(card); } } @@ -336,28 +338,34 @@ public class TriggerHandler { } } - // NAP - allCards = playerAP.getOpponent().getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES); - allCards.addAll(CardLists.filterControlledBy(Singletons.getModel().getGame().getCardsIn(ZoneType.Stack), playerAP.getOpponent())); - // add cards that move to hidden zones - if (runParams.containsKey("Destination") && runParams.containsKey("Card")) { - Card card = (Card) runParams.get("Card"); - if (!playerAP.equals(card.getController()) && !allCards.contains(card) - && (Singletons.getModel().getGame().getZoneOf(card) == null || Singletons.getModel().getGame().getZoneOf(card).getZoneType().isHidden())) { - allCards.add(card); - } - } - for (final Card c : allCards) { - for (final Trigger t : c.getTriggers()) { - if (!t.isStatic()) { - this.runSingleTrigger(t, mode, runParams); + // NAPs + + for(Player nap: game.getPlayers() ) + { + if ( nap.equals(playerAP) ) continue; + + allCards = nap.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES); + allCards.addAll(CardLists.filterControlledBy(game.getCardsIn(ZoneType.Stack), nap)); + // add cards that move to hidden zones + if (runParams.containsKey("Destination") && runParams.containsKey("Card")) { + Card card = (Card) runParams.get("Card"); + if (!playerAP.equals(card.getController()) && !allCards.contains(card) + && (game.getZoneOf(card) == null || game.getZoneOf(card).getZoneType().isHidden())) { + allCards.add(card); } } - } - for (Trigger deltrig : delayedTriggersWorkingCopy) { - if (deltrig.getHostCard().getController().equals(playerAP.getOpponent())) { - if (this.runSingleTrigger(deltrig, mode, runParams)) { - this.delayedTriggers.remove(deltrig); + for (final Card c : allCards) { + for (final Trigger t : c.getTriggers()) { + if (!t.isStatic()) { + this.runSingleTrigger(t, mode, runParams); + } + } + } + for (Trigger deltrig : delayedTriggersWorkingCopy) { + if (deltrig.getHostCard().getController().equals(nap)) { + if (this.runSingleTrigger(deltrig, mode, runParams)) { + this.delayedTriggers.remove(deltrig); + } } } } diff --git a/src/main/java/forge/game/MatchController.java b/src/main/java/forge/game/MatchController.java index 7bac80317b3..41dc36f328e 100644 --- a/src/main/java/forge/game/MatchController.java +++ b/src/main/java/forge/game/MatchController.java @@ -84,7 +84,7 @@ public class MatchController { if ( !game.isGameOver() ) throw new RuntimeException("Game is not over yet."); - GameOutcome result = new GameOutcome(reason, game.getPlayers()); + GameOutcome result = new GameOutcome(reason, game.getRegisteredPlayers()); result.setTurnsPlayed(game.getPhaseHandler().getTurn()); gamesPlayed.add(result); }