From 335462c8c8ae0af54f82b4caccf3ba790dc3f658 Mon Sep 17 00:00:00 2001 From: magenoxx Date: Thu, 16 Aug 2012 02:19:43 +0400 Subject: [PATCH] Fixed spellAbility fizzle on illegal targets. Fixed #Issue43: Huntmaster of the Fells triggered ability shouldn't be optional --- .../darkascension/HuntmasterOfTheFells.java | 16 ++++- .../sets/darkascension/RavagerOfTheFells.java | 8 ++- .../sets/worldwake/EverflowingChalice.java | 25 +------- .../mage/sets/worldwake/MarshalsAnthem.java | 6 +- .../sets/worldwake/StrengthOfTheTajuru.java | 1 + .../mage/abilities/common/EmptyEffect.java | 63 +++++++++++++++++++ Mage/src/mage/game/stack/StackAbility.java | 1 + Mage/src/mage/target/Targets.java | 13 ++-- 8 files changed, 97 insertions(+), 36 deletions(-) create mode 100644 Mage/src/mage/abilities/common/EmptyEffect.java diff --git a/Mage.Sets/src/mage/sets/darkascension/HuntmasterOfTheFells.java b/Mage.Sets/src/mage/sets/darkascension/HuntmasterOfTheFells.java index 0f7ab90be8a..a93d171a7a7 100644 --- a/Mage.Sets/src/mage/sets/darkascension/HuntmasterOfTheFells.java +++ b/Mage.Sets/src/mage/sets/darkascension/HuntmasterOfTheFells.java @@ -107,7 +107,7 @@ public class HuntmasterOfTheFells extends CardImpl { class HuntmasterOfTheFellsAbility extends TriggeredAbilityImpl { public HuntmasterOfTheFellsAbility() { - super(Constants.Zone.BATTLEFIELD, new CreateTokenEffect(new WolfToken(Token.Type.SECOND)), true); + super(Constants.Zone.BATTLEFIELD, new CreateTokenEffect(new WolfToken(Token.Type.SECOND)), false); this.addEffect(new GainLifeEffect(2)); } @@ -146,7 +146,7 @@ class HuntmasterOfTheFellsAbility extends TriggeredAbilityImpl { public RavagerOfTheFellsAbility() { - super(Constants.Zone.BATTLEFIELD, new RavagerOfTheFellsEffect(), true); + super(Constants.Zone.BATTLEFIELD, new RavagerOfTheFellsEffect(), false); Target target1 = new TargetOpponent(); target1.setRequired(true); this.addTarget(target1); @@ -183,7 +183,7 @@ class RavagerOfTheFellsEffect extends OneShotEffect { public RavagerOfTheFellsEffect() { super(Constants.Outcome.Damage); - staticText = "{this} deals 2 damage to target opponent and 2 damage to up to one target creature that player controls"; + //staticText = "{this} deals 2 damage to target opponent and 2 damage to up to one target creature that player controls"; } public RavagerOfTheFellsEffect(final RavagerOfTheFellsEffect effect) { @@ -235,6 +235,16 @@ class RavagerOfTheFellsTarget extends TargetPermanent { Set availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game); Set possibleTargets = new HashSet(); MageObject object = game.getObject(sourceId); + + for (StackObject item: game.getState().getStack()) { + if (item.getId().equals(sourceId)) { + object = item; + } + if (item.getSourceId().equals(sourceId)) { + object = item; + } + } + if (object instanceof StackObject) { UUID playerId = ((StackObject)object).getStackAbility().getFirstTarget(); for (UUID targetId : availablePossibleTargets) { diff --git a/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java b/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java index 31b2da7332e..91fa4e24c20 100644 --- a/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java +++ b/Mage.Sets/src/mage/sets/darkascension/RavagerOfTheFells.java @@ -27,13 +27,14 @@ */ package mage.sets.darkascension; -import java.util.UUID; import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.MageInt; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.EmptyEffect; +import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.common.TransformSourceEffect; @@ -41,12 +42,16 @@ import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; +import java.util.UUID; + /** * * @author BetaSteward */ public class RavagerOfTheFells extends CardImpl { + private static final String rule = "Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls"; + public RavagerOfTheFells(UUID ownerId) { super(ownerId, 140, "Ravager of the Fells", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, ""); this.expansionSetCode = "DKA"; @@ -62,6 +67,7 @@ public class RavagerOfTheFells extends CardImpl { this.addAbility(TrampleAbility.getInstance()); // Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new EmptyEffect(rule))); // At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ravager of the Fells. TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), Constants.TargetController.ANY, false); diff --git a/Mage.Sets/src/mage/sets/worldwake/EverflowingChalice.java b/Mage.Sets/src/mage/sets/worldwake/EverflowingChalice.java index 07965c9c578..db2e102784b 100644 --- a/Mage.Sets/src/mage/sets/worldwake/EverflowingChalice.java +++ b/Mage.Sets/src/mage/sets/worldwake/EverflowingChalice.java @@ -33,6 +33,7 @@ import mage.Constants.CardType; import mage.Constants.Rarity; import mage.Mana; import mage.abilities.Ability; +import mage.abilities.common.EmptyEffect; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.dynamicvalue.common.CountersCount; @@ -81,30 +82,6 @@ public class EverflowingChalice extends CardImpl { } -class EmptyEffect extends OneShotEffect { - - public EmptyEffect(String rule) { - super(Constants.Outcome.DrawCard); - staticText = rule; - } - - public EmptyEffect(final EmptyEffect effect) { - super(effect); - } - - @Override - public EmptyEffect copy() { - return new EmptyEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - // empty effect - return true; - } - -} - class EverflowingChaliceAddCountersEffect extends OneShotEffect { public EverflowingChaliceAddCountersEffect() { diff --git a/Mage.Sets/src/mage/sets/worldwake/MarshalsAnthem.java b/Mage.Sets/src/mage/sets/worldwake/MarshalsAnthem.java index 51529a028f6..c18f25b5e71 100644 --- a/Mage.Sets/src/mage/sets/worldwake/MarshalsAnthem.java +++ b/Mage.Sets/src/mage/sets/worldwake/MarshalsAnthem.java @@ -27,13 +27,12 @@ */ package mage.sets.worldwake; -import java.util.List; -import java.util.UUID; import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.Constants.TargetController; import mage.abilities.Ability; +import mage.abilities.common.EmptyEffect; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.ManaCostsImpl; @@ -51,6 +50,9 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInYourGraveyard; +import java.util.List; +import java.util.UUID; + /** * * @author jeffwadsworth diff --git a/Mage.Sets/src/mage/sets/worldwake/StrengthOfTheTajuru.java b/Mage.Sets/src/mage/sets/worldwake/StrengthOfTheTajuru.java index 812d3d5f8c4..27fe7e299a3 100644 --- a/Mage.Sets/src/mage/sets/worldwake/StrengthOfTheTajuru.java +++ b/Mage.Sets/src/mage/sets/worldwake/StrengthOfTheTajuru.java @@ -31,6 +31,7 @@ import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.abilities.Ability; +import mage.abilities.common.EmptyEffect; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.OneShotEffect; diff --git a/Mage/src/mage/abilities/common/EmptyEffect.java b/Mage/src/mage/abilities/common/EmptyEffect.java new file mode 100644 index 00000000000..9205206cff3 --- /dev/null +++ b/Mage/src/mage/abilities/common/EmptyEffect.java @@ -0,0 +1,63 @@ +/* +* 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.common; + +import mage.Constants; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.game.Game; + +/** + * This effect is used for adding rules on a card. + * It does nothing else. + * + * @author magenoxx_at_gmail.com + */ +public class EmptyEffect extends OneShotEffect { + + public EmptyEffect(String rule) { + super(Constants.Outcome.Neutral); + staticText = rule; + } + + public EmptyEffect(final EmptyEffect effect) { + super(effect); + } + + @Override + public EmptyEffect copy() { + return new EmptyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + // empty effect + return true; + } + +} \ No newline at end of file diff --git a/Mage/src/mage/game/stack/StackAbility.java b/Mage/src/mage/game/stack/StackAbility.java index b4350114153..fab6e413658 100644 --- a/Mage/src/mage/game/stack/StackAbility.java +++ b/Mage/src/mage/game/stack/StackAbility.java @@ -88,6 +88,7 @@ public class StackAbility implements StackObject, Ability { if (ability.getTargets().stillLegal(ability, game)) { return ability.resolve(game); } + game.informPlayers("Ability has been fizzled: " + getRule()); counter(null, game); return false; } diff --git a/Mage/src/mage/target/Targets.java b/Mage/src/mage/target/Targets.java index 2077fbd8ee5..ccee00c56e3 100644 --- a/Mage/src/mage/target/Targets.java +++ b/Mage/src/mage/target/Targets.java @@ -28,13 +28,14 @@ package mage.target; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.Constants.Outcome; import mage.abilities.Ability; import mage.game.Game; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** * * @author BetaSteward_at_googlemail.com @@ -103,12 +104,12 @@ public class Targets extends ArrayList { // The spell or ability is countered if all its targets, for every instance of the word "target," are now illegal int illegalCount = 0; for (Target target: this) { - if (target.isLegal(source, game)) { + if (!target.isLegal(source, game)) { illegalCount++; } } - // check all are illegal - return this.size() == illegalCount; + // it is legal when either there is no target or not all targets are illegal + return this.size() == 0 || this.size() != illegalCount; } /**