diff --git a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java index 19ac2601d14..f4e8057594e 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/PhyrexianUnlife.java @@ -28,16 +28,17 @@ package mage.sets.newphyrexia; import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.continious.DontLoseByZeroOrLessLifeEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.abilities.Ability; -import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.keyword.LifelinkAbility; -import mage.cards.CardImpl; import mage.counters.CounterType; import mage.game.Game; import mage.game.events.DamagePlayerEvent; @@ -60,7 +61,7 @@ public class PhyrexianUnlife extends CardImpl { this.color.setWhite(true); // You don't lose the game for having 0 or less life. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PhyrexianUnlifeEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontLoseByZeroOrLessLifeEffect(Duration.WhileOnBattlefield))); // As long as you have 0 or less life, all damage is dealt to you as though its source had infect. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PhyrexianUnlifeEffect2())); @@ -77,45 +78,6 @@ public class PhyrexianUnlife extends CardImpl { } } -class PhyrexianUnlifeEffect extends ReplacementEffectImpl { - - public PhyrexianUnlifeEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit); - staticText = "You don't lose the game for having 0 or less life"; - } - - public PhyrexianUnlifeEffect(final PhyrexianUnlifeEffect effect) { - super(effect); - } - - @Override - public PhyrexianUnlifeEffect copy() { - return new PhyrexianUnlifeEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == EventType.LOSES && event.getPlayerId().equals(source.getControllerId())) { - Player player = game.getPlayer(event.getPlayerId()); - if (!player.hasLost() && (player.getLife() <= 0 && !player.isEmptyDraw() && player.getCounters().getCount(CounterType.POISON) < 10)) { - return true; - } - } - return false; - } - -} - class PhyrexianUnlifeEffect2 extends ReplacementEffectImpl { public PhyrexianUnlifeEffect2() { @@ -165,4 +127,4 @@ class PhyrexianUnlifeEffect2 extends ReplacementEffectImpl { + + public DontLoseByZeroOrLessLifeEffect(Duration duration) { + super(duration, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit); + staticText = "You don't lose the game for having 0 or less life"; + } + + public DontLoseByZeroOrLessLifeEffect(final DontLoseByZeroOrLessLifeEffect effect) { + super(effect); + } + + @Override + public DontLoseByZeroOrLessLifeEffect copy() { + return new DontLoseByZeroOrLessLifeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.setLoseByZeroOrLessLife(false); + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index f29ed959e4a..a0c55b50a0b 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1236,7 +1236,10 @@ public abstract class GameImpl> implements Game, Serializa //20091005 - 704.5a/704.5b/704.5c for (Player player: state.getPlayers().values()) { - if (!player.hasLost() && (player.getLife() <= 0 || player.isEmptyDraw() || player.getCounters().getCount(CounterType.POISON) >= 10)) { + if (!player.hasLost() + && ((player.getLife() <= 0 && player.canLoseByZeroOrLessLife()) + || player.isEmptyDraw() + || player.getCounters().getCount(CounterType.POISON) >= 10)) { player.lost(this); } } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index a89ed40f4f0..ae9f9d5c845 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -101,6 +101,9 @@ public interface Player extends MageItem, Copyable { boolean canPaySacrificeCost(); void setLifeTotalCanChange(boolean lifeTotalCanChange); boolean isLifeTotalCanChange(); + void setLoseByZeroOrLessLife(boolean LoseByZeroOrLessLife); + boolean canLoseByZeroOrLessLife(); + /** * Returns alternative casting costs a player can cast spells for * diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index daba32ed7e3..dc4cfd8ff1d 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -163,11 +163,14 @@ public abstract class PlayerImpl> implements Player, Ser protected RangeOfInfluence range; protected Set inRange = new HashSet<>(); + protected boolean isTestMode = false; protected boolean canGainLife = true; protected boolean canLoseLife = true; protected boolean canPayLifeCost = true; protected boolean canPaySacrificeCost = true; + protected boolean loseByZeroOrLessLife = true; + protected final List alternativeSourceCosts = new ArrayList<>(); protected boolean isGameUnderControl = true; @@ -234,6 +237,8 @@ public abstract class PlayerImpl> implements Player, Ser this.range = player.range; this.canGainLife = player.canGainLife; this.canLoseLife = player.canLoseLife; + this.loseByZeroOrLessLife = player.loseByZeroOrLessLife; + this.attachments.addAll(player.attachments); this.inRange.addAll(player.inRange); @@ -294,6 +299,7 @@ public abstract class PlayerImpl> implements Player, Ser this.userData = player.getUserData(); this.canPayLifeCost = player.canPayLifeCost(); this.canPaySacrificeCost = player.canPaySacrificeCost(); + this.loseByZeroOrLessLife = player.canLoseByZeroOrLessLife(); this.alternativeSourceCosts.addAll(player.getAlternativeSourceCosts()); this.storedBookmark = player.getStoredBookmark(); @@ -359,6 +365,7 @@ public abstract class PlayerImpl> implements Player, Ser this.canLoseLife = true; this.canPayLifeCost = true; this.canPaySacrificeCost = true; + this.loseByZeroOrLessLife = true; this.topCardRevealed = false; this.alternativeSourceCosts.clear(); } @@ -1558,7 +1565,7 @@ public abstract class PlayerImpl> implements Player, Ser opponentsAlive++; } } - if (opponentsAlive == 0) { + if (opponentsAlive == 0 && !hasWon()) { game.informPlayers(new StringBuilder(this.getName()).append(" has won the game").toString()); this.wins = true; game.end(); @@ -2042,6 +2049,16 @@ public abstract class PlayerImpl> implements Player, Ser this.canPaySacrificeCost = canPaySacrificeCost; } + @Override + public boolean canLoseByZeroOrLessLife() { + return loseByZeroOrLessLife; + } + + @Override + public void setLoseByZeroOrLessLife(boolean loseByZeroOrLessLife) { + this.loseByZeroOrLessLife = loseByZeroOrLessLife; + } + @Override public boolean autoLoseGame() { return false;