diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AncientOfTheEquinox.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AncientOfTheEquinox.java index 9a2cd4c65fc..f89497400b9 100644 --- a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AncientOfTheEquinox.java +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AncientOfTheEquinox.java @@ -27,7 +27,13 @@ */ package mage.sets.shadowsoverinnistrad; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.HexproofAbility; +import mage.abilities.keyword.TrampleAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -35,20 +41,21 @@ import mage.cards.CardImpl; */ public class AncientOfTheEquinox extends CardImpl { - /* - public AncientOfTheEquinox(UUID ownerId) { - super(ownerId, 194b, "Ancient of the Equinox", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, ""); + public AncientOfTheEquinox(UUID ownerId) { + super(ownerId, 194, "Ancient of the Equinox", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, ""); this.expansionSetCode = "SOI"; this.subtype.add("Treefolk"); this.power = new MageInt(4); this.toughness = new MageInt(4); + this.color.setGreen(true); + this.nightCard = true; + this.canTransform = true; // Trample this.addAbility(TrampleAbility.getInstance()); // Hexproof this.addAbility(HexproofAbility.getInstance()); } - */ public AncientOfTheEquinox(final AncientOfTheEquinox card) { super(card); diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AutumnalGloom.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AutumnalGloom.java new file mode 100644 index 00000000000..2bccb5bb773 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/AutumnalGloom.java @@ -0,0 +1,76 @@ +/* + * 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.shadowsoverinnistrad; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.common.DeliriumCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.keyword.TransformAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class AutumnalGloom extends CardImpl { + + public AutumnalGloom(UUID ownerId) { + super(ownerId, 194, "Autumnal Gloom", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + this.expansionSetCode = "SOI"; + this.canTransform = true; + this.secondSideCard = new AncientOfTheEquinox(ownerId); + + // {B}: Put the top card of your library into your graveyard. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutTopCardOfLibraryIntoGraveControllerEffect(1), new ManaCostsImpl("{B}"))); + + // Delirium — At the beginning of your end step, if there are four or more card types among cards in your graveyard, transform Autumnal Gloom. + this.addAbility(new TransformAbility()); + Ability ability = new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new TransformSourceEffect(true), TargetController.YOU, DeliriumCondition.getInstance(), false); + ability.setAbilityWord(AbilityWord.DELIRIUM); + this.addAbility(ability); + } + + public AutumnalGloom(final AutumnalGloom card) { + super(card); + } + + @Override + public AutumnalGloom copy() { + return new AutumnalGloom(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/LilianasIndignation.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/LilianasIndignation.java index a3f7eaf360f..4b84babbfbe 100644 --- a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/LilianasIndignation.java +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/LilianasIndignation.java @@ -27,7 +27,22 @@ */ package mage.sets.shadowsoverinnistrad; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; /** * @@ -35,14 +50,14 @@ import mage.cards.CardImpl; */ public class LilianasIndignation extends CardImpl { - /* public LilianasIndignation(UUID ownerId) { super(ownerId, 120, "Liliana's Indignation", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{X}{B}"); this.expansionSetCode = "SOI"; - this.power = new MageInt(Put the top X cards of your library into your graveyard. Target player loses 2 life for each creature card put into your graveyard this way.); - this.toughness = new MageInt(); + + // Put the top X cards of your library into your graveyard. Target player loses 2 life for each creature card put into your graveyard this way. + this.getSpellAbility().addEffect(new LilianasIndignationEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); } -*/ public LilianasIndignation(final LilianasIndignation card) { super(card); @@ -53,3 +68,47 @@ public class LilianasIndignation extends CardImpl { return new LilianasIndignation(this); } } + +class LilianasIndignationEffect extends OneShotEffect { + + public LilianasIndignationEffect() { + super(Outcome.LoseLife); + this.staticText = "Put the top X cards of your library into your graveyard. Target player loses 2 life for each creature card put into your graveyard this way"; + } + + public LilianasIndignationEffect(final LilianasIndignationEffect effect) { + super(effect); + } + + @Override + public LilianasIndignationEffect copy() { + return new LilianasIndignationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + int x = source.getManaCostsToPay().getX(); + if (x > 0) { + Cards cardsToGraveyard = new CardsImpl(); + cardsToGraveyard.addAll(controller.getLibrary().getTopCards(game, x)); + if (!cardsToGraveyard.isEmpty()) { + Set movedCards = controller.moveCardsToGraveyardWithInfo(cardsToGraveyard.getCards(game), source, game, Zone.LIBRARY); + Cards cardsMoved = new CardsImpl(); + cardsMoved.addAll(movedCards); + int creatures = cardsMoved.count(new FilterCreatureCard(), game); + if (creatures > 0) { + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetPlayer != null) { + targetPlayer.loseLife(creatures * 2, game); + } + + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/SkinInvasion.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/SkinInvasion.java new file mode 100644 index 00000000000..e43c63d909a --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/SkinInvasion.java @@ -0,0 +1,120 @@ +/* + * 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.shadowsoverinnistrad; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.TransformAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class SkinInvasion extends CardImpl { + + public SkinInvasion(UUID ownerId) { + super(ownerId, 182, "Skin Invasion", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{R}"); + this.expansionSetCode = "SOI"; + this.subtype.add("Aura"); + + this.canTransform = true; + this.secondSideCard = new SkinShedder(ownerId); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // Enchanted creature attacks each combat if able. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, + new AttacksIfAbleAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.AURA))); + + // When enchanted creature dies, return Skin Invasion to the battlefield transformed under your control. + this.addAbility(new TransformAbility()); + this.addAbility(new DiesAttachedTriggeredAbility(new SkinInvasionEffect(), "enchanted creature", false)); + } + + public SkinInvasion(final SkinInvasion card) { + super(card); + } + + @Override + public SkinInvasion copy() { + return new SkinInvasion(this); + } +} + +class SkinInvasionEffect extends OneShotEffect { + + public SkinInvasionEffect() { + super(Outcome.PutCardInPlay); + this.staticText = "return {this} to the battlefield transformed under your control"; + } + + public SkinInvasionEffect(final SkinInvasionEffect effect) { + super(effect); + } + + @Override + public SkinInvasionEffect copy() { + return new SkinInvasionEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (card != null && controller != null) { + game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + controller.moveCards(card, Zone.BATTLEFIELD, source, game); + return true; + } + return false; + } + +} diff --git a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/SkinShedder.java b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/SkinShedder.java index 2fcbd052263..5a022db5ad8 100644 --- a/Mage.Sets/src/mage/sets/shadowsoverinnistrad/SkinShedder.java +++ b/Mage.Sets/src/mage/sets/shadowsoverinnistrad/SkinShedder.java @@ -27,23 +27,30 @@ */ package mage.sets.shadowsoverinnistrad; +import java.util.UUID; +import mage.MageInt; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * * @author LevelX2 */ public class SkinShedder extends CardImpl { -/* + public SkinShedder(UUID ownerId) { - super(ownerId, 182b, "Skin Shedder", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, ""); + super(ownerId, 182, "Skin Shedder", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, ""); this.expansionSetCode = "SOI"; this.subtype.add("Insect"); this.subtype.add("Horror"); + this.color.setRed(true); + this.nightCard = true; + this.power = new MageInt(3); this.toughness = new MageInt(4); } -*/ + public SkinShedder(final SkinShedder card) { super(card); } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java index d37249116ca..e1a6b44e2f7 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/TransformTest.java @@ -136,4 +136,23 @@ public class TransformTest extends CardTestPlayerBase { } + @Test + public void TestEnchantmentToCreature() { + addCard(Zone.GRAVEYARD, playerA, "Silvercoat Lion", 1); + addCard(Zone.GRAVEYARD, playerA, "Lightning Bolt", 1); + addCard(Zone.GRAVEYARD, playerA, "Fireball", 1); + addCard(Zone.GRAVEYARD, playerA, "Infernal Scarring", 1); + + // {B}: Put the top card of your library into your graveyard. + // Delirium &mdash At the beginning of your end step, if there are four or more card types among cards in your graveyard, transform Autumnal Gloom. + addCard(Zone.BATTLEFIELD, playerA, "Autumnal Gloom"); + + setStopAt(2, PhaseStep.PRECOMBAT_MAIN); + execute(); + + assertPermanentCount(playerA, "Autumnal Gloom", 0); + assertPermanentCount(playerA, "Ancient of the Equinox", 1); + + } + } diff --git a/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java index 1e0b759572f..b406ac4ebfb 100644 --- a/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/BeginningOfEndStepTriggeredAbility.java @@ -135,17 +135,21 @@ public class BeginningOfEndStepTriggeredAbility extends TriggeredAbilityImpl { sb.insert(0, "you may "); } } + String abilityWordRule = ""; + if (abilityWord != null) { + abilityWordRule = "" + abilityWord.toString() + " &mdash "; + } switch (targetController) { case YOU: - return sb.insert(0, generateConditionString()).insert(0, "At the beginning of your end step, ").toString(); + return sb.insert(0, generateConditionString()).insert(0, abilityWordRule + "At the beginning of your end step, ").toString(); case NEXT: - return sb.insert(0, generateConditionString()).insert(0, "At the beginning of the end step, ").toString(); + return sb.insert(0, generateConditionString()).insert(0, abilityWordRule + "At the beginning of the end step, ").toString(); case OPPONENT: - return sb.insert(0, generateConditionString()).insert(0, "At the beginning of each opponent's end step, ").toString(); + return sb.insert(0, generateConditionString()).insert(0, abilityWordRule + "At the beginning of each opponent's end step, ").toString(); case ANY: - return sb.insert(0, generateConditionString()).insert(0, "At the beginning of each end step, ").toString(); + return sb.insert(0, generateConditionString()).insert(0, abilityWordRule + "At the beginning of each end step, ").toString(); case CONTROLLER_ATTACHED_TO: - return sb.insert(0, generateConditionString()).insert(0, "At the beginning of the end step of enchanted creature's controller, ").toString(); + return sb.insert(0, generateConditionString()).insert(0, abilityWordRule + "At the beginning of the end step of enchanted creature's controller, ").toString(); } return ""; } diff --git a/Mage/src/main/java/mage/abilities/condition/common/DeliriumCondition.java b/Mage/src/main/java/mage/abilities/condition/common/DeliriumCondition.java index 0740f26ad2d..f555dacc3cb 100644 --- a/Mage/src/main/java/mage/abilities/condition/common/DeliriumCondition.java +++ b/Mage/src/main/java/mage/abilities/condition/common/DeliriumCondition.java @@ -61,4 +61,10 @@ public class DeliriumCondition implements Condition { } return false; } + + @Override + public String toString() { + return "if there are four or more card types among cards in your graveyard"; + } + } diff --git a/Mage/src/main/java/mage/abilities/effects/common/TransformSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/TransformSourceEffect.java index 892fb7399bb..72bc6b69359 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/TransformSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/TransformSourceEffect.java @@ -24,13 +24,12 @@ * 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.abilities.Ability; import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; import mage.game.Game; import mage.game.permanent.Permanent; @@ -44,7 +43,8 @@ public class TransformSourceEffect extends OneShotEffect { private boolean fromDayToNight; /** - * @param fromDayToNight Defines whether we transform from "day" side to "night" or vice versa. + * @param fromDayToNight Defines whether we transform from "day" side to + * "night" or vice versa. */ public TransformSourceEffect(boolean fromDayToNight) { this(fromDayToNight, false); @@ -75,20 +75,21 @@ public class TransformSourceEffect extends OneShotEffect { if (permanent.canTransform()) { // check not to transform twice the same side if (permanent.isTransformed() != fromDayToNight) { - if (withoutTrigger) { + if (withoutTrigger) { permanent.setTransformed(fromDayToNight); } else { permanent.transform(game); } if (!game.isSimulation()) { if (fromDayToNight) { - game.informPlayers(new StringBuilder(permanent.getName()).append(" transforms into ").append(permanent.getSecondCardFace().getName()).toString()); + game.informPlayers(permanent.getIdName() + " transforms into " + permanent.getSecondCardFace().getIdName()); } else { - game.informPlayers(new StringBuilder(permanent.getSecondCardFace().getName()).append(" transforms into ").append(permanent.getName()).toString()); + game.informPlayers(permanent.getSecondCardFace().getIdName() + " transforms into " + permanent.getIdName()); } } } } + return true; } return false;