* Blizzard Specter - Fixed that the seond mode (discard) did not work.

This commit is contained in:
LevelX2 2015-10-09 14:22:21 +02:00
parent 816c4bf652
commit 987280c4e7
8 changed files with 322 additions and 201 deletions

View file

@ -32,7 +32,6 @@ import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
@ -41,7 +40,6 @@ import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -65,14 +63,17 @@ public class BlizzardSpecter extends CardImpl {
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
// Whenever Blizzard Specter deals combat damage to a player, choose one - That player returns a permanent he or she controls to its owner's hand; or that player discards a card.
Ability ability2 = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandEffect(), false);
Mode mode2 = new Mode(); // Whenever Blizzard Specter deals combat damage to a player, choose one
mode2.getEffects().add(new DiscardTargetEffect(1, false)); // - That player returns a permanent he or she controls to its owner's hand;
ability2.addMode(mode2); Ability ability = new DealsCombatDamageToAPlayerTriggeredAbility(new ReturnToHandEffect(), false, true);
this.addAbility(ability2); // or that player discards a card.
Mode mode = new Mode();
mode.getEffects().add(new DiscardTargetEffect(1, false));
ability.addMode(mode);
this.addAbility(ability);
} }
public BlizzardSpecter(final BlizzardSpecter card) { public BlizzardSpecter(final BlizzardSpecter card) {
@ -103,26 +104,19 @@ class ReturnToHandEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
boolean result = false; Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
if (targetPlayer == null) {
Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player == null) {
return false; return false;
} }
Target target = new TargetControlledPermanent(1, 1, new FilterControlledPermanent(), true); Target target = new TargetControlledPermanent(1, 1, new FilterControlledPermanent(), true);
if (target.canChoose(player.getId(), game)) { if (target.canChoose(targetPlayer.getId(), game)) {
while (player.canRespond() && !target.isChosen() && target.canChoose(player.getId(), game)) { targetPlayer.chooseTarget(Outcome.ReturnToHand, target, source, game);
player.chooseTarget(Outcome.ReturnToHand, target, source, game); Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
targetPlayer.moveCards(permanent, null, Zone.HAND, source, game);
} }
for (UUID targetId: target.getTargets()) { }
Permanent permanent = game.getPermanent(targetId); return true;
if (permanent != null) {
result |= permanent.moveToZone(Zone.HAND, source.getSourceId(), game, false);
}
}
}
return result;
} }
} }

View file

