diff --git a/Mage.Sets/src/mage/sets/magic2010/SafePassage.java b/Mage.Sets/src/mage/sets/magic2010/SafePassage.java index fbfc73a84d2..fc39108c271 100644 --- a/Mage.Sets/src/mage/sets/magic2010/SafePassage.java +++ b/Mage.Sets/src/mage/sets/magic2010/SafePassage.java @@ -32,6 +32,7 @@ import java.util.UUID; import mage.Constants.CardType; import mage.Constants.Duration; import mage.Constants.Rarity; +import mage.Constants.TargetController; import mage.abilities.effects.common.PreventAllDamageToEffect; import mage.cards.CardImpl; import mage.filter.common.FilterCreatureOrPlayer; @@ -42,11 +43,18 @@ import mage.filter.common.FilterCreatureOrPlayer; */ public class SafePassage extends CardImpl { + private static FilterCreatureOrPlayer filter = new FilterCreatureOrPlayer("you and creatures you control"); + + static { + filter.getCreatureFilter().setTargetController(TargetController.YOU); + filter.getPlayerFilter().setPlayerTarget(TargetController.YOU); + } + public SafePassage(UUID ownerId) { super(ownerId, 28, "Safe Passage", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{W}"); this.expansionSetCode = "M10"; this.color.setWhite(true); - this.getSpellAbility().addEffect(new PreventAllDamageToEffect(Duration.EndOfTurn, new FilterCreatureOrPlayer("you and creatures you control", ownerId))); + this.getSpellAbility().addEffect(new PreventAllDamageToEffect(Duration.EndOfTurn, filter)); } public SafePassage(final SafePassage card) { diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index f8bda1ad99b..c002be2da15 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -62,7 +62,7 @@ public abstract class AbilityImpl> implements Ability { private final static transient Logger logger = Logging.getLogger(AbilityImpl.class.getName()); - protected final UUID id; + protected UUID id; protected AbilityType abilityType; protected UUID controllerId; protected UUID sourceId; diff --git a/Mage/src/mage/abilities/SpellAbility.java b/Mage/src/mage/abilities/SpellAbility.java index b05a33759e8..7df3489821d 100644 --- a/Mage/src/mage/abilities/SpellAbility.java +++ b/Mage/src/mage/abilities/SpellAbility.java @@ -90,4 +90,10 @@ public class SpellAbility extends ActivatedAbilityImpl { return new SpellAbility(this); } + public SpellAbility copySpell() { + SpellAbility spell = new SpellAbility(this); + spell.id = UUID.randomUUID(); + return spell; + } + } diff --git a/Mage/src/mage/abilities/effects/PreventionEffectImpl.java b/Mage/src/mage/abilities/effects/PreventionEffectImpl.java index c3fc4f78c17..8b7e8a1f0fa 100644 --- a/Mage/src/mage/abilities/effects/PreventionEffectImpl.java +++ b/Mage/src/mage/abilities/effects/PreventionEffectImpl.java @@ -40,7 +40,7 @@ import mage.game.events.GameEvent; * * @author BetaSteward_at_googlemail.com */ -public abstract class PreventionEffectImpl> extends ReplacementEffectImpl { +public abstract class PreventionEffectImpl> extends ReplacementEffectImpl implements PreventionEffect { public PreventionEffectImpl(Duration duration) { super(duration, Outcome.PreventDamage); diff --git a/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java b/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java index f3ec30cd41a..cbcdab40289 100644 --- a/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java @@ -75,7 +75,7 @@ public class CantTargetSourceEffect extends ReplacementEffectImpl public boolean apply(Game game, Ability source) { Spell spell = game.getStack().getSpell(source.getFirstTarget()); if (spell != null) { - Spell copy = spell.copy(); + Spell copy = spell.copySpell(); copy.setControllerId(source.getControllerId()); game.getStack().push(copy); copy.chooseNewTargets(game); diff --git a/Mage/src/mage/abilities/effects/common/PreventAllDamageToEffect.java b/Mage/src/mage/abilities/effects/common/PreventAllDamageToEffect.java index 084ff37e2d1..f172b9f9891 100644 --- a/Mage/src/mage/abilities/effects/common/PreventAllDamageToEffect.java +++ b/Mage/src/mage/abilities/effects/common/PreventAllDamageToEffect.java @@ -32,6 +32,7 @@ import mage.Constants.Duration; import mage.abilities.Ability; import mage.abilities.effects.PreventionEffectImpl; import mage.filter.Filter; +import mage.filter.FilterInPlay; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -43,9 +44,9 @@ import mage.players.Player; */ public class PreventAllDamageToEffect extends PreventionEffectImpl { - protected Filter filter; + protected FilterInPlay filter; - public PreventAllDamageToEffect(Duration duration, Filter filter) { + public PreventAllDamageToEffect(Duration duration, FilterInPlay filter) { super(duration); this.filter = filter; } @@ -81,12 +82,12 @@ public class PreventAllDamageToEffect extends PreventionEffectImpl extends Serializable { +public interface Filter extends Serializable { public enum ComparisonType { GreaterThan, Equal, LessThan @@ -44,11 +44,11 @@ public interface Filter extends Serializable { Any, All } - public boolean match(T o); + public boolean match(E o); public String getMessage(); public void setMessage(String message); public void setNotFilter(boolean notFilter); - public Filter copy(); + public Filter copy(); } diff --git a/Mage/src/mage/filter/FilterPlayer.java b/Mage/src/mage/filter/FilterPlayer.java index eb40d13b949..e8a7bac99be 100644 --- a/Mage/src/mage/filter/FilterPlayer.java +++ b/Mage/src/mage/filter/FilterPlayer.java @@ -31,6 +31,8 @@ package mage.filter; import java.util.ArrayList; import java.util.List; import java.util.UUID; +import mage.Constants.TargetController; +import mage.game.Game; import mage.players.Player; /** @@ -41,6 +43,7 @@ public class FilterPlayer extends FilterImpl implements Fi protected List playerId = new ArrayList(); protected boolean notPlayer; + protected TargetController playerTarget = TargetController.ANY; public FilterPlayer() { super("player"); @@ -52,6 +55,7 @@ public class FilterPlayer extends FilterImpl implements Fi this.playerId.add(pId); } this.notPlayer = filter.notPlayer; + this.playerTarget = filter.playerTarget; } @Override @@ -63,6 +67,30 @@ public class FilterPlayer extends FilterImpl implements Fi return !notFilter; } + public boolean match(Player player, UUID playerId, Game game) { + if (!this.match(player)) + return notFilter; + + if (playerTarget != TargetController.ANY && playerId != null) { + switch(playerTarget) { + case YOU: + if (!player.getId().equals(playerId)) + return notFilter; + break; + case OPPONENT: + if (!game.getOpponents(playerId).contains(player.getId())) + return notFilter; + break; + case NOT_YOU: + if (player.getId().equals(playerId)) + return notFilter; + break; + } + } + + return !notFilter; + } + public List getPlayerId() { return playerId; } @@ -71,6 +99,10 @@ public class FilterPlayer extends FilterImpl implements Fi this.notPlayer = notPlayer; } + public void setPlayerTarget(TargetController playerTarget) { + this.playerTarget = playerTarget; + } + @Override public FilterPlayer copy() { return new FilterPlayer(this); diff --git a/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java b/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java index 63210f3e8e6..0302fba16ac 100644 --- a/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java +++ b/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java @@ -31,6 +31,7 @@ package mage.filter.common; import java.util.UUID; import mage.filter.Filter; import mage.filter.FilterImpl; +import mage.filter.FilterInPlay; import mage.filter.FilterPlayer; import mage.game.Game; import mage.game.permanent.Permanent; @@ -40,7 +41,7 @@ import mage.players.Player; * * @author BetaSteward_at_googlemail.com */ -public class FilterCreatureOrPlayer extends FilterImpl implements Filter { +public class FilterCreatureOrPlayer extends FilterImpl implements FilterInPlay { protected FilterCreaturePermanent creatureFilter; protected FilterPlayer playerFilter; @@ -80,9 +81,10 @@ public class FilterCreatureOrPlayer extends FilterImpl { public void handleEvent(GameEvent event, Game game) { watchers.watch(event, game); if (!replaceEvent(event, game)) { + //TODO: this is awkward - improve if (event.getType() == EventType.ZONE_CHANGE) { ZoneChangeEvent zEvent = (ZoneChangeEvent)event; if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - zEvent.getTarget().checkTriggers(zEvent.getFromZone(), event, game); - zEvent.getTarget().checkTriggers(zEvent.getToZone(), event, game); + if (zEvent.getTarget() instanceof PermanentCard) { + ((PermanentCard)zEvent.getTarget()).checkPermanentOnlyTriggers(zEvent, game); + } + else { + zEvent.getTarget().checkTriggers(zEvent.getFromZone(), event, game); + zEvent.getTarget().checkTriggers(zEvent.getToZone(), event, game); + } } } for (Player player: players.values()) { diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java index c9515d94c6d..b7711567647 100644 --- a/Mage/src/mage/game/permanent/PermanentCard.java +++ b/Mage/src/mage/game/permanent/PermanentCard.java @@ -35,10 +35,12 @@ import mage.Constants.CardType; import mage.Constants.Zone; import mage.MageInt; import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; import mage.abilities.keyword.LevelAbility; import mage.cards.Card; import mage.cards.LevelerCard; import mage.game.Game; +import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.players.Player; @@ -112,6 +114,21 @@ public class PermanentCard extends PermanentImpl { this.cardNumber = card.getCardNumber(); } + public void checkPermanentOnlyTriggers(ZoneChangeEvent event, Game game) { + // we only want to trigger abilities that are not on the underlying card ie. have been added by another effect + // card abilities will get triggered later when the card hits the new zone + Card card = game.getCard(objectId).copy(); + for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getFromZone())) { + if (!card.getAbilities().containsKey(ability.getId())) + ability.checkTrigger(event, game); + } + for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getToZone())) { + if (!card.getAbilities().containsKey(ability.getId())) + ability.checkTrigger(event, game); + } + } + + @Override public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) { Zone fromZone = game.getZone(objectId); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index ff1158046d3..69743fb94d3 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -496,19 +496,6 @@ public abstract class PermanentImpl> extends CardImpl return (!hasProtectionFrom(source)); } -// protected void addEffects(Game game) { -// for (Ability ability: abilities.getStaticAbilities(Zone.BATTLEFIELD)) { -// if (ability instanceof EntersBattlefieldStaticAbility) { -// for (Effect effect: ability.getEffects()) { -// if (effect instanceof OneShotEffect) { -// //20100423 - 603.6e -// effect.apply(game, ability); -// } -// } -// } -// } -// } - @Override public boolean destroy(UUID sourceId, Game game, boolean noRegen) { //20091005 - 701.6 diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 5c961a6a54e..fdd9203679d 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -283,10 +283,14 @@ public class Spell> implements StackObject, Card { public void setExpansionSetCode(String expansionSetCode) {} @Override - public Spell copy() { - return new Spell(this); + public Spell copy() { + return new Spell(this); } + public Spell copySpell() { + return new Spell(this.card.copy(), this.ability.copySpell(), this.controllerId); + } + @Override public void adjustCosts(Ability ability, Game game) {}