From 5eae8136e40add7603cb73bf94a5b9df6e7098e9 Mon Sep 17 00:00:00 2001 From: BetaSteward Date: Wed, 6 Oct 2010 01:51:53 +0000 Subject: [PATCH] ... --- Mage/src/mage/Constants.java | 11 + Mage/src/mage/abilities/Ability.java | 3 + Mage/src/mage/abilities/AbilityImpl.java | 40 ++- Mage/src/mage/abilities/SpellAbility.java | 8 +- Mage/src/mage/abilities/TriggeredAbility.java | 2 +- .../mage/abilities/TriggeredAbilityImpl.java | 6 +- .../costs/common/ReturnToHandTargetCost.java | 1 - .../abilities/effects/AsThoughEffect.java | 45 +++ .../abilities/effects/AsThoughEffectImpl.java | 58 ++++ .../abilities/effects/ContinuousEffect.java | 1 + .../effects/ContinuousEffectImpl.java | 7 + .../abilities/effects/ContinuousEffects.java | 267 ++++++++++-------- .../effects/PreventionEffectImpl.java | 1 - .../abilities/effects/ReplacementEffect.java | 1 - .../effects/ReplacementEffectImpl.java | 8 - .../common/CantTargetControlledEffect.java | 16 +- .../common/CantTargetControllerEffect.java | 94 ++++++ .../common/CounterUnlessPaysEffect.java | 2 +- .../effects/common/CreateTokenEffect.java | 3 +- .../effects/common/DamageAllEffect.java | 2 +- .../common/DamageControllerEffect.java | 1 - .../common/DamageEverythingEffect.java | 81 ++++++ .../effects/common/DrawCardAllEffect.java | 8 +- .../common/PreventAllCombatDamageEffect.java | 7 +- .../common/PreventAllDamageSourceEffect.java | 7 +- .../common/PreventAllDamageToEffect.java | 7 +- .../common/PreventDamageTargetEffect.java | 20 +- .../common/PutOnLibraryTargetEffect.java | 11 +- .../effects/common/ReturnFromExileEffect.java | 14 +- ...ourceFromGraveyardToBattlefieldEffect.java | 4 +- ...ReturnSourceFromGraveyardToHandEffect.java | 75 +++++ .../effects/common/SacrificeAllEffect.java | 3 +- .../abilities/effects/common/ScryEffect.java | 13 +- .../common/SearchLibraryPutInHandEffect.java | 8 +- .../common/SearchLibraryPutInPlayEffect.java | 9 +- .../SearchLibraryPutOnLibraryEffect.java | 84 ++++++ .../SearchLibraryRevealPutInHandEffect.java | 2 +- .../abilities/keyword/CascadeAbility.java | 6 +- .../mage/abilities/keyword/EquipAbility.java | 9 +- .../abilities/keyword/FortifyAbility.java | 12 +- .../abilities/keyword/LeylineAbility.java | 65 +++++ Mage/src/mage/cards/Card.java | 3 + Mage/src/mage/cards/CardImpl.java | 59 ++++ Mage/src/mage/filter/Filter.java | 1 + Mage/src/mage/filter/FilterPermanent.java | 54 +++- Mage/src/mage/filter/FilterSpell.java | 27 +- Mage/src/mage/filter/FilterStackObject.java | 36 ++- .../FilterControlledCreaturePermanent.java | 59 ++++ .../common/FilterControlledPermanent.java | 58 ++++ .../filter/common/FilterCreatureOrPlayer.java | 12 + Mage/src/mage/game/GameImpl.java | 14 +- Mage/src/mage/game/events/GameEvent.java | 5 +- .../src/mage/game/events/ZoneChangeEvent.java | 4 + Mage/src/mage/game/permanent/Battlefield.java | 6 +- .../mage/game/permanent/PermanentCard.java | 37 +-- .../mage/game/permanent/PermanentToken.java | 8 +- Mage/src/mage/game/permanent/token/Token.java | 15 + Mage/src/mage/game/stack/Spell.java | 27 +- Mage/src/mage/game/stack/StackAbility.java | 15 + Mage/src/mage/players/Player.java | 4 +- Mage/src/mage/players/PlayerImpl.java | 34 +-- Mage/src/mage/target/TargetPermanent.java | 52 +--- .../common/TargetAttackingCreature.java | 10 +- .../TargetControlledCreaturePermanent.java | 60 ++++ .../common/TargetControlledPermanent.java | 15 +- .../target/common/TargetCreatureOrPlayer.java | 6 +- .../common/TargetCreatureOrPlayerAmount.java | 6 +- .../common/TargetCreaturePermanent.java | 13 +- .../target/common/TargetLandPermanent.java | 12 +- .../target/common/TargetNonlandPermanent.java | 11 +- 70 files changed, 1286 insertions(+), 399 deletions(-) create mode 100644 Mage/src/mage/abilities/effects/AsThoughEffect.java create mode 100644 Mage/src/mage/abilities/effects/AsThoughEffectImpl.java create mode 100644 Mage/src/mage/abilities/effects/common/CantTargetControllerEffect.java create mode 100644 Mage/src/mage/abilities/effects/common/DamageEverythingEffect.java create mode 100644 Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java create mode 100644 Mage/src/mage/abilities/effects/common/SearchLibraryPutOnLibraryEffect.java create mode 100644 Mage/src/mage/abilities/keyword/LeylineAbility.java create mode 100644 Mage/src/mage/filter/common/FilterControlledCreaturePermanent.java create mode 100644 Mage/src/mage/filter/common/FilterControlledPermanent.java create mode 100644 Mage/src/mage/target/common/TargetControlledCreaturePermanent.java diff --git a/Mage/src/mage/Constants.java b/Mage/src/mage/Constants.java index 83027c44759..ce24f9116b3 100644 --- a/Mage/src/mage/Constants.java +++ b/Mage/src/mage/Constants.java @@ -90,6 +90,7 @@ public final class Constants { public enum Rarity { + NA ("na", "na"), LAND ("Land", "common"), COMMON ("Common", "common"), UNCOMMON ("Uncommon", "uncommon"), @@ -138,6 +139,16 @@ public final class Constants { } } + public enum AsThoughEffectType { + BLOCK, + BE_BLOCKED, + ATTACK, + CAST, + TARGET, + PAY, + DAMAGE + } + public enum Duration { OneUse(""), EndOfGame("for the rest of the game"), diff --git a/Mage/src/mage/abilities/Ability.java b/Mage/src/mage/abilities/Ability.java index 6833c70002f..f7485df3f13 100644 --- a/Mage/src/mage/abilities/Ability.java +++ b/Mage/src/mage/abilities/Ability.java @@ -58,6 +58,8 @@ public interface Ability extends Serializable { public void addManaCost(ManaCost cost); public List getAlternativeCosts(); public void addAlternativeCost(AlternativeCost cost); + public Costs getOptionalCosts(); + public void addOptionalCost(Cost cost); public Effects getEffects(); public void addEffect(Effect effect); public Targets getTargets(); @@ -71,6 +73,7 @@ public interface Ability extends Serializable { public boolean activate(Game game, boolean noMana); public boolean resolve(Game game); public void reset(Game game); + public boolean checkIfClause(Game game); public void setControllerId(UUID controllerId); public void setSourceId(UUID sourceID); diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index f7dff588a25..4aee829c453 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -68,6 +68,7 @@ public abstract class AbilityImpl> implements Ability { protected ManaCosts manaCosts; protected Costs costs; protected ArrayList alternativeCosts = new ArrayList(); + protected Costs optionalCosts; protected Targets targets; protected Choices choices; protected Effects effects; @@ -84,6 +85,7 @@ public abstract class AbilityImpl> implements Ability { this.zone = zone; this.manaCosts = new ManaCostsImpl(); this.costs = new CostsImpl(); + this.optionalCosts = new CostsImpl(); this.effects = new Effects(); this.targets = new Targets(); this.choices = new Choices(); @@ -99,6 +101,7 @@ public abstract class AbilityImpl> implements Ability { this.usesStack = ability.usesStack; this.manaCosts = ability.manaCosts.copy(); this.costs = ability.costs.copy(); + this.optionalCosts = ability.optionalCosts.copy(); for (AlternativeCost cost: ability.alternativeCosts) { this.alternativeCosts.add((AlternativeCost)cost.copy()); } @@ -120,12 +123,15 @@ public abstract class AbilityImpl> implements Ability { @Override public boolean resolve(Game game) { boolean result = true; - for (Effect effect: getEffects()) { - if (effect instanceof OneShotEffect) { - result &= effect.apply(game, this); - } - else { - game.addEffect((ContinuousEffect) effect, this); + //20100716 - 117.12 + if (checkIfClause(game)) { + for (Effect effect: getEffects()) { + if (effect instanceof OneShotEffect) { + result &= effect.apply(game, this); + } + else { + game.addEffect((ContinuousEffect) effect, this); + } } } return result; @@ -168,6 +174,11 @@ public abstract class AbilityImpl> implements Ability { return false; } + @Override + public boolean checkIfClause(Game game) { + return true; + } + @Override public UUID getControllerId() { return controllerId; @@ -204,6 +215,11 @@ public abstract class AbilityImpl> implements Ability { return alternativeCosts; } + @Override + public Costs getOptionalCosts() { + return optionalCosts; + } + @Override public Effects getEffects() { return effects; @@ -260,11 +276,6 @@ public abstract class AbilityImpl> implements Ability { return sbRule.toString(); } -// @Override -// public String getName() { -// return ""; -// } - @Override public void addCost(Cost cost) { if (cost != null) { @@ -286,6 +297,13 @@ public abstract class AbilityImpl> implements Ability { } } + @Override + public void addOptionalCost(Cost cost) { + if (cost != null) { + this.optionalCosts.add(cost); + } + } + @Override public void addEffect(Effect effect) { if (effect != null) { diff --git a/Mage/src/mage/abilities/SpellAbility.java b/Mage/src/mage/abilities/SpellAbility.java index e6827e8a3b0..b05a33759e8 100644 --- a/Mage/src/mage/abilities/SpellAbility.java +++ b/Mage/src/mage/abilities/SpellAbility.java @@ -30,8 +30,10 @@ package mage.abilities; import java.util.UUID; import mage.Constants.AbilityType; +import mage.Constants.AsThoughEffectType; import mage.Constants.CardType; import mage.Constants.Zone; +import mage.MageObject; import mage.abilities.costs.mana.ManaCost; import mage.abilities.keyword.FlashAbility; import mage.game.Game; @@ -54,8 +56,10 @@ public class SpellAbility extends ActivatedAbilityImpl { @Override public boolean canActivate(UUID playerId, Game game) { - if ((game.getObject(sourceId).getCardType().contains(CardType.INSTANT) || - game.getObject(sourceId).getAbilities().containsKey(FlashAbility.getInstance().getId()) || + MageObject object = game.getObject(sourceId); + if ((object.getCardType().contains(CardType.INSTANT) || + object.getAbilities().containsKey(FlashAbility.getInstance().getId()) || + game.getContinuousEffects().asThough(sourceId, AsThoughEffectType.CAST, game) || game.canPlaySorcery(playerId))) { if (costs.canPay(sourceId, controllerId, game) && targets.canChoose(sourceId, playerId, game)) { return true; diff --git a/Mage/src/mage/abilities/TriggeredAbility.java b/Mage/src/mage/abilities/TriggeredAbility.java index e1299fd2480..763052272cd 100644 --- a/Mage/src/mage/abilities/TriggeredAbility.java +++ b/Mage/src/mage/abilities/TriggeredAbility.java @@ -40,6 +40,6 @@ public interface TriggeredAbility extends Ability { public void trigger(Game game, UUID controllerId); public boolean checkTrigger(GameEvent event, Game game); - public boolean checkIfClause(Game game); + public boolean checkInterveningIfClause(Game game); } diff --git a/Mage/src/mage/abilities/TriggeredAbilityImpl.java b/Mage/src/mage/abilities/TriggeredAbilityImpl.java index 0b7504d605c..ffdff7caa5a 100644 --- a/Mage/src/mage/abilities/TriggeredAbilityImpl.java +++ b/Mage/src/mage/abilities/TriggeredAbilityImpl.java @@ -63,14 +63,14 @@ public abstract class TriggeredAbilityImpl> ex @Override public void trigger(Game game, UUID controllerId) { //20091005 - 603.4 - if (checkIfClause(game)) { + if (checkInterveningIfClause(game)) { this.controllerId = controllerId; game.addTriggeredAbility(this); } } @Override - public boolean checkIfClause(Game game) { + public boolean checkInterveningIfClause(Game game) { return true; } @@ -84,7 +84,7 @@ public abstract class TriggeredAbilityImpl> ex } } //20091005 - 603.4 - if (checkIfClause(game)) + if (checkInterveningIfClause(game)) return super.resolve(game); return false; } diff --git a/Mage/src/mage/abilities/costs/common/ReturnToHandTargetCost.java b/Mage/src/mage/abilities/costs/common/ReturnToHandTargetCost.java index 9eed9a4f1af..0de197a4730 100644 --- a/Mage/src/mage/abilities/costs/common/ReturnToHandTargetCost.java +++ b/Mage/src/mage/abilities/costs/common/ReturnToHandTargetCost.java @@ -31,7 +31,6 @@ package mage.abilities.costs.common; import java.util.UUID; import mage.Constants.Outcome; import mage.Constants.Zone; -import mage.abilities.Ability; import mage.abilities.costs.CostImpl; import mage.game.Game; import mage.game.permanent.Permanent; diff --git a/Mage/src/mage/abilities/effects/AsThoughEffect.java b/Mage/src/mage/abilities/effects/AsThoughEffect.java new file mode 100644 index 00000000000..5d339d1939b --- /dev/null +++ b/Mage/src/mage/abilities/effects/AsThoughEffect.java @@ -0,0 +1,45 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.effects; + +import java.util.UUID; +import mage.Constants.AsThoughEffectType; +import mage.abilities.Ability; +import mage.game.Game; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public interface AsThoughEffect> extends ContinuousEffect { + + public boolean applies(UUID sourceId, Ability source, Game game); + public AsThoughEffectType getAsThoughEffectType(); + +} diff --git a/Mage/src/mage/abilities/effects/AsThoughEffectImpl.java b/Mage/src/mage/abilities/effects/AsThoughEffectImpl.java new file mode 100644 index 00000000000..46ce0996b0d --- /dev/null +++ b/Mage/src/mage/abilities/effects/AsThoughEffectImpl.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.effects; + +import mage.Constants.AsThoughEffectType; +import mage.Constants.Duration; +import mage.Constants.Outcome; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public abstract class AsThoughEffectImpl> extends ContinuousEffectImpl implements AsThoughEffect { + + protected AsThoughEffectType type; + + public AsThoughEffectImpl(AsThoughEffectType type, Duration duration, Outcome outcome) { + super(duration, outcome); + this.type = type; + } + + public AsThoughEffectImpl(final AsThoughEffectImpl effect) { + super(effect); + this.type = effect.type; + } + + @Override + public AsThoughEffectType getAsThoughEffectType() { + return type; + } + +} diff --git a/Mage/src/mage/abilities/effects/ContinuousEffect.java b/Mage/src/mage/abilities/effects/ContinuousEffect.java index ffaeb005094..317bdde4ef7 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffect.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffect.java @@ -41,6 +41,7 @@ import mage.game.Game; */ public interface ContinuousEffect> extends Effect { + public boolean isUsed(); public Duration getDuration(); public Date getTimestamp(); public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game); diff --git a/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java b/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java index 09de9afecc7..d0b300624a8 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffectImpl.java @@ -46,6 +46,7 @@ public abstract class ContinuousEffectImpl> ex protected Layer layer; protected SubLayer sublayer; protected Date timestamp; + protected boolean used = false; public ContinuousEffectImpl(Duration duration, Outcome outcome) { super(outcome); @@ -65,6 +66,7 @@ public abstract class ContinuousEffectImpl> ex this.layer = effect.layer; this.sublayer = effect.sublayer; this.timestamp = new Date(effect.timestamp.getTime()); + this.used = effect.used; } @Override @@ -90,4 +92,9 @@ public abstract class ContinuousEffectImpl> ex return this.layer == layer; } + @Override + public boolean isUsed() { + return used; + } + } diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index c9d85af9f87..aef344c6c29 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -37,6 +37,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.UUID; +import mage.Constants.AsThoughEffectType; import mage.Constants.Duration; import mage.Constants.Layer; import mage.Constants.SubLayer; @@ -46,25 +48,35 @@ import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; - - /** * * @author BetaSteward_at_googlemail.com */ public class ContinuousEffects implements Serializable { - private final Map effects = new HashMap(); + private final Map layeredEffects = new HashMap(); + private final Map replacementEffects = new HashMap(); + private final Map preventionEffects = new HashMap(); + private final Map asThoughEffects = new HashMap(); private final ApplyCountersEffect applyCounters; public ContinuousEffects() { applyCounters = new ApplyCountersEffect(); } - public ContinuousEffects(ContinuousEffects effect) { + public ContinuousEffects(final ContinuousEffects effect) { this.applyCounters = effect.applyCounters.copy(); - for (Entry entry: effect.effects.entrySet()) { - effects.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy()); + for (Entry entry: effect.layeredEffects.entrySet()) { + layeredEffects.put((ContinuousEffect)entry.getKey().copy(), entry.getValue().copy()); + } + for (Entry entry: effect.replacementEffects.entrySet()) { + replacementEffects.put((ReplacementEffect)entry.getKey().copy(), entry.getValue().copy()); + } + for (Entry entry: effect.preventionEffects.entrySet()) { + preventionEffects.put((PreventionEffect)entry.getKey().copy(), entry.getValue().copy()); + } + for (Entry entry: effect.asThoughEffects.entrySet()) { + asThoughEffects.put((AsThoughEffect)entry.getKey().copy(), entry.getValue().copy()); } } @@ -73,7 +85,22 @@ public class ContinuousEffects implements Serializable { } public void removeEndOfTurnEffects() { - for (Iterator i = effects.keySet().iterator(); i.hasNext();) { + for (Iterator i = layeredEffects.keySet().iterator(); i.hasNext();) { + ContinuousEffect entry = i.next(); + if (entry.getDuration() == Duration.EndOfTurn) + i.remove(); + } + for (Iterator i = replacementEffects.keySet().iterator(); i.hasNext();) { + ContinuousEffect entry = i.next(); + if (entry.getDuration() == Duration.EndOfTurn) + i.remove(); + } + for (Iterator i = preventionEffects.keySet().iterator(); i.hasNext();) { + ContinuousEffect entry = i.next(); + if (entry.getDuration() == Duration.EndOfTurn) + i.remove(); + } + for (Iterator i = asThoughEffects.keySet().iterator(); i.hasNext();) { ContinuousEffect entry = i.next(); if (entry.getDuration() == Duration.EndOfTurn) i.remove(); @@ -81,81 +108,92 @@ public class ContinuousEffects implements Serializable { } public void removeInactiveEffects(Game game) { - for (Iterator i = effects.keySet().iterator(); i.hasNext();) { + for (Iterator i = layeredEffects.keySet().iterator(); i.hasNext();) { ContinuousEffect entry = i.next(); if (entry.getDuration() == Duration.WhileOnBattlefield) { - Permanent permanent = game.getPermanent(effects.get(entry).getSourceId()); + Permanent permanent = game.getPermanent(layeredEffects.get(entry).getSourceId()); if (permanent == null || !permanent.isPhasedIn()) i.remove(); } - if (entry.getDuration() == Duration.OneUse) { - if (entry instanceof ReplacementEffect) { - if (((ReplacementEffect)entry).isUsed()) - i.remove(); - } + else if (entry.getDuration() == Duration.OneUse && entry.isUsed()) + i.remove(); + } + for (Iterator i = replacementEffects.keySet().iterator(); i.hasNext();) { + ReplacementEffect entry = i.next(); + if (entry.getDuration() == Duration.WhileOnBattlefield) { + Permanent permanent = game.getPermanent(replacementEffects.get(entry).getSourceId()); + if (permanent == null || !permanent.isPhasedIn()) + i.remove(); } + else if (entry.getDuration() == Duration.OneUse && entry.isUsed()) + i.remove(); + } + for (Iterator i = preventionEffects.keySet().iterator(); i.hasNext();) { + PreventionEffect entry = i.next(); + if (entry.getDuration() == Duration.WhileOnBattlefield) { + Permanent permanent = game.getPermanent(preventionEffects.get(entry).getSourceId()); + if (permanent == null || !permanent.isPhasedIn()) + i.remove(); + } + else if (entry.getDuration() == Duration.OneUse && entry.isUsed()) + i.remove(); + } + for (Iterator i = asThoughEffects.keySet().iterator(); i.hasNext();) { + AsThoughEffect entry = i.next(); + if (entry.getDuration() == Duration.WhileOnBattlefield) { + Permanent permanent = game.getPermanent(asThoughEffects.get(entry).getSourceId()); + if (permanent == null || !permanent.isPhasedIn()) + i.remove(); + } + else if (entry.getDuration() == Duration.OneUse && entry.isUsed()) + i.remove(); } } private List getLayeredEffects() { - List layerEffects = new ArrayList(); - for (ContinuousEffect effect: effects.keySet()) { - if (!(effect instanceof ReplacementEffect) && !(effect instanceof PreventionEffect)) { - layerEffects.add(effect); - } - } + List layerEffects = new ArrayList(layeredEffects.keySet()); Collections.sort(layerEffects, new TimestampSorter()); return layerEffects; } - private List getApplicableReplacementEffects(GameEvent event, Game game) { - List replacementEffects = new ArrayList(); - for (ContinuousEffect effect: effects.keySet()) { - if (effect instanceof ReplacementEffect && ((ReplacementEffect)effect).applies(event, effects.get(effect), game)) { - if (effect.getDuration() != Duration.OneUse || !((ReplacementEffect)effect).isUsed()) - replacementEffects.add((ReplacementEffect)effect); + List replaceEffects = new ArrayList(); + for (ReplacementEffect effect: replacementEffects.keySet()) { + if (effect.applies(event, replacementEffects.get(effect), game)) { + if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) + replaceEffects.add((ReplacementEffect)effect); } } - return replacementEffects; + return replaceEffects; } -// private List GetApplicableSelfReplacementEffects(GameEvent event, Game game) { -// List effects = new ArrayList(); -// for (IEffect effect: this) { -// if (effect instanceof SelfReplacementEffect && ((SelfReplacementEffect)effect).Applies(event, game)) { -// effects.add((SelfReplacementEffect)effect); -// } -// } -// return effects; -// } + public boolean asThough(UUID objectId, AsThoughEffectType type, Game game) { + for (Entry entry: asThoughEffects.entrySet()) { + AsThoughEffect effect = entry.getKey(); + if (effect.getAsThoughEffectType() == type) { + if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) { + if (effect.applies(objectId, entry.getValue(), game)) { + return true; + } + } + } + } + return false; + } public boolean replaceEvent(GameEvent event, Game game) { boolean caught = false; -// List srEffects = GetApplicableSelfReplacementEffects(event, game); -// -// if (srEffects.size() > 0) { -// if (srEffects.size() == 1) { -// caught = srEffects.get(0).ReplaceEvent(event, game); -// } -// else { -// //TODO: handle multiple -// } -// } - - if (!caught) { - List rEffects = getApplicableReplacementEffects(event, game); - if (rEffects.size() > 0) { - int index; - if (rEffects.size() == 1) { - index = 0; - } - else { - Player player = game.getPlayer(event.getPlayerId()); - index = player.chooseEffect(rEffects, game); - } - caught = rEffects.get(index).replaceEvent(event, effects.get(rEffects.get(index)), game); + List rEffects = getApplicableReplacementEffects(event, game); + if (rEffects.size() > 0) { + int index; + if (rEffects.size() == 1) { + index = 0; } + else { + Player player = game.getPlayer(event.getPlayerId()); + index = player.chooseEffect(rEffects, game); + } + caught = rEffects.get(index).replaceEvent(event, replacementEffects.get(rEffects.get(index)), game); } return caught; @@ -164,96 +202,75 @@ public class ContinuousEffects implements Serializable { //20091005 - 613 public void apply(Game game) { removeInactiveEffects(game); - List layeredEffects = getLayeredEffects(); - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, effects.get(effect), game); + List layerEffects = getLayeredEffects(); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.CopyEffects_1, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.CopyEffects_1, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.CopyEffects_1, SubLayer.NA, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.ControlChangingEffects_2, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.TextChangingEffects_3, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.TypeChangingEffects_4, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.ColorChangingEffects_5, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.PTChangingEffects_7, SubLayer.CharacteristicDefining_7a, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, layeredEffects.get(effect), game); } applyCounters.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, null, game); -// for (ContinuousEffect effect: layeredEffects) { -// effect.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, game); -// } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.PlayerEffects, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.PlayerEffects, SubLayer.NA, layeredEffects.get(effect), game); } - for (ContinuousEffect effect: layeredEffects) { - effect.apply(Layer.RulesEffects, SubLayer.NA, effects.get(effect), game); + for (ContinuousEffect effect: layerEffects) { + effect.apply(Layer.RulesEffects, SubLayer.NA, layeredEffects.get(effect), game); } } -// protected void applyCounters(Game game) { -// for (Permanent permanent: game.getBattlefield().getAllActivePermanents(CardType.CREATURE)) { -// for (BoostCounter counter: permanent.getCounters().getBoostCounters()) { -// permanent.addPower(counter.getPower() * counter.getCount()); -// permanent.addToughness(counter.getToughness() * counter.getCount()); -// } -// } -// } - -// public String getText() { -// StringBuilder sbText = new StringBuilder(); -// for (ActiveContinuousEffect effect: effects) { -// sbText.append(effect.getEffect().getText()).append(" "); -// } -// return sbText.toString(); -// } - public void addEffect(ContinuousEffect effect, Ability source) { - effects.put(effect, source); + if (effect instanceof ReplacementEffect) + replacementEffects.put((ReplacementEffect)effect, source); + else if (effect instanceof PreventionEffect) + preventionEffects.put((PreventionEffect)effect, source); + else if (effect instanceof AsThoughEffect) + asThoughEffects.put((AsThoughEffect) effect,source); + else + layeredEffects.put(effect, source); } -// public boolean effectExists(UUID abilityId) { -// for (ContinuousEffect effect: effects) { -// if (effect.getSource().getId().equals(abilityId)) -// return true; -// } -// return false; -// } - } class TimestampSorter implements Comparator { diff --git a/Mage/src/mage/abilities/effects/PreventionEffectImpl.java b/Mage/src/mage/abilities/effects/PreventionEffectImpl.java index 29277315286..b051337e65d 100644 --- a/Mage/src/mage/abilities/effects/PreventionEffectImpl.java +++ b/Mage/src/mage/abilities/effects/PreventionEffectImpl.java @@ -61,5 +61,4 @@ public abstract class PreventionEffectImpl> ex } } - } diff --git a/Mage/src/mage/abilities/effects/ReplacementEffect.java b/Mage/src/mage/abilities/effects/ReplacementEffect.java index 41cffdcad12..b22e2608df3 100644 --- a/Mage/src/mage/abilities/effects/ReplacementEffect.java +++ b/Mage/src/mage/abilities/effects/ReplacementEffect.java @@ -40,6 +40,5 @@ public interface ReplacementEffect> extends Conti public boolean replaceEvent(GameEvent event, Ability source, Game game); public boolean applies(GameEvent event, Ability source, Game game); - boolean isUsed(); } diff --git a/Mage/src/mage/abilities/effects/ReplacementEffectImpl.java b/Mage/src/mage/abilities/effects/ReplacementEffectImpl.java index e8140c495d5..fcb5512f999 100644 --- a/Mage/src/mage/abilities/effects/ReplacementEffectImpl.java +++ b/Mage/src/mage/abilities/effects/ReplacementEffectImpl.java @@ -37,20 +37,12 @@ import mage.Constants.Outcome; */ public abstract class ReplacementEffectImpl> extends ContinuousEffectImpl implements ReplacementEffect { - protected boolean used = false; - public ReplacementEffectImpl(Duration duration, Outcome outcome) { super(duration, outcome); } public ReplacementEffectImpl(final ReplacementEffectImpl effect) { super(effect); - this.used = effect.used; - } - - @Override - public boolean isUsed() { - return used; } } diff --git a/Mage/src/mage/abilities/effects/common/CantTargetControlledEffect.java b/Mage/src/mage/abilities/effects/common/CantTargetControlledEffect.java index a042c0396af..0bc9deed86a 100644 --- a/Mage/src/mage/abilities/effects/common/CantTargetControlledEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantTargetControlledEffect.java @@ -30,15 +30,18 @@ package mage.abilities.effects.common; import mage.Constants.Duration; import mage.Constants.Outcome; +import mage.Constants.TargetController; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.ReplacementEffectImpl; import mage.filter.FilterObject; import mage.filter.FilterPermanent; +import mage.filter.FilterStackObject; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; +import mage.game.stack.StackObject; /** * @@ -47,9 +50,9 @@ import mage.game.permanent.Permanent; public class CantTargetControlledEffect extends ReplacementEffectImpl { private FilterPermanent filterTarget; - private FilterObject filterSource; + private FilterStackObject filterSource; - public CantTargetControlledEffect(FilterPermanent filterTarget, FilterObject filterSource, Duration duration) { + public CantTargetControlledEffect(FilterPermanent filterTarget, FilterStackObject filterSource, Duration duration) { super(duration, Outcome.Benefit); this.filterTarget = filterTarget; this.filterSource = filterSource; @@ -83,14 +86,15 @@ public class CantTargetControlledEffect extends ReplacementEffectImpl { + + private FilterObject filterSource; + + public CantTargetControllerEffect(FilterObject filterSource, Duration duration) { + super(duration, Outcome.Benefit); + this.filterSource = filterSource; + } + + public CantTargetControllerEffect(final CantTargetControllerEffect effect) { + super(effect); + this.filterSource = effect.filterSource.copy(); + } + + @Override + public CantTargetControllerEffect copy() { + return new CantTargetControllerEffect(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.TARGET && event.getTargetId().equals(source.getControllerId())) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null && filterSource.match(sourceObject)) { + return true; + } + } + return false; + } + + @Override + public String getText(Ability source) { + StringBuilder sb = new StringBuilder(); + sb.append("{this} can't be the targets of "); + sb.append(filterSource.getMessage()); + sb.append(" ").append(duration.toString()); + return sb.toString(); + } + +} diff --git a/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java b/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java index 59ba2799b40..65052c7b440 100644 --- a/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java +++ b/Mage/src/mage/abilities/effects/common/CounterUnlessPaysEffect.java @@ -76,7 +76,7 @@ public class CounterUnlessPaysEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); for (int i = 0; i < amount; i++) { - controller.putOntoBattlefield(token, game); + token.putOntoBattlefield(game, source.getControllerId()); } return true; } diff --git a/Mage/src/mage/abilities/effects/common/DamageAllEffect.java b/Mage/src/mage/abilities/effects/common/DamageAllEffect.java index b1e9d4bf585..748cb6b9413 100644 --- a/Mage/src/mage/abilities/effects/common/DamageAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/DamageAllEffect.java @@ -63,7 +63,7 @@ public class DamageAllEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter)) { + for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { permanent.damage(amount, source.getSourceId(), game, true); } return true; diff --git a/Mage/src/mage/abilities/effects/common/DamageControllerEffect.java b/Mage/src/mage/abilities/effects/common/DamageControllerEffect.java index 10901bca925..b29bd232b69 100644 --- a/Mage/src/mage/abilities/effects/common/DamageControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/DamageControllerEffect.java @@ -82,7 +82,6 @@ public class DamageControllerEffect extends OneShotEffect { + + private int amount; + + public DamageEverythingEffect(int amount) { + super(Outcome.Damage); + this.amount = amount; + } + + public DamageEverythingEffect(final DamageEverythingEffect effect) { + super(effect); + this.amount = effect.amount; + } + + @Override + public DamageEverythingEffect copy() { + return new DamageEverythingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent: game.getBattlefield().getActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { + permanent.damage(amount, source.getId(), game, true); + } + for (UUID playerId: game.getPlayer(source.getControllerId()).getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) + player.damage(amount, source.getId(), game, false, true); + } + return true; + } + + @Override + public String getText(Ability source) { + return "{source} deals " + Integer.toString(amount) + " damage to each creature and each player"; + } + +} diff --git a/Mage/src/mage/abilities/effects/common/DrawCardAllEffect.java b/Mage/src/mage/abilities/effects/common/DrawCardAllEffect.java index a0c20527cd5..c5c22362848 100644 --- a/Mage/src/mage/abilities/effects/common/DrawCardAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/DrawCardAllEffect.java @@ -28,6 +28,7 @@ package mage.abilities.effects.common; +import java.util.UUID; import mage.Constants.Outcome; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; @@ -60,8 +61,11 @@ public class DrawCardAllEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (Player player: game.getPlayers().values()) { - player.drawCards(amount, game); + Player sourcePlayer = game.getPlayer(source.getControllerId()); + for (UUID playerId: sourcePlayer.getInRange()) { + Player player = game.getPlayer(playerId); + if (player != null) + player.drawCards(amount, game); } return true; } diff --git a/Mage/src/mage/abilities/effects/common/PreventAllCombatDamageEffect.java b/Mage/src/mage/abilities/effects/common/PreventAllCombatDamageEffect.java index 00038e5fa5c..62b7168272d 100644 --- a/Mage/src/mage/abilities/effects/common/PreventAllCombatDamageEffect.java +++ b/Mage/src/mage/abilities/effects/common/PreventAllCombatDamageEffect.java @@ -61,7 +61,12 @@ public class PreventAllCombatDamageEffect extends PreventionEffectImpl= this.amount) { - event.setAmount(event.getAmount() - amount); - this.used = true; - } else { - int damage = event.getAmount(); - event.setAmount(0); - amount -= damage; + GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), event.getAmount()); + if (!game.replaceEvent(preventEvent)) { + if (event.getAmount() >= this.amount) { + int damage = event.getAmount(); + event.setAmount(event.getAmount() - amount); + this.used = true; + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage)); + } else { + int damage = event.getAmount(); + event.setAmount(0); + amount -= damage; + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE, source.getFirstTarget(), source.getId(), source.getControllerId(), damage)); + } } return false; } diff --git a/Mage/src/mage/abilities/effects/common/PutOnLibraryTargetEffect.java b/Mage/src/mage/abilities/effects/common/PutOnLibraryTargetEffect.java index 9042e3b8332..46f0de402b2 100644 --- a/Mage/src/mage/abilities/effects/common/PutOnLibraryTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/PutOnLibraryTargetEffect.java @@ -73,11 +73,12 @@ public class PutOnLibraryTargetEffect extends OneShotEffect Player player; for (UUID cardId: game.getExile().getExileZone(exileId)) { Card card = game.getCard(cardId); - player = game.getPlayer(card.getOwnerId()); - switch(zone) { - case BATTLEFIELD: - player.putOntoBattlefield(card, game); - break; - case HAND: - player.putInHand(card, game); - break; - case GRAVEYARD: - player.putInGraveyard(card, game, false); - break; - } + card.moveToZone(zone, game, false); } game.getExile().getExileZone(exileId).clear(); return true; diff --git a/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java index 5096cc41c94..6ec6a3e3c83 100644 --- a/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java +++ b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToBattlefieldEffect.java @@ -29,6 +29,7 @@ package mage.abilities.effects.common; import mage.Constants.Outcome; +import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -59,8 +60,8 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect< Player player = game.getPlayer(source.getControllerId()); Card card = player.getGraveyard().get(source.getSourceId(), game); if (card != null) { - player.putOntoBattlefield(card, game); player.removeFromGraveyard(card, game); + card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId()); return true; } return false; @@ -71,5 +72,4 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect< return "Return {this} from your graveyard to the battlefield"; } - } diff --git a/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java new file mode 100644 index 00000000000..6a9791612db --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/ReturnSourceFromGraveyardToHandEffect.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.effects.common; + +import mage.Constants.Outcome; +import mage.Constants.Zone; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class ReturnSourceFromGraveyardToHandEffect extends OneShotEffect { + + public ReturnSourceFromGraveyardToHandEffect() { + super(Outcome.PutCreatureInPlay); + } + + public ReturnSourceFromGraveyardToHandEffect(final ReturnSourceFromGraveyardToHandEffect effect) { + super(effect); + } + + @Override + public ReturnSourceFromGraveyardToHandEffect copy() { + return new ReturnSourceFromGraveyardToHandEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + Card card = player.getGraveyard().get(source.getSourceId(), game); + if (card != null) { + player.removeFromGraveyard(card, game); + card.moveToZone(Zone.HAND, game, false); + return true; + } + return false; + } + + @Override + public String getText(Ability source) { + return "Return {this} from your graveyard to your hand"; + } + +} diff --git a/Mage/src/mage/abilities/effects/common/SacrificeAllEffect.java b/Mage/src/mage/abilities/effects/common/SacrificeAllEffect.java index 17ac50039a3..3ce3a8fb6ca 100644 --- a/Mage/src/mage/abilities/effects/common/SacrificeAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/SacrificeAllEffect.java @@ -76,7 +76,8 @@ public class SacrificeAllEffect extends OneShotEffect { List perms = new ArrayList(); for (Player player: game.getPlayers().values()) { int numTargets = Math.min(amount, game.getBattlefield().countAll(filter, player.getId())); - TargetPermanent target = new TargetPermanent(numTargets, filter, TargetController.YOU); + filter.setTargetController(TargetController.YOU); + TargetPermanent target = new TargetPermanent(numTargets, filter); while (!target.isChosen()) { player.choose(Outcome.Sacrifice, target, game); } diff --git a/Mage/src/mage/abilities/effects/common/ScryEffect.java b/Mage/src/mage/abilities/effects/common/ScryEffect.java index 4d88282b048..ff64df7cab2 100644 --- a/Mage/src/mage/abilities/effects/common/ScryEffect.java +++ b/Mage/src/mage/abilities/effects/common/ScryEffect.java @@ -72,7 +72,8 @@ public class ScryEffect extends OneShotEffect { while (cards.size() > 0 && player.chooseTarget(cards, target1, source, game)) { Card card = cards.get(target1.getFirstTarget(), game); cards.remove(card); - player.getLibrary().putOnBottom(card, game); + card.moveToZone(Zone.LIBRARY, game, false); +// player.getLibrary().putOnBottom(card, game); target1.clearChosen(); } if (cards.size() > 1) { @@ -82,12 +83,16 @@ public class ScryEffect extends OneShotEffect { player.chooseTarget(cards, target2, source, game); Card card = cards.get(target2.getFirstTarget(), game); cards.remove(card); - player.getLibrary().putOnTop(card, game); + card.moveToZone(Zone.LIBRARY, game, true); +// player.getLibrary().putOnTop(card, game); target2.clearChosen(); } } - if (cards.size() == 1) - player.getLibrary().putOnTop(cards.get(cards.iterator().next(), game), game); + if (cards.size() == 1) { + Card card = cards.get(cards.iterator().next(), game); + card.moveToZone(Zone.LIBRARY, game, true); +// player.getLibrary().putOnTop(cards.get(cards.iterator().next(), game), game); + } return true; } diff --git a/Mage/src/mage/abilities/effects/common/SearchLibraryPutInHandEffect.java b/Mage/src/mage/abilities/effects/common/SearchLibraryPutInHandEffect.java index 8f5a69c76a7..d89c7aec0b8 100644 --- a/Mage/src/mage/abilities/effects/common/SearchLibraryPutInHandEffect.java +++ b/Mage/src/mage/abilities/effects/common/SearchLibraryPutInHandEffect.java @@ -31,6 +31,7 @@ package mage.abilities.effects.common; import java.util.List; import java.util.UUID; import mage.Constants.Outcome; +import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.SearchEffect; import mage.cards.Card; @@ -65,7 +66,7 @@ public class SearchLibraryPutInHandEffect extends SearchEffect)target.getTargets()) { Card card = player.getLibrary().remove(cardId, game); if (card != null){ - player.putInHand(card, game); + card.moveToZone(Zone.HAND, game, false); } } player.shuffleLibrary(game); @@ -89,9 +90,4 @@ public class SearchLibraryPutInHandEffect extends SearchEffect)target.getTargets()) { Card card = player.getLibrary().remove(cardId, game); if (card != null) { - if (player.putOntoBattlefield(card, game)) { + if (card.putOntoBattlefield(game, Zone.HAND, source.getControllerId())) { if (tapped) { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) @@ -111,10 +112,4 @@ public class SearchLibraryPutInPlayEffect extends SearchEffect { + + public SearchLibraryPutOnLibraryEffect(TargetCardInLibrary target) { + super(target, Outcome.DrawCard); + } + + public SearchLibraryPutOnLibraryEffect(final SearchLibraryPutOnLibraryEffect effect) { + super(effect); + } + + @Override + public SearchLibraryPutOnLibraryEffect copy() { + return new SearchLibraryPutOnLibraryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + player.searchLibrary(target, game); + if (target.getTargets().size() > 0) { + for (UUID cardId: (List)target.getTargets()) { + Card card = player.getLibrary().remove(cardId, game); + if (card != null){ + card.moveToZone(Zone.LIBRARY, game, true); + } + } + player.shuffleLibrary(game); + } + return true; + } + + @Override + public String getText(Ability source) { + StringBuilder sb = new StringBuilder(); + sb.append("Search your library for a ").append(target.getTargetName()).append(", then shuffle your library and put that card on top of it"); + return sb.toString(); + } + +} diff --git a/Mage/src/mage/abilities/effects/common/SearchLibraryRevealPutInHandEffect.java b/Mage/src/mage/abilities/effects/common/SearchLibraryRevealPutInHandEffect.java index 4f939e313f9..db3f112ea71 100644 --- a/Mage/src/mage/abilities/effects/common/SearchLibraryRevealPutInHandEffect.java +++ b/Mage/src/mage/abilities/effects/common/SearchLibraryRevealPutInHandEffect.java @@ -69,7 +69,7 @@ public class SearchLibraryRevealPutInHandEffect extends SearchEffect)target.getTargets()) { Card card = player.getLibrary().remove(cardId, game); if (card != null) { - player.putInHand(card, game); + card.moveToZone(Zone.HAND, game, false); revealed.add(card); } } diff --git a/Mage/src/mage/abilities/keyword/CascadeAbility.java b/Mage/src/mage/abilities/keyword/CascadeAbility.java index 1491253e2d5..a2bf987690d 100644 --- a/Mage/src/mage/abilities/keyword/CascadeAbility.java +++ b/Mage/src/mage/abilities/keyword/CascadeAbility.java @@ -96,7 +96,8 @@ class CascadeEffect extends OneShotEffect { card = player.getLibrary().removeFromTop(game); if (card == null) break; - exile.add(card); + card.moveToExile(exile.getId(), exile.getName(), game); +// exile.add(card); } while (card.getCardType().contains(CardType.LAND) || card.getManaCost().convertedManaCost() >= sourceCost); if (card != null) { @@ -109,7 +110,8 @@ class CascadeEffect extends OneShotEffect { while (exile.size() > 0) { card = exile.getRandom(game); exile.remove(card.getId()); - player.getLibrary().putOnBottom(card, game); + card.moveToZone(Zone.LIBRARY, game, false); +// player.getLibrary().putOnBottom(card, game); } return true; diff --git a/Mage/src/mage/abilities/keyword/EquipAbility.java b/Mage/src/mage/abilities/keyword/EquipAbility.java index 1c29da61e1a..594cf3cc0f6 100644 --- a/Mage/src/mage/abilities/keyword/EquipAbility.java +++ b/Mage/src/mage/abilities/keyword/EquipAbility.java @@ -35,6 +35,7 @@ import mage.Constants.Zone; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.Cost; import mage.abilities.effects.common.AttachEffect; +import mage.filter.common.FilterCreaturePermanent; import mage.target.common.TargetCreaturePermanent; /** @@ -43,9 +44,15 @@ import mage.target.common.TargetCreaturePermanent; */ public class EquipAbility extends ActivatedAbilityImpl { + private static FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control"); + + static { + filter.setTargetController(TargetController.YOU); + } + public EquipAbility(Outcome outcome, Cost cost) { super(Zone.BATTLEFIELD, new AttachEffect(outcome), cost); - this.addTarget(new TargetCreaturePermanent(1, TargetController.YOU)); + this.addTarget(new TargetCreaturePermanent(filter)); this.timing = TimingRule.SORCERY; } diff --git a/Mage/src/mage/abilities/keyword/FortifyAbility.java b/Mage/src/mage/abilities/keyword/FortifyAbility.java index 792cbc845ac..56601084be2 100644 --- a/Mage/src/mage/abilities/keyword/FortifyAbility.java +++ b/Mage/src/mage/abilities/keyword/FortifyAbility.java @@ -34,18 +34,26 @@ import mage.Constants.Zone; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.costs.Cost; import mage.abilities.effects.common.AttachEffect; +import mage.filter.common.FilterLandPermanent; import mage.target.common.TargetLandPermanent; /** * * @author BetaSteward_at_googlemail.com */ + +//20091005 - 702.64 public class FortifyAbility extends ActivatedAbilityImpl { - //20091005 - 702.64 + + private static FilterLandPermanent filter = new FilterLandPermanent("land you control"); + + static { + filter.setTargetController(TargetController.YOU); + } public FortifyAbility(Zone zone, AttachEffect effect, Cost cost) { super(zone, effect, cost); - this.addTarget(new TargetLandPermanent(1, TargetController.YOU)); + this.addTarget(new TargetLandPermanent(filter)); timing = TimingRule.SORCERY; } diff --git a/Mage/src/mage/abilities/keyword/LeylineAbility.java b/Mage/src/mage/abilities/keyword/LeylineAbility.java new file mode 100644 index 00000000000..c17bf1a53e2 --- /dev/null +++ b/Mage/src/mage/abilities/keyword/LeylineAbility.java @@ -0,0 +1,65 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.keyword; + +import java.io.ObjectStreamException; +import mage.Constants.Zone; +import mage.abilities.StaticAbility; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class LeylineAbility extends StaticAbility{ + + private static final LeylineAbility fINSTANCE = new LeylineAbility(); + + private Object readResolve() throws ObjectStreamException { + return fINSTANCE; + } + + public static LeylineAbility getInstance() { + return fINSTANCE; + } + + private LeylineAbility() { + super(Zone.HAND, null); + } + + @Override + public String getRule() { + return "If {this} is in your opening hand, you may begin the game with it on the battlefield."; + } + + @Override + public LeylineAbility copy() { + return fINSTANCE; + } + +} diff --git a/Mage/src/mage/cards/Card.java b/Mage/src/mage/cards/Card.java index 4accf4187eb..7d832da62c9 100644 --- a/Mage/src/mage/cards/Card.java +++ b/Mage/src/mage/cards/Card.java @@ -54,6 +54,9 @@ public interface Card extends MageObject { public String getExpansionSetCode(); public void setExpansionSetCode(String expansionSetCode); + public boolean moveToZone(Zone zone, Game game, boolean flag); + public boolean moveToExile(UUID exileId, String name, Game game); + public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId); public void checkTriggers(Zone zone, GameEvent event, Game game); @Override diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index f03acc362ad..d76fd145882 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -41,6 +41,8 @@ import mage.abilities.SpellAbility; import mage.abilities.TriggeredAbility; import mage.game.Game; import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.PermanentCard; import mage.watchers.Watchers; public abstract class CardImpl> extends MageObjectImpl implements Card { @@ -166,4 +168,61 @@ public abstract class CardImpl> extends MageObjectImpl public void setExpansionSetCode(String expansionSetCode) { this.expansionSetCode = expansionSetCode; } + + @Override + public boolean moveToZone(Zone toZone, Game game, boolean flag) { + Zone fromZone = zone; + ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), ownerId, fromZone, toZone); + if (!game.replaceEvent(event)) { + switch (event.getToZone()) { + case GRAVEYARD: + game.getPlayer(ownerId).putInGraveyard(this, game, !flag); + break; + case HAND: + game.getPlayer(ownerId).getHand().add(this); + break; + case EXILED: + game.getExile().getPermanentExile().add(this); + break; + case LIBRARY: + if (flag) + game.getPlayer(ownerId).getLibrary().putOnTop(this, game); + else + game.getPlayer(ownerId).getLibrary().putOnBottom(this, game); + + } + zone = event.getToZone(); + game.fireEvent(new ZoneChangeEvent(this.getId(), ownerId, fromZone, event.getToZone())); + return zone == toZone; + } + return false; + } + + @Override + public boolean moveToExile(UUID exileId, String name, Game game) { + Zone fromZone = zone; + ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), ownerId, fromZone, Zone.EXILED); + if (!game.replaceEvent(event)) { + if (exileId == null) { + game.getExile().getPermanentExile().add(this); + } + else { + game.getExile().createZone(exileId, name).add(this); + } + game.fireEvent(new ZoneChangeEvent(this.getId(), ownerId, fromZone, Zone.EXILED)); + return true; + } + return false; + } + + @Override + public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId) { + PermanentCard permanent = new PermanentCard(this, controllerId); + game.getBattlefield().addPermanent(permanent); + permanent.entersBattlefield(game); + game.applyEffects(); + game.fireEvent(new ZoneChangeEvent(permanent.getId(), controllerId, fromZone, Zone.BATTLEFIELD)); + return true; + } + } diff --git a/Mage/src/mage/filter/Filter.java b/Mage/src/mage/filter/Filter.java index c3e866fe207..ec7430e7550 100644 --- a/Mage/src/mage/filter/Filter.java +++ b/Mage/src/mage/filter/Filter.java @@ -29,6 +29,7 @@ package mage.filter; import java.io.Serializable; +import java.util.UUID; /** * diff --git a/Mage/src/mage/filter/FilterPermanent.java b/Mage/src/mage/filter/FilterPermanent.java index dd311e371f9..042b8c9b46d 100644 --- a/Mage/src/mage/filter/FilterPermanent.java +++ b/Mage/src/mage/filter/FilterPermanent.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.game.permanent.Permanent; /** @@ -50,12 +52,13 @@ public class FilterPermanent> extends FilterObject< protected boolean faceup; protected boolean usePhased; protected boolean phasedIn; + protected TargetController controller = TargetController.ANY; public FilterPermanent() { super("permanent"); } - public FilterPermanent(FilterPermanent filter) { + public FilterPermanent(final FilterPermanent filter) { super(filter); for (UUID oId: filter.ownerId) { this.ownerId.add(oId); @@ -73,6 +76,7 @@ public class FilterPermanent> extends FilterObject< this.faceup = filter.faceup; this.usePhased = filter.usePhased; this.phasedIn = filter.phasedIn; + this.controller = filter.controller; } public FilterPermanent(String name) { @@ -105,6 +109,30 @@ public class FilterPermanent> extends FilterObject< return !notFilter; } + public boolean match(Permanent permanent, UUID playerId, Game game) { + if (!this.match(permanent)) + return notFilter; + + if (controller != TargetController.ANY && playerId != null) { + switch(controller) { + case YOU: + if (!permanent.getControllerId().equals(playerId)) + return notFilter; + break; + case OPPONENT: + if (!game.getOpponents(playerId).contains(permanent.getControllerId())) + return notFilter; + break; + case NOT_YOU: + if (permanent.getControllerId().equals(playerId)) + return notFilter; + break; + } + } + + return !notFilter; + } + public List getOwnerId() { return ownerId; } @@ -145,6 +173,30 @@ public class FilterPermanent> extends FilterObject< this.faceup = faceup; } + public void setTargetController(TargetController controller) { + this.controller = controller; + } + +// public void setController(UUID playerId, Game game) { +// controllerId.clear(); +// switch (controller) { +// case ANY: +// break; +// case YOU: +// controllerId.add(playerId); +// notController = false; +// break; +// case NOT_YOU: +// controllerId.add(playerId); +// notController = true; +// break; +// case OPPONENT: +// controllerId.addAll(game.getOpponents(playerId)); +// notController = false; +// break; +// } +// } + public boolean matchOwner(UUID testOwnerId) { if (ownerId.size() > 0 && ownerId.contains(testOwnerId) == notOwner) return false; diff --git a/Mage/src/mage/filter/FilterSpell.java b/Mage/src/mage/filter/FilterSpell.java index 42e6cc01f10..2068fdf2c0b 100644 --- a/Mage/src/mage/filter/FilterSpell.java +++ b/Mage/src/mage/filter/FilterSpell.java @@ -28,19 +28,15 @@ package mage.filter; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; import mage.game.stack.Spell; +import mage.game.stack.StackObject; /** * * @author BetaSteward_at_googlemail.com */ -public class FilterSpell extends FilterObject { - - protected List controllerId = new ArrayList(); - protected boolean notController = false; +public class FilterSpell extends FilterStackObject { public FilterSpell() { super("spell"); @@ -56,26 +52,15 @@ public class FilterSpell extends FilterObject { this.controllerId.add(cId); } this.notController = filter.notController; + this.controller = filter.controller; } @Override - public boolean match(Spell spell) { - - if (!super.match(spell)) + public boolean match(StackObject spell) { + if (!(spell instanceof Spell)) return notFilter; - if (controllerId.size() > 0 && controllerId.contains(spell.getControllerId()) == notController) - return notFilter; - - return !notFilter; - } - - public List getControllerId() { - return controllerId; - } - - public void setNotController(boolean notController) { - this.notController = notController; + return super.match(spell); } @Override diff --git a/Mage/src/mage/filter/FilterStackObject.java b/Mage/src/mage/filter/FilterStackObject.java index 310f7199f3c..117a6a2c87c 100644 --- a/Mage/src/mage/filter/FilterStackObject.java +++ b/Mage/src/mage/filter/FilterStackObject.java @@ -31,16 +31,19 @@ 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.game.stack.StackObject; /** * * @author BetaSteward_at_googlemail.com */ -public class FilterStackObject extends FilterObject { +public class FilterStackObject> extends FilterObject> { protected List controllerId = new ArrayList(); protected boolean notController = false; + protected TargetController controller = TargetController.ANY; public FilterStackObject() { super("spell or ability"); @@ -50,12 +53,13 @@ public class FilterStackObject extends FilterObject filter) { super(filter); for (UUID cId: filter.controllerId) { this.controllerId.add(cId); } this.notController = filter.notController; + this.controller = filter.controller; } @Override @@ -70,6 +74,30 @@ public class FilterStackObject extends FilterObject getControllerId() { return controllerId; } @@ -78,6 +106,10 @@ public class FilterStackObject extends FilterObject { + + public FilterControlledCreaturePermanent() { + this("creature you control"); + } + + public FilterControlledCreaturePermanent(String name) { + super(name); + cardType.add(CardType.CREATURE); + } + + public FilterControlledCreaturePermanent(final FilterControlledCreaturePermanent filter) { + super(filter); + } + + @Override + public FilterControlledCreaturePermanent copy() { + return new FilterControlledCreaturePermanent(this); + } + +} diff --git a/Mage/src/mage/filter/common/FilterControlledPermanent.java b/Mage/src/mage/filter/common/FilterControlledPermanent.java new file mode 100644 index 00000000000..7b58e98714a --- /dev/null +++ b/Mage/src/mage/filter/common/FilterControlledPermanent.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.filter.common; + +import mage.Constants.TargetController; +import mage.filter.FilterPermanent; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class FilterControlledPermanent> extends FilterPermanent> { + + public FilterControlledPermanent() { + this("permanent you control"); + } + + public FilterControlledPermanent(String name) { + super(name); + this.controller = TargetController.YOU; + } + + public FilterControlledPermanent(final FilterControlledPermanent filter) { + super(filter); + } + + @Override + public FilterControlledPermanent copy() { + return new FilterControlledPermanent(this); + } + +} diff --git a/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java b/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java index bcde639ae61..d192e7d4b85 100644 --- a/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java +++ b/Mage/src/mage/filter/common/FilterCreatureOrPlayer.java @@ -32,6 +32,7 @@ import java.util.UUID; import mage.filter.Filter; import mage.filter.FilterImpl; import mage.filter.FilterPlayer; +import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -77,6 +78,17 @@ public class FilterCreatureOrPlayer extends FilterImpl> implements Game, Serializa saveState(); } + //20100716 - 103.5 + for (UUID playerId: state.getPlayerList(startingPlayerId)) { + Player player = getPlayer(playerId); + for (Card card: player.getHand().getCards(this)) { + if (card.getAbilities().containsKey(LeylineAbility.getInstance().getId())) { + if (!player.chooseUse(Outcome.PutCardInPlay, "Do you wish to put " + card.getName() + " on the battlefield?", this)) { + player.getHand().remove(card); + card.putOntoBattlefield(this, Zone.HAND, player.getId()); + } + } + } + } } protected UUID findWinner() { diff --git a/Mage/src/mage/game/events/GameEvent.java b/Mage/src/mage/game/events/GameEvent.java index 5c661740f1c..5d725717e14 100644 --- a/Mage/src/mage/game/events/GameEvent.java +++ b/Mage/src/mage/game/events/GameEvent.java @@ -44,6 +44,10 @@ public class GameEvent { public enum EventType { + //Game events + BEGINNING, + PREVENT_DAMAGE, PREVENTED_DAMAGE, + //Turn-based events CHANGE_PHASE, PHASE_CHANGED, CHANGE_STEP, STEP_CHANGED, @@ -64,7 +68,6 @@ public class GameEvent { END_PHASE, END_PHASE_PRE, END_PHASE_POST, END_TURN_STEP_PRE, END_TURN_STEP, END_TURN_STEP_POST, CLEANUP_STEP_PRE, CLEANUP_STEP, CLEANUP_STEP_POST, - EMPTY_MANA_POOLS, AT_END_OF_TURN, diff --git a/Mage/src/mage/game/events/ZoneChangeEvent.java b/Mage/src/mage/game/events/ZoneChangeEvent.java index 70b68b7d0d3..1993ba16f43 100644 --- a/Mage/src/mage/game/events/ZoneChangeEvent.java +++ b/Mage/src/mage/game/events/ZoneChangeEvent.java @@ -57,4 +57,8 @@ public class ZoneChangeEvent extends GameEvent { public Zone getToZone() { return toZone; } + + public void setToZone(Zone toZone) { + this.toZone = toZone; + } } diff --git a/Mage/src/mage/game/permanent/Battlefield.java b/Mage/src/mage/game/permanent/Battlefield.java index 27cb747148e..43de0f27567 100644 --- a/Mage/src/mage/game/permanent/Battlefield.java +++ b/Mage/src/mage/game/permanent/Battlefield.java @@ -98,7 +98,7 @@ public class Battlefield implements Serializable { int count = 0; if (game.getRangeOfInfluence() == RangeOfInfluence.ALL) { for (Permanent permanent: field.values()) { - if (filter.match(permanent)) { + if (filter.match(permanent, sourcePlayerId, game)) { count++; } } @@ -106,7 +106,7 @@ public class Battlefield implements Serializable { else { Set range = game.getPlayer(sourcePlayerId).getInRange(); for (Permanent permanent: field.values()) { - if (range.contains(permanent.getControllerId()) && filter.match(permanent)) { + if (range.contains(permanent.getControllerId()) && filter.match(permanent, sourcePlayerId, game)) { count++; } } @@ -257,7 +257,7 @@ public class Battlefield implements Serializable { List active = new ArrayList(); Set range = game.getPlayer(sourcePlayerId).getInRange(); for (Permanent perm: field.values()) { - if (perm.isPhasedIn() && range.contains(perm.getControllerId()) && filter.match(perm)) + if (perm.isPhasedIn() && range.contains(perm.getControllerId()) && filter.match(perm, sourcePlayerId, game)) active.add(perm); } return active; diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java index 5856936deba..f75ec703b55 100644 --- a/Mage/src/mage/game/permanent/PermanentCard.java +++ b/Mage/src/mage/game/permanent/PermanentCard.java @@ -112,27 +112,11 @@ public class PermanentCard extends PermanentImpl { @Override public boolean moveToZone(Zone zone, Game game, boolean flag) { - if (!game.replaceEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone))) { + ZoneChangeEvent event = new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone); + if (!game.replaceEvent(event)) { if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) { - switch (zone) { - case GRAVEYARD: - game.getPlayer(ownerId).putInGraveyard(game.getCard(objectId), game, !flag); - break; - case HAND: - game.getPlayer(ownerId).getHand().add(game.getCard(objectId)); - break; - case EXILED: - game.getExile().getPermanentExile().add(game.getCard(objectId)); - break; - case LIBRARY: - if (flag) - game.getPlayer(ownerId).getLibrary().putOnTop(game.getCard(objectId), game); - else - game.getPlayer(ownerId).getLibrary().putOnBottom(game.getCard(objectId), game); - - } - game.fireEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, zone)); - return true; + Card card = game.getCard(objectId); + return card.moveToZone(event.getToZone(), game, flag); } } return false; @@ -140,17 +124,8 @@ public class PermanentCard extends PermanentImpl { @Override public boolean moveToExile(UUID exileId, String name, Game game) { - if (!game.replaceEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED))) { - if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) { - if (exileId == null) { - game.getExile().getPermanentExile().add(game.getCard(objectId)); - } - else { - game.getExile().createZone(exileId, name).add(game.getCard(objectId)); - } - game.fireEvent(new ZoneChangeEvent(this.getId(), this.getControllerId(), Zone.BATTLEFIELD, Zone.EXILED)); - return true; - } + if (game.getPlayer(controllerId).removeFromBattlefield(this, game)) { + return game.getCard(objectId).moveToExile(exileId, name, game); } return false; } diff --git a/Mage/src/mage/game/permanent/PermanentToken.java b/Mage/src/mage/game/permanent/PermanentToken.java index 4bfe4c40751..222facc7847 100644 --- a/Mage/src/mage/game/permanent/PermanentToken.java +++ b/Mage/src/mage/game/permanent/PermanentToken.java @@ -43,8 +43,8 @@ public class PermanentToken extends PermanentImpl { protected Token token; - public PermanentToken(Token token, UUID ownerId, UUID controllerId) { - super(ownerId, controllerId, token.getName()); + public PermanentToken(Token token, UUID controllerId) { + super(controllerId, controllerId, token.getName()); this.token = token; copyFromToken(token); } @@ -104,6 +104,10 @@ public class PermanentToken extends PermanentImpl { @Override public void setArt(String art) { } + public Token getToken() { + return token; + } + @Override public PermanentToken copy() { return new PermanentToken(this); diff --git a/Mage/src/mage/game/permanent/token/Token.java b/Mage/src/mage/game/permanent/token/Token.java index fd01bd818e1..32d76673158 100644 --- a/Mage/src/mage/game/permanent/token/Token.java +++ b/Mage/src/mage/game/permanent/token/Token.java @@ -29,11 +29,16 @@ package mage.game.permanent.token; import java.util.List; +import java.util.UUID; import mage.Constants.CardType; +import mage.Constants.Zone; import mage.MageObjectImpl; import mage.ObjectColor; import mage.abilities.Abilities; import mage.abilities.Ability; +import mage.game.Game; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.PermanentToken; public class Token extends MageObjectImpl { @@ -74,4 +79,14 @@ public class Token extends MageObjectImpl { public Token copy() { return new Token(this); } + + public boolean putOntoBattlefield(Game game, UUID controllerId) { + PermanentToken permanent = new PermanentToken(this, controllerId); + game.getBattlefield().addPermanent(permanent); + permanent.entersBattlefield(game); + game.applyEffects(); + game.fireEvent(new ZoneChangeEvent(permanent.getId(), controllerId, Zone.OUTSIDE, Zone.BATTLEFIELD)); + return true; + } + } diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 6897e6370ad..1e21803393b 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -44,7 +44,6 @@ import mage.abilities.effects.common.ExileSpellEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.Card; import mage.game.events.GameEvent; -import mage.players.Player; import mage.watchers.Watchers; /** @@ -83,7 +82,8 @@ public class Spell> implements StackObject, Card { if (ability.getEffects().contains(ExileSpellEffect.getInstance())) game.getExile().getPermanentExile().add(card); else - game.getPlayers().get(controllerId).putInGraveyard(card, game, false); + card.moveToZone(Zone.GRAVEYARD, game, false); +// game.getPlayers().get(controllerId).putInGraveyard(card, game, false); return result; } //20091005 - 608.2b @@ -92,8 +92,7 @@ public class Spell> implements StackObject, Card { } else if (card.getCardType().contains(CardType.ENCHANTMENT) && card.getSubtype().contains("Aura")) { if (ability.getTargets().stillLegal(ability, game)) { - Player controller = game.getPlayers().get(controllerId); - if (controller.putOntoBattlefield(card, game)) { + if (card.putOntoBattlefield(game, Zone.HAND, controllerId)) { return ability.resolve(game); } return false; @@ -103,8 +102,7 @@ public class Spell> implements StackObject, Card { return false; } else { - Player controller = game.getPlayers().get(controllerId); - result = controller.putOntoBattlefield(card, game); + result = card.putOntoBattlefield(game, Zone.HAND, controllerId); resolveKicker(game); return result; } @@ -125,7 +123,7 @@ public class Spell> implements StackObject, Card { @Override public void counter(Game game) { - game.getPlayers().get(controllerId).putInGraveyard(card, game, false); + card.moveToZone(Zone.GRAVEYARD, game, false); } @Override @@ -273,4 +271,19 @@ public class Spell> implements StackObject, Card { @Override public void adjustCosts(Ability ability, Game game) {} + + @Override + public boolean moveToZone(Zone zone, Game game, boolean flag) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean moveToExile(UUID exileId, String name, Game game) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean putOntoBattlefield(Game game, Zone fromZone, UUID controllerId) { + throw new UnsupportedOperationException("Not supported yet."); + } } diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java index 14eb34f692a..3d7c7e7a845 100644 --- a/Mage/src/mage/game/stack/StackAbility.java +++ b/Mage/src/mage/game/stack/StackAbility.java @@ -268,4 +268,19 @@ public class StackAbility implements StackObject, Ability { @Override public void adjustCosts(Ability ability, Game game) {} + @Override + public Costs getOptionalCosts() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void addOptionalCost(Cost cost) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean checkIfClause(Game game) { + return true; + } + } diff --git a/Mage/src/mage/players/Player.java b/Mage/src/mage/players/Player.java index 2c357e41eb9..37c0ce72f16 100644 --- a/Mage/src/mage/players/Player.java +++ b/Mage/src/mage/players/Player.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Set; import java.util.UUID; import mage.Constants.Outcome; +import mage.Constants.Zone; import mage.MageItem; import mage.MageObject; import mage.abilities.Abilities; @@ -95,9 +96,6 @@ public interface Player extends MageItem, Copyable { public boolean cast(SpellAbility ability, Game game, boolean noMana); public boolean putInHand(Card card, Game game); public boolean removeFromHand(Card card, Game game); - public boolean putOntoBattlefield(Card card, Game game); -// public boolean putOntoBattlefield(Card copy, Card card, Game game); - public boolean putOntoBattlefield(Token token, Game game); public boolean removeFromBattlefield(Permanent permanent, Game game); public boolean putInGraveyard(Card card, Game game, boolean fromBattlefield); public boolean removeFromGraveyard(Card card, Game game); diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 5fda7288e44..f0654e6121a 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -259,7 +259,7 @@ public abstract class PlayerImpl> implements Player, Ser if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DRAW_CARD, null, playerId))) { Card card = getLibrary().removeFromTop(game); if (card != null) { - putInHand(card, game); + card.moveToZone(Zone.HAND, game, false); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DREW_CARD, card.getId(), playerId)); return true; } @@ -293,8 +293,6 @@ public abstract class PlayerImpl> implements Player, Ser public boolean putInHand(Card card, Game game) { if (card.getOwnerId().equals(playerId)) { this.hand.add(card); -// if (card.getSpellAbility() != null) -// card.getSpellAbility().clear(); } else { return game.getPlayer(card.getOwnerId()).putInHand(card, game); } @@ -330,34 +328,14 @@ public abstract class PlayerImpl> implements Player, Ser //20091005 - 701.1 if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DISCARD_CARD, playerId, playerId))) { removeFromHand(card, game); - putInGraveyard(card, game, false); - game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, playerId, playerId)); - return true; + if (card.moveToZone(Zone.GRAVEYARD, game, false)) { + game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, playerId, playerId)); + return true; + } } return false; } - @Override - public boolean putOntoBattlefield(Card card, Game game) { - PermanentCard permanent = new PermanentCard(card, playerId); - putOntoBattlefield(permanent, game); - return true; - } - - @Override - public boolean putOntoBattlefield(Token token, Game game) { - PermanentToken permanent = new PermanentToken(token, playerId, playerId); - putOntoBattlefield(permanent, game); - return true; - } - - protected void putOntoBattlefield(Permanent permanent, Game game) { - game.getBattlefield().addPermanent(permanent); - permanent.entersBattlefield(game); - game.applyEffects(); - game.fireEvent(new ZoneChangeEvent(permanent.getId(), playerId, Zone.ALL, Zone.BATTLEFIELD)); - } - @Override public boolean removeFromBattlefield(Permanent permanent, Game game) { permanent.removeFromCombat(game); @@ -414,7 +392,7 @@ public abstract class PlayerImpl> implements Player, Ser if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), playerId))) { game.bookmarkState(); removeFromHand(card, game); - if (putOntoBattlefield(card, game)) { + if (card.putOntoBattlefield(game, Zone.HAND, playerId)) { landsPlayed++; game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LAND_PLAYED, card.getId(), playerId)); game.fireInformEvent(name + " plays " + card.getName()); diff --git a/Mage/src/mage/target/TargetPermanent.java b/Mage/src/mage/target/TargetPermanent.java index 2292411fc3d..28bdf6fb9bf 100644 --- a/Mage/src/mage/target/TargetPermanent.java +++ b/Mage/src/mage/target/TargetPermanent.java @@ -33,7 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import mage.Constants.TargetController; import mage.Constants.Zone; import mage.MageObject; import mage.abilities.Ability; @@ -48,38 +47,31 @@ import mage.game.permanent.Permanent; public class TargetPermanent> extends TargetObject> { protected FilterPermanent filter; - protected TargetController controller; public TargetPermanent() { - this(1, 1, new FilterPermanent(), TargetController.ANY, false); + this(1, 1, new FilterPermanent(), false); } public TargetPermanent(FilterPermanent filter) { - this(1, 1, filter, TargetController.ANY, false); + this(1, 1, filter, false); } - public TargetPermanent(FilterPermanent filter, TargetController controller) { - this(1, 1, filter, controller, false); + public TargetPermanent(int numTargets, FilterPermanent filter) { + this(numTargets, numTargets, filter, false); } - public TargetPermanent(int numTargets, FilterPermanent filter, TargetController controller) { - this(numTargets, numTargets, filter, controller, false); - } - - public TargetPermanent(int minNumTargets, int maxNumTargets, FilterPermanent filter, TargetController controller, boolean notTarget) { + public TargetPermanent(int minNumTargets, int maxNumTargets, FilterPermanent filter, boolean notTarget) { this.minNumberOfTargets = minNumTargets; this.maxNumberOfTargets = maxNumTargets; this.zone = Zone.BATTLEFIELD; this.filter = filter; this.targetName = filter.getMessage(); - this.controller = controller; this.notTarget = notTarget; } public TargetPermanent(final TargetPermanent target) { super(target); this.filter = target.filter.copy(); - this.controller = target.controller; } @Override @@ -89,42 +81,16 @@ public class TargetPermanent> extends TargetObject< public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { Permanent permanent = game.getPermanent(id); - if (controllerId != null) - setController(controllerId, game); if (permanent != null) { if (source != null) //TODO: check for replacement effects - return permanent.canBeTargetedBy(game.getObject(source.getSourceId())) && filter.match(permanent); + return permanent.canBeTargetedBy(game.getObject(source.getSourceId())) && filter.match(permanent, controllerId, game); else - return filter.match(permanent); + return filter.match(permanent, controllerId, game); } return false; } - public void setTargetController(TargetController controller) { - this.controller = controller; - } - - protected void setController(UUID controllerId, Game game) { - filter.getControllerId().clear(); - switch (controller) { - case ANY: - break; - case YOU: - filter.getControllerId().add(controllerId); - filter.setNotController(false); - break; - case NOT_YOU: - filter.getControllerId().add(controllerId); - filter.setNotController(true); - break; - case OPPONENT: - filter.getControllerId().addAll(game.getOpponents(controllerId)); - filter.setNotController(false); - break; - } - } - @Override public FilterPermanent getFilter() { return this.filter; @@ -134,8 +100,6 @@ public class TargetPermanent> extends TargetObject< public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { int count = 0; MageObject targetSource = game.getObject(sourceId); - if (sourceControllerId != null) - setController(sourceControllerId, game); for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, game)) { if (permanent.canBeTargetedBy(targetSource)) { count++; @@ -150,8 +114,6 @@ public class TargetPermanent> extends TargetObject< public List possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { Map possibleTargets = new HashMap(); MageObject targetSource = game.getObject(sourceId); - if (sourceControllerId != null) - setController(sourceControllerId, game); for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, game)) { if (permanent.canBeTargetedBy(targetSource)) { possibleTargets.put(permanent.getValue().hashCode(), permanent.getId()); diff --git a/Mage/src/mage/target/common/TargetAttackingCreature.java b/Mage/src/mage/target/common/TargetAttackingCreature.java index c856cfd0bde..8061ba0fbe3 100644 --- a/Mage/src/mage/target/common/TargetAttackingCreature.java +++ b/Mage/src/mage/target/common/TargetAttackingCreature.java @@ -38,15 +38,15 @@ import mage.filter.common.FilterAttackingCreature; public class TargetAttackingCreature extends TargetCreaturePermanent { public TargetAttackingCreature() { - this(1, 1, new FilterAttackingCreature(), TargetController.ANY, false); + this(1, 1, new FilterAttackingCreature(), false); } - public TargetAttackingCreature(int numTargets, TargetController controller) { - this(numTargets, numTargets, new FilterAttackingCreature(), controller, false); + public TargetAttackingCreature(int numTargets) { + this(numTargets, numTargets, new FilterAttackingCreature(), false); } - public TargetAttackingCreature(int minNumTargets, int maxNumTargets, FilterAttackingCreature filter, TargetController controller, boolean notTarget) { - super(1, 1, filter, controller, notTarget); + public TargetAttackingCreature(int minNumTargets, int maxNumTargets, FilterAttackingCreature filter, boolean notTarget) { + super(1, 1, filter, notTarget); this.targetName = filter.getMessage(); } diff --git a/Mage/src/mage/target/common/TargetControlledCreaturePermanent.java b/Mage/src/mage/target/common/TargetControlledCreaturePermanent.java new file mode 100644 index 00000000000..175cf8b33bd --- /dev/null +++ b/Mage/src/mage/target/common/TargetControlledCreaturePermanent.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.target.common; + +import mage.filter.common.FilterControlledCreaturePermanent; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class TargetControlledCreaturePermanent extends TargetControlledPermanent { + + public TargetControlledCreaturePermanent() { + this(1, 1, new FilterControlledCreaturePermanent(), false); + } + + public TargetControlledCreaturePermanent(int numTargets) { + this(numTargets, numTargets, new FilterControlledCreaturePermanent(), false); + } + + public TargetControlledCreaturePermanent(int minNumTargets, int maxNumTargets, FilterControlledCreaturePermanent filter, boolean notTarget) { + super(1, 1, filter, notTarget); + this.targetName = filter.getMessage(); + } + + public TargetControlledCreaturePermanent(final TargetControlledCreaturePermanent target) { + super(target); + } + + @Override + public TargetControlledCreaturePermanent copy() { + return new TargetControlledCreaturePermanent(this); + } +} diff --git a/Mage/src/mage/target/common/TargetControlledPermanent.java b/Mage/src/mage/target/common/TargetControlledPermanent.java index a92cf626c68..3a6f29fd788 100644 --- a/Mage/src/mage/target/common/TargetControlledPermanent.java +++ b/Mage/src/mage/target/common/TargetControlledPermanent.java @@ -30,24 +30,29 @@ package mage.target.common; import mage.Constants.TargetController; import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledPermanent; import mage.target.TargetPermanent; /** * * @author BetaSteward_at_googlemail.com */ -public class TargetControlledPermanent extends TargetPermanent { +public class TargetControlledPermanent> extends TargetPermanent> { public TargetControlledPermanent() { - this(1, 1, new FilterPermanent(), false); + this(1, 1, new FilterControlledPermanent(), false); } public TargetControlledPermanent(int numTargets) { - this(numTargets, numTargets, new FilterPermanent(), false); + this(numTargets, numTargets, new FilterControlledPermanent(), false); } - public TargetControlledPermanent(int minNumTargets, int maxNumTargets, FilterPermanent filter, boolean notTarget) { - super(1, 1, filter, TargetController.YOU, notTarget); + public TargetControlledPermanent(FilterControlledPermanent filter) { + this(1, 1, filter, false); + } + + public TargetControlledPermanent(int minNumTargets, int maxNumTargets, FilterControlledPermanent filter, boolean notTarget) { + super(1, 1, filter, notTarget); this.targetName = filter.getMessage(); } diff --git a/Mage/src/mage/target/common/TargetCreatureOrPlayer.java b/Mage/src/mage/target/common/TargetCreatureOrPlayer.java index 32c6330080b..ac539a77eea 100644 --- a/Mage/src/mage/target/common/TargetCreatureOrPlayer.java +++ b/Mage/src/mage/target/common/TargetCreatureOrPlayer.java @@ -96,7 +96,7 @@ public class TargetCreatureOrPlayer extends TargetImpl { MageObject targetSource = game.getObject(source.getSourceId()); if (permanent != null) { if (source != null) - return permanent.canBeTargetedBy(targetSource) && filter.match(permanent); + return permanent.canBeTargetedBy(targetSource) && filter.match(permanent, source.getControllerId(), game); else return filter.match(permanent); } @@ -122,7 +122,7 @@ public class TargetCreatureOrPlayer extends TargetImpl { } } for (Permanent permanent: game.getBattlefield().getActivePermanents(FilterCreaturePermanent.getDefault(), sourceControllerId, game)) { - if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent)) { + if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent, sourceControllerId, game)) { count++; if (count >= this.minNumberOfTargets) return true; @@ -142,7 +142,7 @@ public class TargetCreatureOrPlayer extends TargetImpl { } } for (Permanent permanent: game.getBattlefield().getActivePermanents(FilterCreaturePermanent.getDefault(), sourceControllerId, game)) { - if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent)) { + if (permanent.canBeTargetedBy(targetSource) && filter.match(permanent, sourceControllerId, game)) { possibleTargets.put(permanent.getValue().hashCode(), permanent.getId()); } } diff --git a/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java b/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java index 2b5ca0f102d..ffd0a53683c 100644 --- a/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java +++ b/Mage/src/mage/target/common/TargetCreatureOrPlayerAmount.java @@ -87,7 +87,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount= this.minNumberOfTargets) return true; @@ -133,7 +133,7 @@ public class TargetCreatureOrPlayerAmount extends TargetAmount> extends TargetPermanent> { public TargetCreaturePermanent() { - this(1, 1, FilterCreaturePermanent.getDefault(), TargetController.ANY, false); + this(1, 1, FilterCreaturePermanent.getDefault(), false); } public TargetCreaturePermanent(FilterCreaturePermanent filter) { - this(1, 1, filter, TargetController.ANY, false); + this(1, 1, filter, false); } - public TargetCreaturePermanent(int numTargets, TargetController controller) { - this(numTargets, numTargets, FilterCreaturePermanent.getDefault(), controller, false); + public TargetCreaturePermanent(int numTargets) { + this(numTargets, numTargets, FilterCreaturePermanent.getDefault(), false); } - public TargetCreaturePermanent(int minNumTargets, int maxNumTargets, FilterCreaturePermanent filter, TargetController controller, boolean notTarget) { - super(1, 1, filter, controller, notTarget); + public TargetCreaturePermanent(int minNumTargets, int maxNumTargets, FilterCreaturePermanent filter, boolean notTarget) { + super(1, 1, filter, notTarget); this.targetName = filter.getMessage(); } diff --git a/Mage/src/mage/target/common/TargetLandPermanent.java b/Mage/src/mage/target/common/TargetLandPermanent.java index 8d4a07c019a..caf85da1f99 100644 --- a/Mage/src/mage/target/common/TargetLandPermanent.java +++ b/Mage/src/mage/target/common/TargetLandPermanent.java @@ -39,19 +39,19 @@ import mage.target.TargetPermanent; public class TargetLandPermanent> extends TargetPermanent> { public TargetLandPermanent() { - this(1, 1, new FilterLandPermanent(), TargetController.ANY, false); + this(1, 1, new FilterLandPermanent(), false); } public TargetLandPermanent(FilterLandPermanent filter) { - this(1, 1, filter, TargetController.ANY, false); + this(1, 1, filter, false); } - public TargetLandPermanent(int numTargets, TargetController controller) { - this(numTargets, numTargets, new FilterLandPermanent(), controller, false); + public TargetLandPermanent(int numTargets) { + this(numTargets, numTargets, new FilterLandPermanent(), false); } - public TargetLandPermanent(int minNumTargets, int maxNumTargets, FilterLandPermanent filter, TargetController controller, boolean notTarget) { - super(1, 1, filter, controller, notTarget); + public TargetLandPermanent(int minNumTargets, int maxNumTargets, FilterLandPermanent filter, boolean notTarget) { + super(1, 1, filter, notTarget); this.targetName = filter.getMessage(); } diff --git a/Mage/src/mage/target/common/TargetNonlandPermanent.java b/Mage/src/mage/target/common/TargetNonlandPermanent.java index 47a8da6958b..9bec9d18651 100644 --- a/Mage/src/mage/target/common/TargetNonlandPermanent.java +++ b/Mage/src/mage/target/common/TargetNonlandPermanent.java @@ -28,7 +28,6 @@ package mage.target.common; -import mage.Constants.TargetController; import mage.filter.common.FilterNonlandPermanent; import mage.target.TargetPermanent; @@ -39,15 +38,15 @@ import mage.target.TargetPermanent; public class TargetNonlandPermanent extends TargetPermanent { public TargetNonlandPermanent() { - this(1, 1, TargetController.ANY, false); + this(1, 1, false); } - public TargetNonlandPermanent(int numTargets, TargetController controller) { - this(numTargets, numTargets, controller, false); + public TargetNonlandPermanent(int numTargets) { + this(numTargets, numTargets, false); } - public TargetNonlandPermanent(int minNumTargets, int maxNumTargets, TargetController controller, boolean notTarget) { - super(1, 1, new FilterNonlandPermanent(), controller, notTarget); + public TargetNonlandPermanent(int minNumTargets, int maxNumTargets, boolean notTarget) { + super(1, 1, new FilterNonlandPermanent(), notTarget); this.targetName = filter.getMessage(); }