diff --git a/Mage.Common/src/mage/view/PlayerView.java b/Mage.Common/src/mage/view/PlayerView.java index eb2123fd877..6dc55fca136 100644 --- a/Mage.Common/src/mage/view/PlayerView.java +++ b/Mage.Common/src/mage/view/PlayerView.java @@ -80,8 +80,13 @@ public class PlayerView implements Serializable { //show permanents controlled by player or attachments to permanents controlled by player if (permanent.getAttachedTo() == null) return permanent.getControllerId().equals(playerId); - else - return game.getPermanent(permanent.getAttachedTo()).getControllerId().equals(playerId); + else { + Permanent attachedTo = game.getPermanent(permanent.getAttachedTo()); + if (attachedTo != null) + return attachedTo.getControllerId().equals(playerId); + else + return permanent.getControllerId().equals(playerId); + } } public int getLife() { diff --git a/Mage.Deck.Constructed/src/mage/deck/Constructed.java b/Mage.Deck.Constructed/src/mage/deck/Constructed.java index 94b21ba9edd..b76db08d3bd 100644 --- a/Mage.Deck.Constructed/src/mage/deck/Constructed.java +++ b/Mage.Deck.Constructed/src/mage/deck/Constructed.java @@ -62,7 +62,7 @@ public class Constructed extends DeckValidatorImpl { countCards(counts, deck.getSideboard()); for (Entry entry: counts.entrySet()) { if (entry.getValue() > 4) { - if (!basicLandNames.contains(entry.getKey())) { + if (!basicLandNames.contains(entry.getKey()) && !entry.getKey().equals("Relentless Rats")) { return false; } } diff --git a/Mage.Sets/src/mage/sets/magic2010/ArmoredAscension.java b/Mage.Sets/src/mage/sets/magic2010/ArmoredAscension.java index 2763540faf0..aa7a32d6c97 100644 --- a/Mage.Sets/src/mage/sets/magic2010/ArmoredAscension.java +++ b/Mage.Sets/src/mage/sets/magic2010/ArmoredAscension.java @@ -64,7 +64,7 @@ public class ArmoredAscension extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - Ability ability = new EnchantAbility(Outcome.BoostCreature, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ArmoredAscensionEffect())); diff --git a/Mage.Sets/src/mage/sets/magic2010/IceCage.java b/Mage.Sets/src/mage/sets/magic2010/IceCage.java index 37ed7ffb633..6b7ba704afe 100644 --- a/Mage.Sets/src/mage/sets/magic2010/IceCage.java +++ b/Mage.Sets/src/mage/sets/magic2010/IceCage.java @@ -64,7 +64,7 @@ public class IceCage extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); - Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new IceCageEffect())); this.addAbility(new IceCageAbility()); diff --git a/Mage.Sets/src/mage/sets/magic2010/MindControl.java b/Mage.Sets/src/mage/sets/magic2010/MindControl.java index 97eb0b46f1a..26d1ad4b0ed 100644 --- a/Mage.Sets/src/mage/sets/magic2010/MindControl.java +++ b/Mage.Sets/src/mage/sets/magic2010/MindControl.java @@ -62,7 +62,7 @@ public class MindControl extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); - Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MindControlEffect())); diff --git a/Mage.Sets/src/mage/sets/magic2010/PlatinumAngel.java b/Mage.Sets/src/mage/sets/magic2010/PlatinumAngel.java index 96f55368ebf..d7797beb10c 100644 --- a/Mage.Sets/src/mage/sets/magic2010/PlatinumAngel.java +++ b/Mage.Sets/src/mage/sets/magic2010/PlatinumAngel.java @@ -29,6 +29,7 @@ package mage.sets.magic2010; import java.util.UUID; +import mage.Constants.Rarity; /** * @@ -39,6 +40,7 @@ public class PlatinumAngel extends mage.sets.tenth.PlatinumAngel { public PlatinumAngel(UUID ownerId) { super(ownerId); this.expansionSetCode = "M10"; + this.rarity = Rarity.MYTHIC; } public PlatinumAngel(final PlatinumAngel card) { diff --git a/Mage.Sets/src/mage/sets/magic2010/Weakness.java b/Mage.Sets/src/mage/sets/magic2010/Weakness.java index 176fc5c070f..db919cc6080 100644 --- a/Mage.Sets/src/mage/sets/magic2010/Weakness.java +++ b/Mage.Sets/src/mage/sets/magic2010/Weakness.java @@ -61,7 +61,7 @@ public class Weakness extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature)); - Ability ability = new EnchantAbility(Outcome.BoostCreature, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new WeaknessEffect())); } @@ -77,7 +77,7 @@ public class Weakness extends CardImpl { @Override public String getArt() { - return "102510_typ_reg_sty_010.jpg"; + return "02510_typ_reg_sty_010.jpg"; } } diff --git a/Mage.Sets/src/mage/sets/magic2011/DryadsFavor.java b/Mage.Sets/src/mage/sets/magic2011/DryadsFavor.java index 51a9d48fd1b..a3efe488cbb 100644 --- a/Mage.Sets/src/mage/sets/magic2011/DryadsFavor.java +++ b/Mage.Sets/src/mage/sets/magic2011/DryadsFavor.java @@ -65,7 +65,7 @@ public class DryadsFavor extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); - Ability ability = new EnchantAbility(Outcome.Benefit, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DryadsFavorEffect())); diff --git a/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java b/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java index 7efd49865f2..08d57a7ce7e 100644 --- a/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java +++ b/Mage.Sets/src/mage/sets/magic2011/NecroticPlague.java @@ -71,7 +71,7 @@ public class NecroticPlague extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); - Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NecroticPlagueEffect())); diff --git a/Mage.Sets/src/mage/sets/magic2011/PlatinumAngel.java b/Mage.Sets/src/mage/sets/magic2011/PlatinumAngel.java index e6dcddbe3e5..2cdf1a736e9 100644 --- a/Mage.Sets/src/mage/sets/magic2011/PlatinumAngel.java +++ b/Mage.Sets/src/mage/sets/magic2011/PlatinumAngel.java @@ -34,7 +34,7 @@ import java.util.UUID; * * @author BetaSteward_at_googlemail.com */ -public class PlatinumAngel extends mage.sets.tenth.PlatinumAngel { +public class PlatinumAngel extends mage.sets.magic2010.PlatinumAngel { public PlatinumAngel(UUID ownerId) { super(ownerId); diff --git a/Mage.Sets/src/mage/sets/magic2011/PrimalCocoon.java b/Mage.Sets/src/mage/sets/magic2011/PrimalCocoon.java index 0c847006273..164af8bce05 100644 --- a/Mage.Sets/src/mage/sets/magic2011/PrimalCocoon.java +++ b/Mage.Sets/src/mage/sets/magic2011/PrimalCocoon.java @@ -62,7 +62,7 @@ public class PrimalCocoon extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); - Ability ability = new EnchantAbility(Outcome.Benefit, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new PrimalCocoonAbility1()); this.addAbility(new PrimalCocoonAbility2()); diff --git a/Mage.Sets/src/mage/sets/tenth/HolyStrength.java b/Mage.Sets/src/mage/sets/tenth/HolyStrength.java index 58c2397e425..ffbfd42c9f3 100644 --- a/Mage.Sets/src/mage/sets/tenth/HolyStrength.java +++ b/Mage.Sets/src/mage/sets/tenth/HolyStrength.java @@ -62,7 +62,7 @@ public class HolyStrength extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - Ability ability = new EnchantAbility(Outcome.BoostCreature, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new HolyStrengthEffect())); diff --git a/Mage.Sets/src/mage/sets/tenth/Pacifism.java b/Mage.Sets/src/mage/sets/tenth/Pacifism.java index bdc47bf6899..cb84a67942c 100644 --- a/Mage.Sets/src/mage/sets/tenth/Pacifism.java +++ b/Mage.Sets/src/mage/sets/tenth/Pacifism.java @@ -65,7 +65,7 @@ public class Pacifism extends CardImpl { TargetPermanent auraTarget = new TargetCreaturePermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); - Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PacifismEffect())); diff --git a/Mage.Sets/src/mage/sets/tenth/PlatinumAngel.java b/Mage.Sets/src/mage/sets/tenth/PlatinumAngel.java index 615e830796c..c16648d3d29 100644 --- a/Mage.Sets/src/mage/sets/tenth/PlatinumAngel.java +++ b/Mage.Sets/src/mage/sets/tenth/PlatinumAngel.java @@ -52,7 +52,7 @@ import mage.game.events.GameEvent.EventType; public class PlatinumAngel extends CardImpl { public PlatinumAngel(UUID ownerId) { - super(ownerId, "Platinum Angel", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}"); + super(ownerId, "Platinum Angel", Rarity.RARE, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{7}"); this.expansionSetCode = "10E"; this.subtype.add("Angel"); this.power = new MageInt(4); diff --git a/Mage.Sets/src/mage/sets/zendikar/OranRiefTheVastwood.java b/Mage.Sets/src/mage/sets/zendikar/OranRiefTheVastwood.java index e33e293291a..d48bd456ae9 100644 --- a/Mage.Sets/src/mage/sets/zendikar/OranRiefTheVastwood.java +++ b/Mage.Sets/src/mage/sets/zendikar/OranRiefTheVastwood.java @@ -98,7 +98,7 @@ class OranRiefTheVastwoodEffect extends OneShotEffect filter.getColor().setGreen(true); for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game)) { if (permanent.getTurnsOnBattlefield() == 0) { - permanent.getCounters().addCounter(new PlusOneCounter()); + permanent.addCounters(new PlusOneCounter()); } } return true; diff --git a/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java b/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java index 07733673e71..1dbea502589 100644 --- a/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java +++ b/Mage.Sets/src/mage/sets/zendikar/SpreadingSeas.java @@ -65,7 +65,7 @@ public class SpreadingSeas extends CardImpl { TargetPermanent auraTarget = new TargetLandPermanent(); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); - Ability ability = new EnchantAbility(Outcome.Detriment, auraTarget); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardControllerEffect(1), false)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpreadingSeasEffect())); diff --git a/Mage/src/mage/Constants.java b/Mage/src/mage/Constants.java index ee6bf0e0d6e..b68e90ec4da 100644 --- a/Mage/src/mage/Constants.java +++ b/Mage/src/mage/Constants.java @@ -284,6 +284,7 @@ public final class Constants { Tap(false), Untap(true), Win(true), + Copy(true), Benefit(true), Detriment(false), Neutral(true); diff --git a/Mage/src/mage/abilities/AbilityImpl.java b/Mage/src/mage/abilities/AbilityImpl.java index 4e467e712a8..b4490313ce2 100644 --- a/Mage/src/mage/abilities/AbilityImpl.java +++ b/Mage/src/mage/abilities/AbilityImpl.java @@ -46,6 +46,8 @@ import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.Card; import mage.choices.Choice; import mage.choices.Choices; import mage.game.Game; @@ -139,21 +141,40 @@ public abstract class AbilityImpl> implements Ability { @Override public boolean activate(Game game, boolean noMana) { + //20100716 - 601.2b if (choices.size() > 0 && choices.choose(game, this) == false) { logger.fine("activate failed - choice"); return false; } + //20100716 - 114.1b +// if (game.getObject(sourceId).getSubtype().contains("Aura")) { +// for (Ability ability: game.getObject(sourceId).getAbilities()) { +// if (ability instanceof EnchantAbility) { +// Targets enchantTargets = ability.getTargets(); +// if (enchantTargets.size() > 0 && enchantTargets.chooseTargets(ability.getEffects().get(0).getOutcome(), this.controllerId, this, game) == false) { +// logger.fine("activate failed - target"); +// return false; +// } +// break; +// } +// } +// } + //20100716 - 601.2b if (targets.size() > 0 && targets.chooseTargets(effects.get(0).getOutcome(), this.controllerId, this, game) == false) { logger.fine("activate failed - target"); return false; } - game.getObject(sourceId).adjustCosts(this, game); + //20100716 - 601.2e + if (game.getObject(sourceId) != null) + game.getObject(sourceId).adjustCosts(this, game); if (!useAlternativeCost(game)) { + //20100716 - 601.2f if (!manaCosts.pay(game, sourceId, controllerId, noMana)) { logger.fine("activate failed - mana"); return false; } } + //20100716 - 601.2g if (!costs.pay(game, sourceId, controllerId, noMana)) { logger.fine("activate failed - non mana costs"); return false; diff --git a/Mage/src/mage/abilities/costs/common/RemoveCountersSourceCost.java b/Mage/src/mage/abilities/costs/common/RemoveCountersSourceCost.java index 8b335c4cfc9..77bea55d0cd 100644 --- a/Mage/src/mage/abilities/costs/common/RemoveCountersSourceCost.java +++ b/Mage/src/mage/abilities/costs/common/RemoveCountersSourceCost.java @@ -67,7 +67,7 @@ public class RemoveCountersSourceCost extends CostImpl public boolean pay(Game game, UUID sourceId, UUID controllerId, boolean noMana) { Permanent permanent = game.getPermanent(sourceId); if (permanent != null && permanent.getCounters().getCount(name) >= amount) { - permanent.getCounters().removeCounter(name, amount); + permanent.removeCounters(name, amount, game); this.paid = true; } return paid; diff --git a/Mage/src/mage/abilities/effects/common/AddCountersSourceEffect.java b/Mage/src/mage/abilities/effects/common/AddCountersSourceEffect.java index cade08d1507..f4bdad5b266 100644 --- a/Mage/src/mage/abilities/effects/common/AddCountersSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/AddCountersSourceEffect.java @@ -60,9 +60,7 @@ public class AddCountersSourceEffect extends OneShotEffect { + private boolean tapped; + public ReturnSourceFromGraveyardToBattlefieldEffect() { + this(false); + } + + public ReturnSourceFromGraveyardToBattlefieldEffect(boolean tapped) { super(Outcome.PutCreatureInPlay); + this.tapped = tapped; } public ReturnSourceFromGraveyardToBattlefieldEffect(final ReturnSourceFromGraveyardToBattlefieldEffect effect) { super(effect); + this.tapped = effect.tapped; } @Override @@ -61,15 +70,24 @@ public class ReturnSourceFromGraveyardToBattlefieldEffect extends OneShotEffect< Card card = player.getGraveyard().get(source.getSourceId(), game); if (card != null) { player.removeFromGraveyard(card, game); - card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getControllerId()); - return true; + if (card.putOntoBattlefield(game, Zone.HAND, source.getControllerId())) { + if (tapped) { + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) + permanent.setTapped(true); + } + return true; + } } return false; } @Override public String getText(Ability source) { - return "Return {this} from your graveyard to the battlefield"; + if (tapped) + return "Return {this} from your graveyard to the battlefield tapped"; + else + return "Return {this} from your graveyard to the battlefield"; } } diff --git a/Mage/src/mage/abilities/keyword/EnchantAbility.java b/Mage/src/mage/abilities/keyword/EnchantAbility.java index 4018e7bde02..800f3511613 100644 --- a/Mage/src/mage/abilities/keyword/EnchantAbility.java +++ b/Mage/src/mage/abilities/keyword/EnchantAbility.java @@ -40,13 +40,16 @@ import mage.target.TargetPermanent; */ public class EnchantAbility extends StaticAbility { - public EnchantAbility(Outcome outcome, TargetPermanent target) { - super(Zone.BATTLEFIELD, new AttachEffect(outcome)); - this.addTarget(target); + protected String targetName; + + public EnchantAbility(String targetName) { + super(Zone.BATTLEFIELD, null); + this.targetName = targetName; } public EnchantAbility(final EnchantAbility ability) { super(ability); + this.targetName = ability.targetName; } @Override @@ -56,7 +59,7 @@ public class EnchantAbility extends StaticAbility { @Override public String getRule() { - return "Enchant " + this.getTargets().get(0).getTargetName(); + return "Enchant " + targetName; } diff --git a/Mage/src/mage/abilities/keyword/UnearthAbility.java b/Mage/src/mage/abilities/keyword/UnearthAbility.java index 8675b6f8fd0..24b2629cfc2 100644 --- a/Mage/src/mage/abilities/keyword/UnearthAbility.java +++ b/Mage/src/mage/abilities/keyword/UnearthAbility.java @@ -83,40 +83,6 @@ public class UnearthAbility extends ActivatedAbilityImpl { } -//class UnearthEffect extends OneShotEffect { -// -// public UnearthEffect() { -// super(Outcome.PutCreatureInPlay); -// } -// -// public UnearthEffect(final UnearthEffect effect) { -// super(effect); -// } -// -// @Override -// public UnearthEffect copy() { -// return new UnearthEffect(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.putOntoBattlefield(card, game); -// player.removeFromGraveyard(card, game); -// return true; -// } -// return false; -// } -// -// @Override -// public String getText(Ability source) { -// return "Return {this} from your graveyard to the battlefield"; -// } -// -//} - class UnearthDelayedTriggeredAbility extends DelayedTriggeredAbility { public UnearthDelayedTriggeredAbility() { diff --git a/Mage/src/mage/filter/common/FilterAura.java b/Mage/src/mage/filter/common/FilterAura.java new file mode 100644 index 00000000000..96c470230e8 --- /dev/null +++ b/Mage/src/mage/filter/common/FilterAura.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.CardType; +import mage.filter.FilterPermanent; + +/** + * + * @author BetaSteward_at_googlemail.com + */ +public class FilterAura extends FilterPermanent { + + public FilterAura() { + this("aura"); + } + + public FilterAura(String name) { + super(name); + this.cardType.add(CardType.ENCHANTMENT); + this.getSubtype().add("Aura"); + } + + public FilterAura(final FilterAura filter) { + super(filter); + } + + @Override + public FilterAura copy() { + return new FilterAura(this); + } +} diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index d1472eaa8f8..5805fbb15e1 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -57,7 +57,9 @@ import mage.abilities.keyword.LeylineAbility; import mage.cards.Card; import mage.cards.Cards; import mage.choices.Choice; +import mage.filter.Filter; import mage.filter.Filter.ComparisonScope; +import mage.filter.common.FilterAura; import mage.filter.common.FilterEquipment; import mage.filter.common.FilterFortification; import mage.filter.common.FilterLegendaryPermanent; @@ -89,6 +91,7 @@ public abstract class GameImpl> implements Game, Serializa private static FilterPlaneswalkerPermanent filterPlaneswalker = new FilterPlaneswalkerPermanent(); private static FilterLegendaryPermanent filterLegendary = new FilterLegendaryPermanent(); private static FilterLegendaryPermanent filterLegendName = new FilterLegendaryPermanent(); + private static FilterAura filterAura = new FilterAura(); private static FilterEquipment filterEquipment = new FilterEquipment(); private static FilterFortification filterFortification = new FilterFortification(); @@ -570,6 +573,25 @@ public abstract class GameImpl> implements Game, Serializa } } } + //20091005 - 704.5n + for (Permanent perm: getBattlefield().getAllActivePermanents(filterAura)) { + if (perm.getAttachedTo() == null) { + perm.moveToZone(Zone.GRAVEYARD, this, false); + } + else { + //TODO: handle player auras + Permanent attachedTo = getPermanent(perm.getAttachedTo()); + if (attachedTo == null) { + perm.moveToZone(Zone.GRAVEYARD, this, false); + } + else { + Filter auraFilter = perm.getSpellAbility().getTargets().get(0).getFilter(); + if (!auraFilter.match(attachedTo)) { + perm.moveToZone(Zone.GRAVEYARD, this, false); + } + } + } + } //20091005 - 704.5k, 801.12 if (getBattlefield().countAll(filterLegendary) > 1) { //don't bother checking if less than 2 legends in play for (Permanent legend: getBattlefield().getAllActivePermanents(filterLegendary)) { diff --git a/Mage/src/mage/game/events/GameEvent.java b/Mage/src/mage/game/events/GameEvent.java index 5d725717e14..c7b57ac567d 100644 --- a/Mage/src/mage/game/events/GameEvent.java +++ b/Mage/src/mage/game/events/GameEvent.java @@ -41,6 +41,7 @@ public class GameEvent { private UUID sourceId; private UUID playerId; private int amount; + private String data; public enum EventType { @@ -109,6 +110,7 @@ public class GameEvent { SACRIFICE_PERMANENT, SACRIFICED_PERMANENT, ATTACH, ATTACHED, UNATTACH, UNATTACHED, + COUNTER_REMOVED, //combat events COMBAT_DAMAGE_APPLIED, @@ -164,4 +166,11 @@ public class GameEvent { this.amount = amount; } + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } } diff --git a/Mage/src/mage/game/permanent/Permanent.java b/Mage/src/mage/game/permanent/Permanent.java index 4a707347803..b4421350ad6 100644 --- a/Mage/src/mage/game/permanent/Permanent.java +++ b/Mage/src/mage/game/permanent/Permanent.java @@ -30,10 +30,10 @@ package mage.game.permanent; import java.util.List; import java.util.UUID; -import mage.Constants.Zone; import mage.MageObject; import mage.abilities.Ability; import mage.cards.Card; +import mage.counters.Counter; import mage.counters.Counters; import mage.game.Game; import mage.game.events.GameEvent; @@ -71,12 +71,13 @@ public interface Permanent extends Card { public int damage(int damage, UUID sourceId, Game game, boolean preventable); public void removeAllDamage(Game game); public Counters getCounters(); + public void addCounters(String name, int amount); + public void addCounters(Counter counter); + public void removeCounters(String name, int amount, Game game); public void reset(Game game); public boolean destroy(UUID sourceId, Game game, boolean noRegen); public boolean sacrifice(UUID sourceId, Game game); public void entersBattlefield(Game game); -// public boolean moveToZone(Zone zone, Game game, boolean flag); -// public boolean moveToExile(UUID exileId, String name, Game game); public String getValue(); public void setArt(String art); diff --git a/Mage/src/mage/game/permanent/PermanentImpl.java b/Mage/src/mage/game/permanent/PermanentImpl.java index 55959201d39..a61ee6ee78a 100644 --- a/Mage/src/mage/game/permanent/PermanentImpl.java +++ b/Mage/src/mage/game/permanent/PermanentImpl.java @@ -50,6 +50,7 @@ import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ShroudAbility; import mage.cards.CardImpl; +import mage.counters.Counter; import mage.counters.Counters; import mage.game.Game; import mage.game.events.GameEvent; @@ -141,6 +142,25 @@ public abstract class PermanentImpl> extends CardImpl return counters; } + @Override + public void addCounters(String name, int amount) { + counters.addCounter(name, amount); + } + + @Override + public void addCounters(Counter counter) { + counters.addCounter(counter); + } + + @Override + public void removeCounters(String name, int amount, Game game) { + counters.removeCounter(name, amount); + GameEvent event = GameEvent.getEvent(EventType.COUNTER_REMOVED, objectId, controllerId); + event.setData(name); + for (int i = 0; i < amount; i++) + game.fireEvent(event); + } + @Override public int getTurnsOnBattlefield() { return turnsOnBattlefield; diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 1e21803393b..22c31913eaa 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -36,14 +36,18 @@ import mage.Constants.CardType; import mage.Constants.Rarity; import mage.Constants.Zone; import mage.MageInt; +import mage.MageObject; import mage.ObjectColor; import mage.abilities.Abilities; import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; 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.target.Target; import mage.watchers.Watchers; /** @@ -83,7 +87,6 @@ public class Spell> implements StackObject, Card { game.getExile().getPermanentExile().add(card); else card.moveToZone(Zone.GRAVEYARD, game, false); -// game.getPlayers().get(controllerId).putInGraveyard(card, game, false); return result; } //20091005 - 608.2b @@ -121,6 +124,26 @@ public class Spell> implements StackObject, Card { return replaced; } + public boolean chooseNewTargets(Game game) { + Player player = game.getPlayer(controllerId); + for (Target target: ability.getTargets()) { + Target newTarget = target.copy(); + newTarget.clearChosen(); + for (UUID targetId: target.getTargets()) { + MageObject object = game.getObject(targetId); + if (player.chooseUse(ability.getEffects().get(0).getOutcome(), "Change target from " + object.getName() + "?", game)) { + if (!player.chooseTarget(ability.getEffects().get(0).getOutcome(), newTarget, ability, game)) + newTarget.addTarget(targetId, ability, game); + } + } + target.getTargets().clear(); + for (UUID newTargetId: newTarget.getTargets()) { + target.getTargets().add(newTargetId); + } + } + return true; + } + @Override public void counter(Game game) { card.moveToZone(Zone.GRAVEYARD, game, false); @@ -168,7 +191,7 @@ public class Spell> implements StackObject, Card { } @Override - public Abilities getAbilities() { + public Abilities getAbilities() { return card.getAbilities(); } @@ -178,7 +201,7 @@ public class Spell> implements StackObject, Card { } @Override - public ManaCosts getManaCost() { + public ManaCosts getManaCost() { return card.getManaCost(); } diff --git a/Mage/src/mage/game/stack/SpellStack.java b/Mage/src/mage/game/stack/SpellStack.java index e7996683b03..4b98eaed982 100644 --- a/Mage/src/mage/game/stack/SpellStack.java +++ b/Mage/src/mage/game/stack/SpellStack.java @@ -121,6 +121,18 @@ public class SpellStack extends Stack { return null; } + public Spell getSpell(UUID id) { + for (StackObject stackObject: this) { + if (stackObject.getId().equals(id)) { + if (stackObject instanceof Spell) + return (Spell)stackObject; + else + return null; + } + } + return null; + } + public SpellStack copy() { return new SpellStack(this); } diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 455a8ec8d69..ee006d2a210 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -337,7 +337,9 @@ public abstract class PlayerImpl> implements Player, Ser permanent.removeFromCombat(game); game.getBattlefield().removePermanent(permanent.getId()); if (permanent.getAttachedTo() != null) { - game.getPermanent(permanent.getAttachedTo()).removeAttachment(permanent.getId(), game); + Permanent attachedTo = game.getPermanent(permanent.getAttachedTo()); + if (attachedTo != null) + attachedTo.removeAttachment(permanent.getId(), game); } return true; } diff --git a/Mage/src/mage/target/TargetSpell.java b/Mage/src/mage/target/TargetSpell.java index 0af6f384439..7097d57382f 100644 --- a/Mage/src/mage/target/TargetSpell.java +++ b/Mage/src/mage/target/TargetSpell.java @@ -78,9 +78,9 @@ public class TargetSpell extends TargetObject { @Override public boolean canTarget(UUID id, Ability source, Game game) { - StackObject stackObject = game.getStack().getStackObject(id); - if (stackObject != null && stackObject instanceof Spell) { - return filter.match((Spell)stackObject); + Spell spell = game.getStack().getSpell(id); + if (spell != null) { + return filter.match(spell); } return false; }