From 53964ee80c64742cbb19370a01388b8d906ab58a Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sat, 28 Jun 2014 10:30:47 +0200 Subject: [PATCH] * Phyrexian Unlife - Fixed that damage from a combat damage step was not handled as if all damage was dealt at once. This could cause a wrong mix of damage and poison conters. --- .../sets/newphyrexia/PhyrexianUnlife.java | 25 ++++++++++++++-- Mage/src/mage/game/GameState.java | 16 ++++++++++ Mage/src/mage/game/combat/CombatGroup.java | 29 +++++++++---------- Mage/src/mage/game/turn/Phase.java | 3 +- 4 files changed, 54 insertions(+), 19 deletions(-) diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java index 215fe6b371..1361dcf6e9 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java @@ -80,6 +80,9 @@ public class PhyrexianUnlife extends CardImpl { class PhyrexianUnlifeEffect2 extends ReplacementEffectImpl { + int lastCheckedDamageStepNum = 0; + boolean startedWithLifeAboveZero = false; + public PhyrexianUnlifeEffect2() { super(Duration.WhileOnBattlefield, Outcome.Benefit); staticText = "As long as you have 0 or less life, all damage is dealt to you as though its source had infect"; @@ -87,6 +90,8 @@ class PhyrexianUnlifeEffect2 extends ReplacementEffectImpl { public PhyrexianUnlifeEffect2(final PhyrexianUnlifeEffect2 effect) { super(effect); + this.lastCheckedDamageStepNum = effect.lastCheckedDamageStepNum; + this.startedWithLifeAboveZero = effect.startedWithLifeAboveZero; } @Override @@ -119,11 +124,25 @@ class PhyrexianUnlifeEffect2 extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.DAMAGE_PLAYER && event.getPlayerId().equals(source.getControllerId())) { - Player player = game.getPlayer(event.getPlayerId()); - if (player.getLife() <= 0) { - return true; + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + // The decision if the player has more than 0 life has to be checked only at start of a combat damage step + // and all damage in the same step has to be handled the same beause by the rules it's all done at once + if (((DamagePlayerEvent) event).isCombatDamage()) { + if (lastCheckedDamageStepNum != game.getState().getStepNum()) { + lastCheckedDamageStepNum = game.getState().getStepNum(); + startedWithLifeAboveZero = player.getLife() > 0; + } + if (startedWithLifeAboveZero) { + return false; + } + } + if (player.getLife() <= 0) { + return true; + } } } + return false; } diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java index 20217ada44..d7fce8601e 100644 --- a/Mage/src/mage/game/GameState.java +++ b/Mage/src/mage/game/GameState.java @@ -105,6 +105,7 @@ public class GameState implements Serializable, Copyable { private Exile exile; private Battlefield battlefield; private int turnNum = 1; + private int stepNum = 0; private UUID turnId = null; private boolean extraTurn = false; private boolean legendaryRuleActive = true; @@ -149,6 +150,7 @@ public class GameState implements Serializable, Copyable { this.lookedAt.putAll(state.lookedAt); this.battlefield = state.battlefield.copy(); this.turnNum = state.turnNum; + this.stepNum = state.stepNum; this.extraTurn = state.extraTurn; this.legendaryRuleActive = state.legendaryRuleActive; this.gameOver = state.gameOver; @@ -351,6 +353,19 @@ public class GameState implements Serializable, Copyable { return combat; } + /** + * Gets the game step counter. This counter isgoing one up for + * every played step during the game. + * @return + */ + public int getStepNum() { + return stepNum; + } + + public void increaseStepNum() { + this.stepNum++; + } + public int getTurnNum() { return turnNum; } @@ -695,6 +710,7 @@ public class GameState implements Serializable, Copyable { revealed.clear(); lookedAt.clear(); turnNum = 0; + stepNum = 0; extraTurn = false; legendaryRuleActive = true; gameOver = false; diff --git a/Mage/src/mage/game/combat/CombatGroup.java b/Mage/src/mage/game/combat/CombatGroup.java index 9d0c92e2e8..e8211d2feb 100644 --- a/Mage/src/mage/game/combat/CombatGroup.java +++ b/Mage/src/mage/game/combat/CombatGroup.java @@ -53,11 +53,11 @@ import mage.util.Copyable; */ public class CombatGroup implements Serializable, Copyable { - protected List attackers = new ArrayList(); - protected List blockers = new ArrayList(); - protected List blockerOrder = new ArrayList(); - protected List attackerOrder = new ArrayList(); - protected Map players = new HashMap(); + protected List attackers = new ArrayList<>(); + protected List blockers = new ArrayList<>(); + protected List blockerOrder = new ArrayList<>(); + protected List attackerOrder = new ArrayList<>(); + protected Map players = new HashMap<>(); protected boolean blocked; protected UUID defenderId; // planeswalker or player protected UUID defendingPlayerId; @@ -274,7 +274,7 @@ public class CombatGroup implements Serializable, Copyable { int damage = getDamageValueFromPermanent(attacker, game); if (canDamage(attacker, first)) { // must be set before attacker damage marking because of effects like Test of Faith - Map blockerPower = new HashMap(); + Map blockerPower = new HashMap<>(); for (UUID blockerId: blockerOrder) { Permanent blocker = game.getPermanent(blockerId); if (canDamage(blocker, first)) { @@ -283,7 +283,7 @@ public class CombatGroup implements Serializable, Copyable { } } } - Map assigned = new HashMap(); + Map assigned = new HashMap<>(); if (blocked) { for (UUID blockerId: blockerOrder) { Permanent blocker = game.getPermanent(blockerId); @@ -316,8 +316,7 @@ public class CombatGroup implements Serializable, Copyable { Permanent blocker = game.getPermanent(entry.getKey()); blocker.markDamage(entry.getValue(), attacker.getId(), game, true, true); } - } - else { + } else { for (UUID blockerId: blockerOrder) { Permanent blocker = game.getPermanent(blockerId); if (canDamage(blocker, first)) { @@ -365,7 +364,7 @@ public class CombatGroup implements Serializable, Copyable { int damage = getDamageValueFromPermanent(blocker, game); if (canDamage(blocker, first)) { - Map assigned = new HashMap(); + Map assigned = new HashMap<>(); for (UUID attackerId: attackerOrder) { Permanent attacker = game.getPermanent(attackerId); int lethalDamage; @@ -437,7 +436,7 @@ public class CombatGroup implements Serializable, Copyable { return; } Player player = game.getPlayer(playerId); - List blockerList = new ArrayList(blockers); + List blockerList = new ArrayList<>(blockers); blockerOrder.clear(); while (true) { if (blockerList.size() == 1) { @@ -445,7 +444,7 @@ public class CombatGroup implements Serializable, Copyable { break; } else { - List blockerPerms = new ArrayList(); + List blockerPerms = new ArrayList<>(); for (UUID blockerId: blockerList) { blockerPerms.add(game.getPermanent(blockerId)); } @@ -461,7 +460,7 @@ public class CombatGroup implements Serializable, Copyable { return; } Player player = game.getPlayer(playerId); - List attackerList = new ArrayList(attackers); + List attackerList = new ArrayList<>(attackers); attackerOrder.clear(); while (true) { if (attackerList.size() == 1) { @@ -469,7 +468,7 @@ public class CombatGroup implements Serializable, Copyable { break; } else { - List attackerPerms = new ArrayList(); + List attackerPerms = new ArrayList<>(); for (UUID attackerId: attackerList) { attackerPerms.add(game.getPermanent(attackerId)); } @@ -532,7 +531,7 @@ public class CombatGroup implements Serializable, Copyable { return blockWasLegal; } if (blockersCount == 1) { - List toBeRemoved = new ArrayList(); + List toBeRemoved = new ArrayList<>(); for (UUID blockerId: getBlockers()) { Permanent blocker = game.getPermanent(blockerId); if (blocker != null && blocker.getAbilities().containsKey(CantBlockAloneAbility.getInstance().getId())) { diff --git a/Mage/src/mage/game/turn/Phase.java b/Mage/src/mage/game/turn/Phase.java index 51862172bc..db43252bdd 100644 --- a/Mage/src/mage/game/turn/Phase.java +++ b/Mage/src/mage/game/turn/Phase.java @@ -46,7 +46,7 @@ import mage.game.events.GameEvent.EventType; public abstract class Phase implements Serializable { protected TurnPhase type; - protected List steps = new ArrayList(); + protected List steps = new ArrayList<>(); protected EventType event; protected EventType preEvent; protected EventType postEvent; @@ -194,6 +194,7 @@ public abstract class Phase implements Serializable { protected void playStep(Game game) { if (!currentStep.skipStep(game, activePlayerId)) { + game.getState().increaseStepNum(); prePriority(game, activePlayerId); if (!game.isPaused() && !game.gameOver(null)) { currentStep.priority(game, activePlayerId, false);