diff --git a/Mage/src/mage/abilities/effects/PreventAllNonCombatDamageToEffect.java b/Mage/src/mage/abilities/effects/PreventAllNonCombatDamageToEffect.java index 9baed23a2d..6ae8602ede 100644 --- a/Mage/src/mage/abilities/effects/PreventAllNonCombatDamageToEffect.java +++ b/Mage/src/mage/abilities/effects/PreventAllNonCombatDamageToEffect.java @@ -47,7 +47,7 @@ public class PreventAllNonCombatDamageToEffect extends PreventionEffectImpl */ public abstract class PreventionEffectImpl> extends ReplacementEffectImpl implements PreventionEffect { + private Integer amountToPrevent; + public PreventionEffectImpl(Duration duration) { + this(duration, Integer.MAX_VALUE); + } + + public PreventionEffectImpl(Duration duration, int amountToPrevent) { super(duration, Outcome.PreventDamage); this.effectType = EffectType.PREVENTION; + this.amountToPrevent = amountToPrevent; } public PreventionEffectImpl(final PreventionEffectImpl effect) { super(effect); + this.amountToPrevent = effect.amountToPrevent; + } + + + @Override + public boolean apply(Game game, Ability source) { + // not used for prevention effect + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + game.preventDamage(event, source, game, amountToPrevent); + if (amountToPrevent == 0) { + this.used = true; + } + // damage amount is reduced or set to 0 so replace of damage event is never neccessary + return false; } @Override diff --git a/Mage/src/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.java b/Mage/src/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.java index eef36c9b19..1e9e85be49 100644 --- a/Mage/src/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.java @@ -28,6 +28,7 @@ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.PreventionEffectImpl; import mage.constants.Duration; @@ -68,17 +69,6 @@ public class PreventAllDamageByAttachedEffect extends PreventionEffectImpl { private FilterPermanent filter; - private boolean onlyCombat; + private final boolean onlyCombat; public PreventAllDamageEffect(FilterPermanent filter, Duration duration, boolean onlyCombat) { super(duration); @@ -52,7 +53,7 @@ public class PreventAllDamageEffect extends PreventionEffectImpl 0) { diff --git a/Mage/src/mage/abilities/effects/common/PreventAllDamageSourceEffect.java b/Mage/src/mage/abilities/effects/common/PreventAllDamageSourceEffect.java index 6ddf353e44..a9d67cd55e 100644 --- a/Mage/src/mage/abilities/effects/common/PreventAllDamageSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/PreventAllDamageSourceEffect.java @@ -28,9 +28,9 @@ package mage.abilities.effects.common; -import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.effects.PreventionEffectImpl; +import mage.constants.Duration; import mage.game.Game; import mage.game.events.GameEvent; @@ -41,7 +41,7 @@ import mage.game.events.GameEvent; public class PreventAllDamageSourceEffect extends PreventionEffectImpl { public PreventAllDamageSourceEffect(Duration duration) { - super(duration); + super(duration, Integer.MAX_VALUE); staticText = "Prevent all damage that would be dealt to {this} " + duration.toString(); } @@ -54,22 +54,6 @@ public class PreventAllDamageSourceEffect extends PreventionEffectImpl cardDao; diff --git a/Mage/src/mage/game/Game.java b/Mage/src/mage/game/Game.java index efe43b6ade..921f43ff5b 100644 --- a/Mage/src/mage/game/Game.java +++ b/Mage/src/mage/game/Game.java @@ -181,6 +181,27 @@ public interface Game extends MageItem, Serializable { void addSimultaneousEvent(GameEvent event); boolean replaceEvent(GameEvent event); + /** + * Creates and fires an damage prevention event + * + * @param damageEvent damage event that will be replaced (instanceof check will be done) + * @param source ability that's the source of the prevention effect + * @param game + * @param amountToPrevent + * @return true prevention was successfull / false prevention was replaced + */ + boolean preventDamage(GameEvent damageEvent, Ability source, Game game, Integer amountToPrevent); + /** + * Creates and fires an damage prevention event + * + * @param event damage event that will be replaced (instanceof check will be done) + * @param source ability that's the source of the prevention effect + * @param game + * @param preventAllDamage true if there is no limit to the damage that can be prevented + * @return true prevention was successfull / false prevention was replaced + */ + boolean preventDamage(GameEvent event, Ability source, Game game, boolean preventAllDamage); + //game play methods void start(UUID choosingPlayerId); void start(UUID choosingPlayerId, GameOptions options); diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index aed71cd8b6..76af929947 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -88,6 +88,7 @@ import mage.game.combat.Combat; import mage.game.command.CommandObject; import mage.game.command.Commander; import mage.game.command.Emblem; +import mage.game.events.DamageEvent; import mage.game.events.GameEvent; import mage.game.events.Listener; import mage.game.events.PlayerQueryEvent; @@ -1818,6 +1819,38 @@ public abstract class GameImpl> implements Game, Serializa return state.replaceEvent(event, this); } + @Override + public boolean preventDamage(GameEvent event, Ability source, Game game, boolean preventAllDamage) { + return preventDamage(event, source, game, Integer.MAX_VALUE); + } + + @Override + public boolean preventDamage(GameEvent event, Ability source, Game game, Integer amountToPrevent) { + if (!(event instanceof DamageEvent)) { + return false; + } + DamageEvent damageEvent = (DamageEvent) event; + GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, damageEvent.getTargetId(), damageEvent.getSourceId(), source.getControllerId(), damageEvent.getAmount(), false); + if (!game.replaceEvent(preventEvent)) { + int preventedDamage = damageEvent.getAmount(); + MageObject damageSource = game.getObject(damageEvent.getSourceId()); + MageObject preventionSource = game.getObject(source.getSourceId()); + if (damageSource != null && preventionSource != null) { + StringBuilder message = new StringBuilder(Integer.toString(preventedDamage)).append(" damage from "); + message.append(damageSource.getName()).append(" prevented "); + message.append("(").append(preventionSource).append(")"); + game.informPlayers(message.toString()); + } + damageEvent.setAmount(0); + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, damageEvent.getTargetId(), source.getSourceId(), source.getControllerId(), preventedDamage)); + return true; + } + return false; + } + + + + protected void removeCreaturesFromCombat() { //20091005 - 511.3 getCombat().endCombat(this); @@ -1831,7 +1864,7 @@ public abstract class GameImpl> implements Game, Serializa private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { //initialize transient objects during deserialization in.defaultReadObject(); - savedStates = new Stack(); + savedStates = new Stack<>(); tableEventSource = new TableEventSource(); playerQueryEventSource = new PlayerQueryEventSource(); gameStates = new GameStates();