diff --git a/Mage.Sets/src/mage/sets/guildpact/CryOfContrition.java b/Mage.Sets/src/mage/sets/guildpact/CryOfContrition.java new file mode 100644 index 0000000000..5b275ee52d --- /dev/null +++ b/Mage.Sets/src/mage/sets/guildpact/CryOfContrition.java @@ -0,0 +1,68 @@ +/* + * 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.sets.guildpact; + +import java.util.UUID; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.abilities.keyword.HauntAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.TargetPlayer; + +/** + * + * @author LevelX2 + */ +public class CryOfContrition extends CardImpl { + + public CryOfContrition(UUID ownerId) { + super(ownerId, 46, "Cry of Contrition", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{B}"); + this.expansionSetCode = "GPT"; + + // Target player discards a card. + this.getSpellAbility().addEffect(new DiscardTargetEffect(1)); + this.getSpellAbility().addTarget(new TargetPlayer()); + + // Haunt (When this spell card is put into a graveyard after resolving, exile it haunting target creature.) + // When the creature Cry of Contrition haunts dies, target player discards a card. + HauntAbility ability = new HauntAbility(this, new DiscardTargetEffect(1)); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + } + + public CryOfContrition(final CryOfContrition card) { + super(card); + } + + @Override + public CryOfContrition copy() { + return new CryOfContrition(this); + } +} diff --git a/Mage/src/mage/abilities/effects/common/discard/DiscardTargetEffect.java b/Mage/src/mage/abilities/effects/common/discard/DiscardTargetEffect.java index 2715350d8a..0b7b1eea3d 100644 --- a/Mage/src/mage/abilities/effects/common/discard/DiscardTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/discard/DiscardTargetEffect.java @@ -102,7 +102,7 @@ public class DiscardTargetEffect extends OneShotEffect { if(mode.getTargets().isEmpty()){ sb.append("that player"); } else { - sb.append("Target ").append(mode.getTargets().get(0).getTargetName()); + sb.append("target ").append(mode.getTargets().get(0).getTargetName()); } sb.append(" discards "); if (amount.toString().equals("1")) { diff --git a/Mage/src/mage/abilities/keyword/HauntAbility.java b/Mage/src/mage/abilities/keyword/HauntAbility.java index f6db0f248f..61d5e363fb 100644 --- a/Mage/src/mage/abilities/keyword/HauntAbility.java +++ b/Mage/src/mage/abilities/keyword/HauntAbility.java @@ -35,6 +35,7 @@ import mage.abilities.common.ZoneChangeTriggeredAbility; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; +import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Zone; import mage.game.Game; @@ -64,15 +65,18 @@ import mage.target.targetpointer.FixedTarget; public class HauntAbility extends TriggeredAbilityImpl { private boolean usedFromExile = false; - + private boolean creatureHaunt; + public HauntAbility(Card card, Effect effect) { super(Zone.ALL, effect , false); - addSubAbility(new HauntExileAbility()); + creatureHaunt = card.getCardType().contains(CardType.CREATURE); + addSubAbility(new HauntExileAbility(creatureHaunt)); } public HauntAbility(final HauntAbility ability) { super(ability); this.usedFromExile = ability.usedFromExile; + this.creatureHaunt = ability.creatureHaunt; } @Override @@ -80,6 +84,16 @@ public class HauntAbility extends TriggeredAbilityImpl { return new HauntAbility(this); } + @Override + public boolean checkEventType(GameEvent event, Game game) { + switch (event.getType()) { + case ENTERS_THE_BATTLEFIELD: + case ZONE_CHANGE: + return true; + } + return false; + } + @Override public boolean checkTrigger(GameEvent event, Game game) { switch (event.getType()) { @@ -115,36 +129,49 @@ public class HauntAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "When {this} enters the battlefield or the creature it haunts dies, " + super.getRule(); + return (creatureHaunt ? "When {this} enters the battlefield or the creature it haunts dies, " : + "When the creature {this} haunts dies, ") + + super.getRule(); } } class HauntExileAbility extends ZoneChangeTriggeredAbility { private final static String RULE_TEXT_CREATURE = "Haunt (When this creature dies, exile it haunting target creature.)"; - public HauntExileAbility() { - super(Zone.BATTLEFIELD, Zone.GRAVEYARD, new HauntEffect(), null, false); - this.setRuleAtTheTop(true); + private final static String RULE_TEXT_SPELL = "Haunt (When this spell card is put into a graveyard after resolving, exile it haunting target creature.)"; + + private boolean creatureHaunt; + + // TODO: It's not checked yet, if the Haunt spell was resoved (and not countered or removed from stack). + + public HauntExileAbility(boolean creatureHaunt) { + super(creatureHaunt ? Zone.BATTLEFIELD: Zone.STACK, Zone.GRAVEYARD, new HauntEffect(), null, false); + this.creatureHaunt = creatureHaunt; + this.setRuleAtTheTop(creatureHaunt); this.addTarget(new TargetCreaturePermanent()); } - public HauntExileAbility(HauntExileAbility ability) { + public HauntExileAbility(final HauntExileAbility ability) { super(ability); + this.creatureHaunt = ability.creatureHaunt; } @Override - public boolean isInUseableZone(Game game, MageObject source, boolean checkLKI) { - // check it was previously on battlefield - MageObject before = game.getLastKnownInformation(sourceId, Zone.BATTLEFIELD); + public boolean isInUseableZone(Game game, MageObject source, boolean checkLKI) { + boolean fromOK = true; + if (creatureHaunt) { + // check it was previously on battlefield + fromOK = game.getLastKnownInformation(sourceId, Zone.BATTLEFIELD) != null; + } // check now it is in graveyard Zone after = game.getState().getZone(sourceId); - return before != null && after != null && Zone.GRAVEYARD.match(after); + return fromOK && after != null && Zone.GRAVEYARD.match(after); } @Override public String getRule() { - return RULE_TEXT_CREATURE; + return creatureHaunt ? RULE_TEXT_CREATURE : RULE_TEXT_SPELL; } @Override