@ -41,7 +41,6 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
/** /**

View file

@ -0,0 +1,95 @@
/*
* 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 org.mage.test.cards.modal;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class ModalTriggeredAbilityTest extends CardTestPlayerBase {
@Test
public void testBlizzardSpecterReturn() {
// Flying
// Whenever Blizzard Specter deals combat damage to a player, choose one
// - That player returns a permanent he or she controls to its owner's hand;
// or that player discards a card.
addCard(Zone.BATTLEFIELD, playerB, "Blizzard Specter");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
addCard(Zone.HAND, playerA, "Pillarfield Ox");
attack(2, playerB, "Blizzard Specter");
setModeChoice(playerB, "1");
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertHandCount(playerA, "Silvercoat Lion", 1);
assertHandCount(playerA, "Pillarfield Ox", 1);
assertLife(playerA, 18);
assertLife(playerB, 20);
}
@Test
public void testBlizzardSpecterDiscard() {
// Flying
// Whenever Blizzard Specter deals combat damage to a player, choose one
// - That player returns a permanent he or she controls to its owner's hand;
// or that player discards a card.
addCard(Zone.BATTLEFIELD, playerB, "Blizzard Specter");
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
addCard(Zone.HAND, playerA, "Pillarfield Ox");
attack(2, playerB, "Blizzard Specter");
setModeChoice(playerB, "2");
setStopAt(2, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertHandCount(playerA, "Silvercoat Lion", 0);
assertHandCount(playerA, "Pillarfield Ox", 0);
assertGraveyardCount(playerA, "Pillarfield Ox", 1);
assertLife(playerA, 18);
assertLife(playerB, 20);
}
}

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities; package mage.abilities;
import java.io.Serializable; import java.io.Serializable;
@ -54,16 +53,16 @@ import mage.target.Targets;
import mage.watchers.Watcher; import mage.watchers.Watcher;
/** /**
* Practically everything in the game is started from an Ability. This * Practically everything in the game is started from an Ability. This interface
* interface describes what an Ability is composed of at the highest level. * describes what an Ability is composed of at the highest level.
*/ */
public interface Ability extends Controllable, Serializable { public interface Ability extends Controllable, Serializable {
/** /**
* Gets the globally unique id of the ability contained within the game. * Gets the globally unique id of the ability contained within the game.
* *
* @return A {@link java.util.UUID} which the game will use to store and retrieve * @return A {@link java.util.UUID} which the game will use to store and
* the exact instance of this ability. * retrieve the exact instance of this ability.
*/ */
@Override @Override
UUID getId(); UUID getId();
@ -71,18 +70,24 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Assigns a new {@link java.util.UUID} * Assigns a new {@link java.util.UUID}
* *
* @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility, mage.game.Game) * @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility,
* @see mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility) * mage.game.Game)
* @see mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility) * @see
* mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility)
* @see
* mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility)
*/ */
void newId(); void newId();
/** /**
* Assigns a new {@link java.util.UUID} * Assigns a new {@link java.util.UUID}
* *
* @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility, mage.game.Game) * @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility,
* @see mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility) * mage.game.Game)
* @see mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility) * @see
* mage.game.GameImpl#addTriggeredAbility(mage.abilities.TriggeredAbility)
* @see
* mage.game.GameImpl#addDelayedTriggeredAbility(mage.abilities.DelayedTriggeredAbility)
*/ */
void newOriginalId(); void newOriginalId();
@ -111,7 +116,8 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Gets the id of the object which put this ability in motion. * Gets the id of the object which put this ability in motion.
* *
* @return The {@link java.util.UUID} of the object this ability is associated with. * @return The {@link java.util.UUID} of the object this ability is
* associated with.
*/ */
UUID getSourceId(); UUID getSourceId();
@ -148,8 +154,8 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Gets all the {@link ManaCosts} that must be paid before activating this * Gets all the {@link ManaCosts} that must be paid before activating this
* ability. These costs should be modified by any modification effects currently * ability. These costs should be modified by any modification effects
* present within the game state. * currently present within the game state.
* *
* @return All {@link ManaCosts} that must be paid. * @return All {@link ManaCosts} that must be paid.
*/ */
@ -166,7 +172,8 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Gets all {@link AlternativeCost} associated with this ability. * Gets all {@link AlternativeCost} associated with this ability.
* *
* @return All {@link AlternativeCost}'s that can be paid instead of the {@link ManaCosts} * @return All {@link AlternativeCost}'s that can be paid instead of the
* {@link ManaCosts}
*/ */
List<AlternativeCost> getAlternativeCosts(); List<AlternativeCost> getAlternativeCosts();
@ -196,14 +203,22 @@ public interface Ability extends Controllable, Serializable {
void addOptionalCost(Cost cost); void addOptionalCost(Cost cost);
/** /**
* Retrieves the effects that are put into the place by the resolution of this * Retrieves the effects that are put into the place by the resolution of
* ability. * this ability.
* *
* @return All {@link Effects} that will be put into place by the resolution * @return All {@link Effects} that will be put into place by the resolution
* of this ability. * of this ability.
*/ */
Effects getEffects(); Effects getEffects();
/**
* Retrieves all effects of an ability. That means effects from all modes
* event those modes that are not seleced (yet).
*
* @return All {@link Effects} of this ability.
*/
Effects getAllEffects();
/** /**
* Retrieves the effects of the specified {@link EffectType type} that are * Retrieves the effects of the specified {@link EffectType type} that are
* put into place by the resolution of this ability. * put into place by the resolution of this ability.
@ -222,19 +237,21 @@ public interface Ability extends Controllable, Serializable {
void addEffect(Effect effect); void addEffect(Effect effect);
/** /**
* Retrieves all targets that must be satisfied before this ability is * Retrieves all targets that must be satisfied before this ability is put
* put onto the stack. * onto the stack.
* *
* @return All {@link Targets} that must be satisfied before this ability is put onto * @return All {@link Targets} that must be satisfied before this ability is
* the stack. * put onto the stack.
*/ */
Targets getTargets(); Targets getTargets();
/** /**
* Retrieves the {@link Target} located at the 0th index in the {@link Targets}. * Retrieves the {@link Target} located at the 0th index in the
* A call to the method is equivalent to {@link #getTargets()}.get(0).getFirstTarget(). * {@link Targets}. A call to the method is equivalent to
* {@link #getTargets()}.get(0).getFirstTarget().
* *
* @return The {@link java.util.UUID} of the first target within the targets list. * @return The {@link java.util.UUID} of the first target within the targets
* list.
* *
* @see mage.target.Target * @see mage.target.Target
*/ */
@ -278,7 +295,8 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Retrieves a human readable string representing what the ability states it * Retrieves a human readable string representing what the ability states it
* accomplishes. This call is equivalent to {@link #getRule(boolean) getRule(false)} * accomplishes. This call is equivalent to
* {@link #getRule(boolean) getRule(false)}
* *
* @return A human readable string representing what the ability states it * @return A human readable string representing what the ability states it
* accomplishes * accomplishes
@ -286,9 +304,9 @@ public interface Ability extends Controllable, Serializable {
String getRule(); String getRule();
/** /**
* Retrieves a human readable string including any costs associated with this * Retrieves a human readable string including any costs associated with
* ability if the all parameter is true, and just the abilities rule text if * this ability if the all parameter is true, and just the abilities rule
* the all parameter is false. * text if the all parameter is false.
* *
* @param all True if costs are desired in the output, false otherwise. * @param all True if costs are desired in the output, false otherwise.
* @return * @return
@ -307,13 +325,18 @@ public interface Ability extends Controllable, Serializable {
* Activates this ability prompting the controller to pay any mandatory * Activates this ability prompting the controller to pay any mandatory
* {@link Costs} or {@link AlternativeCost} associated with this ability. * {@link Costs} or {@link AlternativeCost} associated with this ability.
* *
* @param game A reference the {@link Game} for which this ability should be activated within. * @param game A reference the {@link Game} for which this ability should be
* activated within.
* @param noMana Whether or not {@link ManaCosts} have to be paid. * @param noMana Whether or not {@link ManaCosts} have to be paid.
* @return True if this ability was successfully activated. * @return True if this ability was successfully activated.
* *
* @see mage.players.PlayerImpl#cast(mage.abilities.SpellAbility, mage.game.Game, boolean) * @see mage.players.PlayerImpl#cast(mage.abilities.SpellAbility,
* @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility, mage.game.Game) * mage.game.Game, boolean)
* @see mage.players.PlayerImpl#triggerAbility(mage.abilities.TriggeredAbility, mage.game.Game) * @see mage.players.PlayerImpl#playAbility(mage.abilities.ActivatedAbility,
* mage.game.Game)
* @see
* mage.players.PlayerImpl#triggerAbility(mage.abilities.TriggeredAbility,
* mage.game.Game)
*/ */
boolean activate(Game game, boolean noMana); boolean activate(Game game, boolean noMana);
@ -321,14 +344,17 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Resolves this ability and puts any effects it produces into play. This * Resolves this ability and puts any effects it produces into play. This
* method should only be called if the {@link #activate(mage.game.Game, boolean)} * method should only be called if the
* method returned true. * {@link #activate(mage.game.Game, boolean)} method returned true.
* *
* @param game The {@link Game} for which this ability resolves within. * @param game The {@link Game} for which this ability resolves within.
* @return Whether or not this ability successfully resolved. * @return Whether or not this ability successfully resolved.
* *
* @see mage.players.PlayerImpl#playManaAbility(mage.abilities.mana.ManaAbility, mage.game.Game) * @see
* @see mage.players.PlayerImpl#specialAction(mage.abilities.SpecialAction, mage.game.Game) * mage.players.PlayerImpl#playManaAbility(mage.abilities.mana.ManaAbility,
* mage.game.Game)
* @see mage.players.PlayerImpl#specialAction(mage.abilities.SpecialAction,
* mage.game.Game)
*/ */
boolean resolve(Game game); boolean resolve(Game game);
@ -340,7 +366,8 @@ public interface Ability extends Controllable, Serializable {
void reset(Game game); void reset(Game game);
/** /**
* Overridden by triggered abilities with intervening if clauses - rule 20110715 - 603.4 * Overridden by triggered abilities with intervening if clauses - rule
* 20110715 - 603.4
* *
* @param game * @param game
* @return Whether or not the intervening if clause is satisfied * @return Whether or not the intervening if clause is satisfied
@ -364,6 +391,7 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Gets the list of sub-abilities associated with this ability. * Gets the list of sub-abilities associated with this ability.
*
* @return * @return
*/ */
List<Ability> getSubAbilities(); List<Ability> getSubAbilities();
@ -376,6 +404,7 @@ public interface Ability extends Controllable, Serializable {
void addSubAbility(Ability ability); void addSubAbility(Ability ability);
List<Watcher> getWatchers(); List<Watcher> getWatchers();
void addWatcher(Watcher watcher); void addWatcher(Watcher watcher);
/** /**
@ -389,8 +418,9 @@ public interface Ability extends Controllable, Serializable {
boolean isInUseableZone(Game game, MageObject source, GameEvent event); boolean isInUseableZone(Game game, MageObject source, GameEvent event);
/** /**
* Returns true if the source object has currently the ability * Returns true if the source object has currently the ability (e.g. The
* (e.g. The object can have lost all or some abilities for some time (e.g. Turn to Frog) * object can have lost all or some abilities for some time (e.g. Turn to
* Frog)
* *
* @param game * @param game
* @param source * @param source
@ -400,7 +430,8 @@ public interface Ability extends Controllable, Serializable {
boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event); boolean hasSourceObjectAbility(Game game, MageObject source, GameEvent event);
/** /**
* Returns true if this ability has to be shown as topmost of all the rules of the object * Returns true if this ability has to be shown as topmost of all the rules
* of the object
* *
* @return * @return
*/ */
@ -415,10 +446,9 @@ public interface Ability extends Controllable, Serializable {
*/ */
void setRuleAtTheTop(boolean ruleAtTheTop); void setRuleAtTheTop(boolean ruleAtTheTop);
/** /**
* Returns true if this ability has to work also with face down object * Returns true if this ability has to work also with face down object (set
* (set to not visible normally). * to not visible normally).
* *
* @return * @return
*/ */
@ -440,19 +470,19 @@ public interface Ability extends Controllable, Serializable {
*/ */
boolean getRuleVisible(); boolean getRuleVisible();
/** /**
* Sets the value for the ruleVisible attribute * Sets the value for the ruleVisible attribute
* *
* true = rule will be shown for the card / permanent * true = rule will be shown for the card / permanent false = rule won't be
* false = rule won't be shown * shown
* *
* @param ruleVisible * @param ruleVisible
*/ */
void setRuleVisible(boolean ruleVisible); void setRuleVisible(boolean ruleVisible);
/** /**
* Returns true if the additional costs of the abilitiy should be visible on the tooltip text * Returns true if the additional costs of the abilitiy should be visible on
* the tooltip text
* *
* @return * @return
*/ */
@ -461,14 +491,13 @@ public interface Ability extends Controllable, Serializable {
/** /**
* Sets the value for the additional costs rule attribute * Sets the value for the additional costs rule attribute
* *
* true = rule will be shown for the card / permanent * true = rule will be shown for the card / permanent false = rule won't be
* false = rule won't be shown * shown
* *
* @param ruleAdditionalCostsVisible * @param ruleAdditionalCostsVisible
*/ */
void setAdditionalCostsRuleVisible(boolean ruleAdditionalCostsVisible); void setAdditionalCostsRuleVisible(boolean ruleAdditionalCostsVisible);
/** /**
* Get the originalId of the ability * Get the originalId of the ability
* *
@ -477,9 +506,9 @@ public interface Ability extends Controllable, Serializable {
UUID getOriginalId(); UUID getOriginalId();
/** /**
* Sets the ability word for the given ability. * Sets the ability word for the given ability. An ability word is a word
* An ability word is a word that, in essence, groups, and reminds players of, cards * that, in essence, groups, and reminds players of, cards that have a
* that have a common functionality and does not imply any particular rules. * common functionality and does not imply any particular rules.
* *
* --- Not usable yet for rule text generation of triggered abilities --- * --- Not usable yet for rule text generation of triggered abilities ---
* *
@ -488,8 +517,8 @@ public interface Ability extends Controllable, Serializable {
void setAbilityWord(AbilityWord abilityWord); void setAbilityWord(AbilityWord abilityWord);
/** /**
* Creates the message about the ability casting/triggering/activating to post in the game log * Creates the message about the ability casting/triggering/activating to
* before the ability resolves. * post in the game log before the ability resolves.
* *
* @param game * @param game
* @return * @return
@ -497,8 +526,9 @@ public interface Ability extends Controllable, Serializable {
String getGameLogMessage(Game game); String getGameLogMessage(Game game);
/** /**
* Used to deactivate cost modification logic of ability activation for some special handling * Used to deactivate cost modification logic of ability activation for some
* (e.g. FlashbackAbility gets cost modifiaction twice because of how it's handled now) * special handling (e.g. FlashbackAbility gets cost modifiaction twice
* because of how it's handled now)
* *
* @param active execute no cost modification * @param active execute no cost modification
*/ */
@ -507,8 +537,8 @@ public interface Ability extends Controllable, Serializable {
boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game); boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game);
/** /**
* Sets the object that actually existed while a ability triggerd or * Sets the object that actually existed while a ability triggerd or an
* an ability was activated. * ability was activated.
* *
* @param mageObject * @param mageObject
* @param game * @param game
@ -516,9 +546,9 @@ public interface Ability extends Controllable, Serializable {
void setSourceObject(MageObject mageObject, Game game); void setSourceObject(MageObject mageObject, Game game);
/** /**
* Returns the object that actually existed while a ability triggerd or * Returns the object that actually existed while a ability triggerd or an
* an ability was activated. * ability was activated. If not set yet, the current object will be
* If not set yet, the current object will be retrieved from the game. * retrieved from the game.
* *
* @param game * @param game
* @return * @return
@ -528,14 +558,13 @@ public interface Ability extends Controllable, Serializable {
int getSourceObjectZoneChangeCounter(); int getSourceObjectZoneChangeCounter();
/** /**
* Returns the object that actually existed while a ability triggerd or * Returns the object that actually existed while a ability triggerd or an
* an ability was activated only if it has not changed zone meanwhile. * ability was activated only if it has not changed zone meanwhile. If not
* If not set yet, the current object will be retrieved from the game. * set yet, the current object will be retrieved from the game.
* *
* @param game * @param game
* @return * @return
*/ */
MageObject getSourceObjectIfItStillExists(Game game); MageObject getSourceObjectIfItStillExists(Game game);
String getTargetDescription(Targets targets, Game game); String getTargetDescription(Targets targets, Game game);

View file

@ -681,6 +681,15 @@ public abstract class AbilityImpl implements Ability {
return modes.getMode().getEffects(); return modes.getMode().getEffects();
} }
@Override
public Effects getAllEffects() {
Effects allEffects = new Effects();
for (Mode mode : getModes().values()) {
allEffects.addAll(mode.getEffects());
}
return allEffects;
}
@Override @Override
public Effects getEffects(Game game, EffectType effectType) { public Effects getEffects(Game game, EffectType effectType) {
Effects typedEffects = new Effects(); Effects typedEffects = new Effects();

View file

@ -77,11 +77,6 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
return true; return true;
} }
// TODO: Implement for all TriggeredAbilities so this default method can be removed
/*@Override
public boolean checkEventType(GameEvent event, Game game) {
return true;
}*/
@Override @Override
public boolean resolve(Game game) { public boolean resolve(Game game) {
if (isOptional()) { if (isOptional()) {

View file

@ -27,9 +27,9 @@
*/ */
package mage.abilities.common; package mage.abilities.common;
import mage.constants.Zone;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamagedPlayerEvent; import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
@ -72,7 +72,7 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
if (event.getSourceId().equals(getSourceId()) if (event.getSourceId().equals(getSourceId())
&& ((DamagedPlayerEvent) event).isCombatDamage()) { && ((DamagedPlayerEvent) event).isCombatDamage()) {
if (setTargetPointer) { if (setTargetPointer) {
for (Effect effect : this.getEffects()) { for (Effect effect : this.getAllEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId())); effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
effect.setValue("damage", event.getAmount()); effect.setValue("damage", event.getAmount());
} }

View file

@ -78,7 +78,7 @@ public class LandfallAbility extends TriggeredAbilityImpl {
&& permanent.getControllerId().equals(this.controllerId)) { && permanent.getControllerId().equals(this.controllerId)) {
triggeringLand = permanent; triggeringLand = permanent;
if (setTargetPointer.equals(SetTargetPointer.PERMANENT)) { if (setTargetPointer.equals(SetTargetPointer.PERMANENT)) {
for (Effect effect : getEffects()) { for (Effect effect : getAllEffects()) {
effect.setTargetPointer(new FixedTarget(permanent, game)); effect.setTargetPointer(new FixedTarget(permanent, game));
} }
} }