* 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.

This commit is contained in:
LevelX2 2014-06-28 10:30:47 +02:00
parent 3ee609d98b
commit 53964ee80c
4 changed files with 54 additions and 19 deletions

View file

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

View file

@ -105,6 +105,7 @@ public class GameState implements Serializable, Copyable<GameState> {
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<GameState> {
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<GameState> {
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<GameState> {
revealed.clear();
lookedAt.clear();
turnNum = 0;
stepNum = 0;
extraTurn = false;
legendaryRuleActive = true;
gameOver = false;

View file

@ -53,11 +53,11 @@ import mage.util.Copyable;
*/
public class CombatGroup implements Serializable, Copyable<CombatGroup> {
protected List<UUID> attackers = new ArrayList<UUID>();
protected List<UUID> blockers = new ArrayList<UUID>();
protected List<UUID> blockerOrder = new ArrayList<UUID>();
protected List<UUID> attackerOrder = new ArrayList<UUID>();
protected Map<UUID, UUID> players = new HashMap<UUID, UUID>();
protected List<UUID> attackers = new ArrayList<>();
protected List<UUID> blockers = new ArrayList<>();
protected List<UUID> blockerOrder = new ArrayList<>();
protected List<UUID> attackerOrder = new ArrayList<>();
protected Map<UUID, UUID> 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<CombatGroup> {
int damage = getDamageValueFromPermanent(attacker, game);
if (canDamage(attacker, first)) {
// must be set before attacker damage marking because of effects like Test of Faith
Map<UUID, Integer> blockerPower = new HashMap<UUID, Integer>();
Map<UUID, Integer> 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<CombatGroup> {
}
}
}
Map<UUID, Integer> assigned = new HashMap<UUID, Integer>();
Map<UUID, Integer> assigned = new HashMap<>();
if (blocked) {
for (UUID blockerId: blockerOrder) {
Permanent blocker = game.getPermanent(blockerId);
@ -316,8 +316,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
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<CombatGroup> {
int damage = getDamageValueFromPermanent(blocker, game);
if (canDamage(blocker, first)) {
Map<UUID, Integer> assigned = new HashMap<UUID, Integer>();
Map<UUID, Integer> assigned = new HashMap<>();
for (UUID attackerId: attackerOrder) {
Permanent attacker = game.getPermanent(attackerId);
int lethalDamage;
@ -437,7 +436,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
return;
}
Player player = game.getPlayer(playerId);
List<UUID> blockerList = new ArrayList<UUID>(blockers);
List<UUID> blockerList = new ArrayList<>(blockers);
blockerOrder.clear();
while (true) {
if (blockerList.size() == 1) {
@ -445,7 +444,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
break;
}
else {
List<Permanent> blockerPerms = new ArrayList<Permanent>();
List<Permanent> blockerPerms = new ArrayList<>();
for (UUID blockerId: blockerList) {
blockerPerms.add(game.getPermanent(blockerId));
}
@ -461,7 +460,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
return;
}
Player player = game.getPlayer(playerId);
List<UUID> attackerList = new ArrayList<UUID>(attackers);
List<UUID> attackerList = new ArrayList<>(attackers);
attackerOrder.clear();
while (true) {
if (attackerList.size() == 1) {
@ -469,7 +468,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
break;
}
else {
List<Permanent> attackerPerms = new ArrayList<Permanent>();
List<Permanent> attackerPerms = new ArrayList<>();
for (UUID attackerId: attackerList) {
attackerPerms.add(game.getPermanent(attackerId));
}
@ -532,7 +531,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
return blockWasLegal;
}
if (blockersCount == 1) {
List<UUID> toBeRemoved = new ArrayList<UUID>();
List<UUID> toBeRemoved = new ArrayList<>();
for (UUID blockerId: getBlockers()) {
Permanent blocker = game.getPermanent(blockerId);
if (blocker != null && blocker.getAbilities().containsKey(CantBlockAloneAbility.getInstance().getId())) {

View file

@ -46,7 +46,7 @@ import mage.game.events.GameEvent.EventType;
public abstract class Phase implements Serializable {
protected TurnPhase type;
protected List<Step> steps = new ArrayList<Step>();
protected List<Step> 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);