diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfCruelty.java b/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfCruelty.java index 49cd01066b..9823a3a6f8 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfCruelty.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfCruelty.java @@ -31,7 +31,7 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.condition.common.ControlsBiggestOrTiedCreatureCondition; +import mage.abilities.condition.common.ControlsCreatureGreatestPowerCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.cards.CardImpl; @@ -59,7 +59,7 @@ public class TriumphOfCruelty extends CardImpl { TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new DiscardTargetEffect(1), TargetController.YOU, false); Target target = new TargetOpponent(); ability.addTarget(target); - this.addAbility(new ConditionalTriggeredAbility(ability, ControlsBiggestOrTiedCreatureCondition.getInstance(), ruleText)); + this.addAbility(new ConditionalTriggeredAbility(ability, ControlsCreatureGreatestPowerCondition.getInstance(), ruleText)); } public TriumphOfCruelty(final TriumphOfCruelty card) { diff --git a/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfFerocity.java b/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfFerocity.java index 1c208120f7..f0aff0368b 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfFerocity.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/TriumphOfFerocity.java @@ -31,7 +31,7 @@ import mage.constants.CardType; import mage.constants.Rarity; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; -import mage.abilities.condition.common.ControlsBiggestOrTiedCreatureCondition; +import mage.abilities.condition.common.ControlsCreatureGreatestPowerCondition; import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; @@ -54,7 +54,7 @@ public class TriumphOfFerocity extends CardImpl { // At the beginning of your upkeep, draw a card if you control the creature with the greatest power or tied for the greatest power. TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.YOU, false); - this.addAbility(new ConditionalTriggeredAbility(ability, ControlsBiggestOrTiedCreatureCondition.getInstance(), ruleText)); + this.addAbility(new ConditionalTriggeredAbility(ability, ControlsCreatureGreatestPowerCondition.getInstance(), ruleText)); } public TriumphOfFerocity(final TriumphOfFerocity card) { diff --git a/Mage.Sets/src/mage/sets/commander/GhaveGuruOfSpores.java b/Mage.Sets/src/mage/sets/commander/GhaveGuruOfSpores.java index 97629e8eb5..d00a61da14 100644 --- a/Mage.Sets/src/mage/sets/commander/GhaveGuruOfSpores.java +++ b/Mage.Sets/src/mage/sets/commander/GhaveGuruOfSpores.java @@ -39,11 +39,12 @@ import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Rarity; import mage.constants.Zone; -import mage.cards.CardImpl; import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.permanent.token.SaprolingToken; @@ -81,7 +82,7 @@ public class GhaveGuruOfSpores extends CardImpl { // {1}, Remove a +1/+1 counter from a creature you control: Put a 1/1 green Saproling creature token onto the battlefield. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken()), new GenericManaCost(1)); - ability.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(), CounterType.P1P1)); + ability.addCost(new RemoveCounterCost(new TargetControlledCreaturePermanent(1,1, new FilterControlledCreaturePermanent(), true), CounterType.P1P1)); this.addAbility(ability); // {1}, Sacrifice a creature: Put a +1/+1 counter on target creature. diff --git a/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java b/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java index badc985d95..9f38b96452 100644 --- a/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java +++ b/Mage.Sets/src/mage/sets/commander/RikuOfTwoReflections.java @@ -161,18 +161,13 @@ class RikuOfTwoReflectionsCopyTokenEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source)); - if (permanent == null) { - permanent = (Permanent) game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD); - } - + Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); if (permanent != null) { EmptyToken token = new EmptyToken(); CardUtil.copyTo(token).from(permanent); token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); return true; } - return false; } } diff --git a/Mage.Sets/src/mage/sets/exodus/Bequeathal.java b/Mage.Sets/src/mage/sets/exodus/Bequeathal.java new file mode 100644 index 0000000000..2f695dd97f --- /dev/null +++ b/Mage.Sets/src/mage/sets/exodus/Bequeathal.java @@ -0,0 +1,73 @@ +/* + * 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.exodus; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class Bequeathal extends CardImpl { + + public Bequeathal(UUID ownerId) { + super(ownerId, 106, "Bequeathal", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{G}"); + this.expansionSetCode = "EXO"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.DrawCard)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When enchanted creature dies, you draw two cards. + this.addAbility( new DiesAttachedTriggeredAbility(new DrawCardSourceControllerEffect(2), "enchanted creature")); + } + + public Bequeathal(final Bequeathal card) { + super(card); + } + + @Override + public Bequeathal copy() { + return new Bequeathal(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/AbzanBeastmaster.java b/Mage.Sets/src/mage/sets/fatereforged/AbzanBeastmaster.java new file mode 100644 index 0000000000..874004d998 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/AbzanBeastmaster.java @@ -0,0 +1,71 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.condition.common.ControlsCreatureGreatestToughnessCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; + +/** + * + * @author LevelX2 + */ +public class AbzanBeastmaster extends CardImpl { + + public AbzanBeastmaster(UUID ownerId) { + super(ownerId, 119, "Abzan Beastmaster", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Hound"); + this.subtype.add("Shaman"); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness. + this.addAbility(new ConditionalTriggeredAbility( + new BeginningOfUpkeepTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.YOU, false), + ControlsCreatureGreatestToughnessCondition.getInstance(), + "At the beginning of your upkeep, draw a card if you control the creature with the greatest toughness or tied for the greatest toughness." + )); + } + + public AbzanBeastmaster(final AbzanBeastmaster card) { + super(card); + } + + @Override + public AbzanBeastmaster copy() { + return new AbzanBeastmaster(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/AinokGuide.java b/Mage.Sets/src/mage/sets/fatereforged/AinokGuide.java new file mode 100644 index 0000000000..bbd7bb1f34 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/AinokGuide.java @@ -0,0 +1,78 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.search.SearchLibraryPutOnLibraryEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.common.FilterBasicLandCard; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LevelX2 + */ +public class AinokGuide extends CardImpl { + + public AinokGuide(UUID ownerId) { + super(ownerId, 121, "Ainok Guide", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Hound"); + this.subtype.add("Scout"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Ainok Guide enters the battlefield, choose one - + // * Put a +1/+1 counter on Ainok Guide. + Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())); + + // * Search your library for a basic land card, reveal it, then shuffle your library and put that card on top of it. + Mode mode = new Mode(); + mode.getEffects().add(new SearchLibraryPutOnLibraryEffect(new TargetCardInLibrary(new FilterBasicLandCard()), true, true)); + ability.addMode(mode); + this.addAbility(ability); + + } + + public AinokGuide(final AinokGuide card) { + super(card); + } + + @Override + public AinokGuide copy() { + return new AinokGuide(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/AmbushKrotiq.java b/Mage.Sets/src/mage/sets/fatereforged/AmbushKrotiq.java new file mode 100644 index 0000000000..f033aa6cef --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/AmbushKrotiq.java @@ -0,0 +1,75 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandChosenControlledPermanentEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author LevelX2 + */ +public class AmbushKrotiq extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another creature you control"); + + static { + filter.add(new AnotherPredicate()); + } + + public AmbushKrotiq(UUID ownerId) { + super(ownerId, 122, "Ambush Krotiq", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{5}{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Insect"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // When Ambush Krotiq enters the battlefield, return another creature you control to its owner's hand. + this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter))); + + } + + public AmbushKrotiq(final AmbushKrotiq card) { + super(card); + } + + @Override + public AmbushKrotiq copy() { + return new AmbushKrotiq(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/AtarkaWorldRender.java b/Mage.Sets/src/mage/sets/fatereforged/AtarkaWorldRender.java new file mode 100644 index 0000000000..1ea9308089 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/AtarkaWorldRender.java @@ -0,0 +1,127 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author jeffwadsworth + */ +public class AtarkaWorldRender extends CardImpl { + + public AtarkaWorldRender(UUID ownerId) { + super(ownerId, 149, "Atarka, World Render", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{R}{G}"); + this.expansionSetCode = "FRF"; + this.supertype.add("Legendary"); + this.subtype.add("Dragon"); + this.power = new MageInt(6); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + + // Whenever a Dragon you control attacks, it gains double strike until end of turn. + this.addAbility(new AtarkaWorldRenderEffect()); + + } + + public AtarkaWorldRender(final AtarkaWorldRender card) { + super(card); + } + + @Override + public AtarkaWorldRender copy() { + return new AtarkaWorldRender(this); + } +} + +class AtarkaWorldRenderEffect extends TriggeredAbilityImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("dragon you control"); + + static { + filter.add(new SubtypePredicate("Dragon")); + } + + public AtarkaWorldRenderEffect() { + super(Zone.BATTLEFIELD, new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn)); + } + + public AtarkaWorldRenderEffect(final AtarkaWorldRenderEffect ability) { + super(ability); + } + + @Override + public AtarkaWorldRenderEffect copy() { + return new AtarkaWorldRenderEffect(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == EventType.ATTACKER_DECLARED) { + Permanent attacker = game.getPermanent(event.getSourceId()); + if (attacker != null + && filter.match(attacker, sourceId, controllerId, game)) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(attacker.getId())); + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a Dragon you control attacks, it gains double strike until end of turn."; + } + +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/BattlefrontKrushok.java b/Mage.Sets/src/mage/sets/fatereforged/BattlefrontKrushok.java new file mode 100644 index 0000000000..3a09ea1388 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/BattlefrontKrushok.java @@ -0,0 +1,77 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneAllEffect; +import mage.abilities.effects.common.combat.CantBeBlockedByMoreThanOneSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.CounterPredicate; + +/** + * + * @author LevelX2 + */ +public class BattlefrontKrushok extends CardImpl { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature you control with a +1/+1 counter on it"); + + static { + filter.add(new CounterPredicate(CounterType.P1P1)); + } + + public BattlefrontKrushok(UUID ownerId) { + super(ownerId, 125, "Battlefront Krushok", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Beast"); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Battlefront Krushok can't be blocked by more than one creature. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByMoreThanOneSourceEffect())); + + // Each creature you control with a +1/+1 counter on it can't be blocked by more than one creature. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByMoreThanOneAllEffect(filter))); + } + + public BattlefrontKrushok(final BattlefrontKrushok card) { + super(card); + } + + @Override + public BattlefrontKrushok copy() { + return new BattlefrontKrushok(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/BrutalHordechief.java b/Mage.Sets/src/mage/sets/fatereforged/BrutalHordechief.java new file mode 100644 index 0000000000..4d1f6ffbf2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/BrutalHordechief.java @@ -0,0 +1,171 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.abilities.effects.common.LoseLifeTargetEffect; +import mage.abilities.effects.common.combat.BlocksIfAbleAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class BrutalHordechief extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creature your opponents control"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public BrutalHordechief(UUID ownerId) { + super(ownerId, 64, "Brutal Hordechief", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{3}{B}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Orc"); + this.subtype.add("Warrior"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever a creature you control attacks, defending player loses 1 life and you gain 1 life. + this.addAbility(new BrutalHordechiefTriggeredAbility()); + + // {3}{R/W}{R/W}: Creatures your opponents control block this turn if able, and you choose how those creatures block. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BlocksIfAbleAllEffect(filter), new ManaCostsImpl("{3}{R/W}{R/W}")); + ability.addEffect(new BrutalHordechiefReplacementEffect()); + this.addAbility(ability); + } + + public BrutalHordechief(final BrutalHordechief card) { + super(card); + } + + @Override + public BrutalHordechief copy() { + return new BrutalHordechief(this); + } +} + +class BrutalHordechiefTriggeredAbility extends TriggeredAbilityImpl { + + public BrutalHordechiefTriggeredAbility() { + super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1)); + this.addEffect(new GainLifeEffect(1)); + } + + public BrutalHordechiefTriggeredAbility(final BrutalHordechiefTriggeredAbility ability) { + super(ability); + } + + @Override + public BrutalHordechiefTriggeredAbility copy() { + return new BrutalHordechiefTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) { + Permanent source = game.getPermanent(event.getSourceId()); + if (source != null && source.getControllerId().equals(controllerId)) { + UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game); + this.getEffects().get(0).setTargetPointer(new FixedTarget(defendingPlayerId)); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a creature you control attacks, defending player loses 1 life and you gain 1 life."; + } +} + +class BrutalHordechiefReplacementEffect extends ReplacementEffectImpl { + + public BrutalHordechiefReplacementEffect() { + super(Duration.EndOfCombat, Outcome.Benefit); + staticText = ", and you choose how those creatures block"; + } + + public BrutalHordechiefReplacementEffect(final BrutalHordechiefReplacementEffect effect) { + super(effect); + } + + @Override + public BrutalHordechiefReplacementEffect copy() { + return new BrutalHordechiefReplacementEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player blockController = game.getPlayer(source.getControllerId()); + if (blockController != null) { + game.getCombat().selectBlockers(blockController, game); + return true; + } + return false; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARING_BLOCKERS; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + Player player = game.getPlayer(event.getPlayerId()); + return player != null && game.isOpponent(player, source.getControllerId()); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/fatereforged/CachedDefenses.java b/Mage.Sets/src/mage/sets/fatereforged/CachedDefenses.java new file mode 100644 index 0000000000..ddc670938f --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/CachedDefenses.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.sets.fatereforged; + +import java.util.UUID; +import mage.abilities.effects.keyword.BolsterEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class CachedDefenses extends CardImpl { + + public CachedDefenses(UUID ownerId) { + super(ownerId, 126, "Cached Defenses", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{2}{G}"); + this.expansionSetCode = "FRF"; + + // Bolster 3. + this.getSpellAbility().addEffect(new BolsterEffect(3)); + } + + public CachedDefenses(final CachedDefenses card) { + super(card); + } + + @Override + public CachedDefenses copy() { + return new CachedDefenses(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/CrucibleOfTheSpiritDragon.java b/Mage.Sets/src/mage/sets/fatereforged/CrucibleOfTheSpiritDragon.java new file mode 100644 index 0000000000..6a065ebd93 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/CrucibleOfTheSpiritDragon.java @@ -0,0 +1,123 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.ConditionalMana; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.RemoveVariableCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.dynamicvalue.common.RemovedCountersForCostValue; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.mana.ColorlessManaAbility; +import mage.abilities.mana.ConditionalAnyColorManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; + +/** + * + * @author LevelX2 + */ +public class CrucibleOfTheSpiritDragon extends CardImpl { + + public CrucibleOfTheSpiritDragon(UUID ownerId) { + super(ownerId, 167, "Crucible of the Spirit Dragon", Rarity.RARE, new CardType[]{CardType.LAND}, ""); + this.expansionSetCode = "FRF"; + + // {T}: Add {1} to your mana pool. + this.addAbility(new ColorlessManaAbility()); + + // {1}, {T}: Put a storage counter on Crucible of the Spirit Dragon. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.STORAGE.createInstance()),new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + // {T}, Remove X storage counters from Crucible of the Spirit Dragon: Add X mana in any combination of colors to your mana pool. Spend this mana only to cast Dragon spells or activate abilities of Dragons. + ability = new ConditionalAnyColorManaAbility( + new TapSourceCost(), + new RemovedCountersForCostValue(), + new CrucibleOfTheSpiritDragonManaBuilder(), + false + ); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance())); + this.addAbility(ability); + } + + public CrucibleOfTheSpiritDragon(final CrucibleOfTheSpiritDragon card) { + super(card); + } + + @Override + public CrucibleOfTheSpiritDragon copy() { + return new CrucibleOfTheSpiritDragon(this); + } +} + +class CrucibleOfTheSpiritDragonManaBuilder extends ConditionalManaBuilder { + + @Override + public ConditionalMana build(Object... options) { + return new CrucibleOfTheSpiritDragonConditionalMana(this.mana); + } + + @Override + public String getRule() { + return "Spend this mana only to cast Dragon spells or activate abilities of Dragons"; + } +} + +class CrucibleOfTheSpiritDragonConditionalMana extends ConditionalMana { + + public CrucibleOfTheSpiritDragonConditionalMana(Mana mana) { + super(mana); + this.staticText = "Spend this mana only to cast Dragon spells or activate abilities of Dragons"; + addCondition(new CrucibleOfTheSpiritDragonManaCondition()); + } +} + +class CrucibleOfTheSpiritDragonManaCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + MageObject object = game.getObject(source.getSourceId()); + if (object != null && object.hasSubtype("Dragon")) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/fatereforged/CunningStrike.java b/Mage.Sets/src/mage/sets/fatereforged/CunningStrike.java index 096ff883d6..414925bbb8 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/CunningStrike.java +++ b/Mage.Sets/src/mage/sets/fatereforged/CunningStrike.java @@ -49,10 +49,10 @@ public class CunningStrike extends CardImpl { this.expansionSetCode = "FRF"; // Cunning Strike deals 2 damage to target creature and 2 damage to target player. - this.getSpellAbility().addEffect(new DamageTargetEffect(1)); + this.getSpellAbility().addEffect(new DamageTargetEffect(2)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - Effect effect = new DamageTargetEffect(1); + Effect effect = new DamageTargetEffect(2); effect.setTargetPointer(new SecondTargetPointer()); effect.setText("and 2 damage to target player"); this.getSpellAbility().addEffect(effect); diff --git a/Mage.Sets/src/mage/sets/fatereforged/FormlessNurturing.java b/Mage.Sets/src/mage/sets/fatereforged/FormlessNurturing.java new file mode 100644 index 0000000000..0d38c747c2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/FormlessNurturing.java @@ -0,0 +1,101 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.keyword.ManifestEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class FormlessNurturing extends CardImpl { + + public FormlessNurturing(UUID ownerId) { + super(ownerId, 129, "Formless Nurturing", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{3}{G}"); + this.expansionSetCode = "FRF"; + + // Manifest the top card of your library, then put a +1/+1 counter on it. + this.getSpellAbility().addEffect(new FormlessNurturingEffect()); + } + + public FormlessNurturing(final FormlessNurturing card) { + super(card); + } + + @Override + public FormlessNurturing copy() { + return new FormlessNurturing(this); + } +} + +class FormlessNurturingEffect extends OneShotEffect { + + public FormlessNurturingEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Manifest the top card of your library, then put a +1/+1 counter on it"; + } + + public FormlessNurturingEffect(final FormlessNurturingEffect effect) { + super(effect); + } + + @Override + public FormlessNurturingEffect copy() { + return new FormlessNurturingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + new ManifestEffect(1).apply(game, source); + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance()); + effect.setTargetPointer(new FixedTarget(card.getId())); + return effect.apply(game, source); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/FruitOfTheFirstTree.java b/Mage.Sets/src/mage/sets/fatereforged/FruitOfTheFirstTree.java new file mode 100644 index 0000000000..b88d13a88e --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/FruitOfTheFirstTree.java @@ -0,0 +1,114 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import static javax.xml.bind.JAXBIntrospector.getValue; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.DiesAttachedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class FruitOfTheFirstTree extends CardImpl { + + public FruitOfTheFirstTree(UUID ownerId) { + super(ownerId, 132, "Fruit of the First Tree", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When enchanted creature dies, you gain X life and draw X cards, where X is its toughness. + this.addAbility( new DiesAttachedTriggeredAbility(new FruitOfTheFirstTreeEffect(), "enchanted creature")); + } + + public FruitOfTheFirstTree(final FruitOfTheFirstTree card) { + super(card); + } + + @Override + public FruitOfTheFirstTree copy() { + return new FruitOfTheFirstTree(this); + } +} + +class FruitOfTheFirstTreeEffect extends OneShotEffect { + + public FruitOfTheFirstTreeEffect() { + super(Outcome.Benefit); + } + + public FruitOfTheFirstTreeEffect(FruitOfTheFirstTreeEffect copy) { + super(copy); + } + + @Override + public FruitOfTheFirstTreeEffect copy() { + return new FruitOfTheFirstTreeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent creature = (Permanent) getValue("attachedTo"); + if (creature != null){ + Player controller = game.getPlayer(creature.getOwnerId()); + if (controller != null) { + controller.gainLife(creature.getToughness().getValue(), game); + controller.drawCards(creature.getToughness().getValue(), game); + return true; + } + } + return false; + } + + @Override + public String getText(Mode mode) { + return "you gain X life and draw X cards, where X is its toughness"; + } + +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/GoblinBoomKeg.java b/Mage.Sets/src/mage/sets/fatereforged/GoblinBoomKeg.java new file mode 100644 index 0000000000..2aa3279ba8 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/GoblinBoomKeg.java @@ -0,0 +1,72 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.PutIntoGraveFromBattlefieldSourceTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.SacrificeSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LevelX2 + */ +public class GoblinBoomKeg extends CardImpl { + + public GoblinBoomKeg(UUID ownerId) { + super(ownerId, 159, "Goblin Boom Keg", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{4}"); + this.expansionSetCode = "FRF"; + + // At the beginning of your upkeep, sacrifice Goblin Boom Keg. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceEffect(), TargetController.YOU, false)); + + // When Goblin Boom Keg is put into a graveyard from the battlefield, it deals 3 damage to target creature or player. + Effect effect = new DamageTargetEffect(3); + effect.setText("it deals 3 damage to target creature or player"); + Ability ability = new PutIntoGraveFromBattlefieldSourceTriggeredAbility(effect, false); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + } + + public GoblinBoomKeg(final GoblinBoomKeg card) { + super(card); + } + + @Override + public GoblinBoomKeg copy() { + return new GoblinBoomKeg(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/GrimContest.java b/Mage.Sets/src/mage/sets/fatereforged/GrimContest.java new file mode 100644 index 0000000000..39838df5c9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/GrimContest.java @@ -0,0 +1,112 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class GrimContest extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature an opponent controls"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public GrimContest(UUID ownerId) { + super(ownerId, 153, "Grim Contest", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{B}{G}"); + this.expansionSetCode = "FRF"; + + // Choose target creature you control and target creature an opponent controls. Each of those creatures deals damage equal to its toughness to the other. + this.getSpellAbility().addEffect(new GrimContestEffect()); + this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + } + + public GrimContest(final GrimContest card) { + super(card); + } + + @Override + public GrimContest copy() { + return new GrimContest(this); + } +} + +class GrimContestEffect extends OneShotEffect { + + public GrimContestEffect() { + super(Outcome.Damage); + this.staticText = "Choose target creature you control and target creature an opponent controls. Each of those creatures deals damage equal to its toughness to the other"; + } + + public GrimContestEffect(final GrimContestEffect effect) { + super(effect); + } + + @Override + public GrimContestEffect copy() { + return new GrimContestEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent creature1 = game.getPermanent(getTargetPointer().getFirst(game, source)); + Permanent creature2 = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (creature1 != null && creature2 != null) { + if (creature1.getCardType().contains(CardType.CREATURE) && creature2.getCardType().contains(CardType.CREATURE)) { + creature1.damage(creature2.getToughness().getValue(), creature2.getId(), game, false, true); + game.informPlayers(creature2.getLogName() + " deals " + creature2.getToughness().getValue() + " damage to " + creature1.getLogName()); + creature2.damage(creature1.getToughness().getValue(), creature1.getId(), game, false, true); + game.informPlayers(creature1.getLogName() + " deals " + creature1.getToughness().getValue() + " damage to " + creature2.getLogName()); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/HarshSustenance.java b/Mage.Sets/src/mage/sets/fatereforged/HarshSustenance.java new file mode 100644 index 0000000000..fb7efe6988 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/HarshSustenance.java @@ -0,0 +1,71 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.GainLifeEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author LevelX2 + */ +public class HarshSustenance extends CardImpl { + + public HarshSustenance(UUID ownerId) { + super(ownerId, 154, "Harsh Sustenance", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{W}{B}"); + this.expansionSetCode = "FRF"; + + // Harsh Sustenance deals X damage to target creature or player and you gain X life, where X is the number of creatures you control. + DynamicValue xValue = new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent()); + Effect effect = new DamageTargetEffect(xValue); + effect.setText("{this} deals X damage to target creature or player"); + getSpellAbility().addEffect(effect); + getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + effect = new GainLifeEffect(xValue); + effect.setText("and you gain X life, where X is the number of creatures you control"); + getSpellAbility().addEffect(effect); + } + + public HarshSustenance(final HarshSustenance card) { + super(card); + } + + @Override + public HarshSustenance copy() { + return new HarshSustenance(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/HerosBlade.java b/Mage.Sets/src/mage/sets/fatereforged/HerosBlade.java new file mode 100644 index 0000000000..a886fb95c2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/HerosBlade.java @@ -0,0 +1,87 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continious.BoostEquippedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SupertypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LevelX2 + */ +public class HerosBlade extends CardImpl { + + private static final FilterPermanent filter = new FilterCreaturePermanent("a legendary creature"); + + static { + filter.add(new SupertypePredicate("Legendary")); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public HerosBlade(UUID ownerId) { + super(ownerId, 160, "Hero's Blade", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Equipment"); + + // Equipped creature gets +3/+2. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(3, 2))); + + // Whenever a legendary creature enters the battlefield under your control, you may attach Hero's Blade to it. + this.addAbility(new EntersBattlefieldAllTriggeredAbility( + Zone.BATTLEFIELD, new AttachEffect(Outcome.Detriment, "attach {source} to it"), + filter, true, SetTargetPointer.PERMANENT, null, true)); + + // Equip {4} + this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(4))); + } + + public HerosBlade(final HerosBlade card) { + super(card); + } + + @Override + public HerosBlade copy() { + return new HerosBlade(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/MarduWoeReaper.java b/Mage.Sets/src/mage/sets/fatereforged/MarduWoeReaper.java index 4fb4190912..90b39e2add 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/MarduWoeReaper.java +++ b/Mage.Sets/src/mage/sets/fatereforged/MarduWoeReaper.java @@ -94,7 +94,7 @@ class MarduWoeReaperTriggeredAbility extends TriggeredAbilityImpl { public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD && event.getPlayerId().equals(this.getControllerId())) { Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent != null && (permanent.getId() == event.getSourceId() || permanent.getSubtype().contains("Warrior"))) { + if (permanent != null && (permanent.getId() == this.getSourceId() || permanent.getSubtype().contains("Warrior"))) { return true; } } diff --git a/Mage.Sets/src/mage/sets/fatereforged/MonasteryMentor.java b/Mage.Sets/src/mage/sets/fatereforged/MonasteryMentor.java index af9b3ca8f4..e30f0ac876 100644 --- a/Mage.Sets/src/mage/sets/fatereforged/MonasteryMentor.java +++ b/Mage.Sets/src/mage/sets/fatereforged/MonasteryMentor.java @@ -79,7 +79,7 @@ public class MonasteryMentor extends CardImpl { MonasteryMentorToken() { super("Monk", "1/1 white Monk creature token with prowess"); cardType.add(CardType.CREATURE); - color.setBlack(true); + color.setWhite(true); subtype.add("Monk"); power = new MageInt(1); toughness = new MageInt(1); diff --git a/Mage.Sets/src/mage/sets/fatereforged/OjutaiSoulOfWinter.java b/Mage.Sets/src/mage/sets/fatereforged/OjutaiSoulOfWinter.java new file mode 100644 index 0000000000..ee0b842c36 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/OjutaiSoulOfWinter.java @@ -0,0 +1,92 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAllTriggeredAbility; +import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class OjutaiSoulOfWinter extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dragon you control"); + private static final FilterCreaturePermanent filterPermanent = new FilterCreaturePermanent("permanent an opponent controls"); + + static { + filter.add(new SubtypePredicate("Dragon")); + filter.add(new ControllerPredicate(TargetController.YOU)); + filterPermanent.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public OjutaiSoulOfWinter(UUID ownerId) { + super(ownerId, 156, "Ojutai, Soul of Winter", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{W}{U}"); + this.expansionSetCode = "FRF"; + this.supertype.add("Legendary"); + this.subtype.add("Dragon"); + this.power = new MageInt(5); + this.toughness = new MageInt(6); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + // Whenever a Dragon you control attacks, tap target nonland permanent an opponent controls. That permanent doesn't untap during its controller's next untap step. + Ability ability = new AttacksAllTriggeredAbility( + new TapTargetEffect(), + false, filter, SetTargetPointer.NONE, false); + ability.addEffect(new DontUntapInControllersNextUntapStepTargetEffect("That permanent")); + ability.addTarget(new TargetPermanent(filterPermanent)); + this.addAbility(ability); + } + + public OjutaiSoulOfWinter(final OjutaiSoulOfWinter card) { + super(card); + } + + @Override + public OjutaiSoulOfWinter copy() { + return new OjutaiSoulOfWinter(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/RealityShift.java b/Mage.Sets/src/mage/sets/fatereforged/RealityShift.java new file mode 100644 index 0000000000..2f70b19294 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/RealityShift.java @@ -0,0 +1,98 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.keyword.ManifestTargetPlayerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class RealityShift extends CardImpl { + + public RealityShift(UUID ownerId) { + super(ownerId, 46, "Reality Shift", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); + this.expansionSetCode = "FRF"; + + // Exile target creature. Its controller manifests the top card of his or her library. + this.getSpellAbility().addEffect(new ExileTargetEffect()); + this.getSpellAbility().addEffect(new RealityShiftEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + } + + public RealityShift(final RealityShift card) { + super(card); + } + + @Override + public RealityShift copy() { + return new RealityShift(this); + } +} + +class RealityShiftEffect extends OneShotEffect { + + public RealityShiftEffect() { + super(Outcome.Exile); + this.staticText = "Its controller manifests the top card of his or her library. (That player puts the top card of his or her library onto the battlefield face down as a 2/2 creature. If it's a creature card, it can be turned face up any time for its mana cost.)"; + } + + public RealityShiftEffect(final RealityShiftEffect effect) { + super(effect); + } + + @Override + public RealityShiftEffect copy() { + return new RealityShiftEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetCreature = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); + if (targetCreature != null) { + Effect effect = new ManifestTargetPlayerEffect(1, "Its controller"); + effect.setTargetPointer(new FixedTarget(targetCreature.getControllerId())); + return effect.apply(game, source); + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/RenownedWeaponsmith.java b/Mage.Sets/src/mage/sets/fatereforged/RenownedWeaponsmith.java new file mode 100644 index 0000000000..e25692eac7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/RenownedWeaponsmith.java @@ -0,0 +1,166 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.ConditionalMana; +import mage.MageInt; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.mana.ConditionalColorlessManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +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.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author jeffwadsworth + */ +public class RenownedWeaponsmith extends CardImpl { + + public RenownedWeaponsmith(UUID ownerId) { + super(ownerId, 48, "Renowned Weaponsmith", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{U}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Human"); + this.subtype.add("Artificer"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // {t}: Add {2} to your mana pool. Spend this mana only to cast artifact spells or activate abilities of artifacts. + this.addAbility(new ConditionalColorlessManaAbility(new TapSourceCost(), 2, new RenownedWeaponsmithManaBuilder())); + + // {U}, {T}: Search your library for a card named Heart-Piercer Bow or Vial of Dragonfire, reveal it, put it into your hand, then shuffle your library. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RenownedWeaponsmithEffect(), new ManaCostsImpl("{U")); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + } + + public RenownedWeaponsmith(final RenownedWeaponsmith card) { + super(card); + } + + @Override + public RenownedWeaponsmith copy() { + return new RenownedWeaponsmith(this); + } +} + +class RenownedWeaponsmithManaBuilder extends ConditionalManaBuilder { + + @Override + public ConditionalMana build(Object... options) { + return new RenownedWeaponsmithConditionalMana(this.mana); + } + + @Override + public String getRule() { + return "Spend this mana only to cast artifact spells or activate abilities of artifacts"; + } +} + +class RenownedWeaponsmithConditionalMana extends ConditionalMana { + + public RenownedWeaponsmithConditionalMana(Mana mana) { + super(mana); + addCondition(new RenownedWeaponsmithCondition()); + } +} + +class RenownedWeaponsmithCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + MageObject object = game.getObject(source.getSourceId()); + return (object != null + && object.getCardType().contains(CardType.ARTIFACT)); + } +} + +class RenownedWeaponsmithEffect extends OneShotEffect { + + private static final FilterCard filter = new FilterCard("card named Heart-Piercer Vial of Dragonfire"); + + static { + filter.add(Predicates.or(new NamePredicate("Heart-Piercer Bow"), + new NamePredicate("Vial of Dragonfire"))); + } + + public RenownedWeaponsmithEffect() { + super(Outcome.DrawCard); + staticText = "Search your library for a card named Heart-Piercer Bow or Vial of Dragonfire, reveal it, put it into your hand, then shuffle your library"; + } + + public RenownedWeaponsmithEffect(final RenownedWeaponsmithEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null && controller != null) { + TargetCardInLibrary target = new TargetCardInLibrary(filter); + if (controller.searchLibrary(target, game)) { + if (target.getTargets().size() > 0) { + Card card = game.getCard(target.getFirstTarget()); + Cards revealed = new CardsImpl(); + revealed.add(card); + controller.revealCards(sourceObject.getLogName(), revealed, game); + controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.LIBRARY); + } + } + controller.shuffleLibrary(game); + return true; + } + return false; + } + + @Override + public RenownedWeaponsmithEffect copy() { + return new RenownedWeaponsmithEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/ReturnToTheEarth.java b/Mage.Sets/src/mage/sets/fatereforged/ReturnToTheEarth.java new file mode 100644 index 0000000000..4aa9f3d084 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/ReturnToTheEarth.java @@ -0,0 +1,78 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.AbilityPredicate; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class ReturnToTheEarth extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("artifact, enchantment, or creature with flying"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.ENCHANTMENT), + Predicates.and( + new CardTypePredicate(CardType.CREATURE), + new AbilityPredicate(FlyingAbility.class)) + )); + } + + public ReturnToTheEarth(UUID ownerId) { + super(ownerId, 135, "Return to the Earth", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{G}"); + this.expansionSetCode = "FRF"; + + // Destroy target artifact, enchantment, or creature with flying. + this.getSpellAbility().addEffect(new DestroyTargetEffect()); + this.getSpellAbility().addTarget(new TargetPermanent(filter)); + + } + + public ReturnToTheEarth(final ReturnToTheEarth card) { + super(card); + } + + @Override + public ReturnToTheEarth copy() { + return new ReturnToTheEarth(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/RuthlessInstincts.java b/Mage.Sets/src/mage/sets/fatereforged/RuthlessInstincts.java new file mode 100644 index 0000000000..a619d2abd3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/RuthlessInstincts.java @@ -0,0 +1,100 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Mode; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.UntapTargetEffect; +import mage.abilities.effects.common.continious.BoostTargetEffect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.keyword.DeathtouchAbility; +import mage.abilities.keyword.ReachAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class RuthlessInstincts extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonattacking creature"); + private static final FilterCreaturePermanent filterAttacking = new FilterCreaturePermanent("attacking creature"); + + static { + filter.add(Predicates.not(new AttackingPredicate())); + filterAttacking.add(new AttackingPredicate()); + } + + public RuthlessInstincts(UUID ownerId) { + super(ownerId, 136, "Ruthless Instincts", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{G}"); + this.expansionSetCode = "FRF"; + + // Choose one - + // * Target nonattacking creature gains reach and deathtouch until end of turn. Untap it. + Effect effect = new GainAbilityTargetEffect(ReachAbility.getInstance(), Duration.EndOfTurn); + effect.setText("Target nonattacking creature gains reach"); + this.getSpellAbility().addEffect(effect); + effect = new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and deathtouch until end of turn"); + this.getSpellAbility().addEffect(effect); + effect = new UntapTargetEffect(); + effect.setText("Untap it"); + this.getSpellAbility().addEffect(effect); + Target target = new TargetCreaturePermanent(filter); + this.getSpellAbility().addTarget(target); + // * Target attacking creature gets +2/+2 and gains trample until end of turn. + Mode mode = new Mode(); + effect = new BoostTargetEffect(2,2,Duration.EndOfTurn); + effect.setText("Target attacking creature gets +2/+2"); + mode.getEffects().add(effect); + effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setText("and gains trample until end of turn"); + mode.getEffects().add(effect); + mode.getTargets().add(new TargetCreaturePermanent(filterAttacking)); + this.getSpellAbility().addMode(mode); + } + + public RuthlessInstincts(final RuthlessInstincts card) { + super(card); + } + + @Override + public RuthlessInstincts copy() { + return new RuthlessInstincts(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/SageEyeAvengers.java b/Mage.Sets/src/mage/sets/fatereforged/SageEyeAvengers.java new file mode 100644 index 0000000000..f14d8c67ae --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/SageEyeAvengers.java @@ -0,0 +1,109 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.ProwessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class SageEyeAvengers extends CardImpl { + + public SageEyeAvengers(UUID ownerId) { + super(ownerId, 50, "Sage-Eye Avengers", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{U}{U}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Djinn"); + this.subtype.add("Monk"); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // Prowess + this.addAbility(new ProwessAbility()); + + // Whenever Sage-Eye Avengers attacks, you may return target creature to its owner's hand if its power is less than Sage-Eye Avengers's power. + Ability ability = new AttacksTriggeredAbility(new SageEyeAvengersEffect(), true); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public SageEyeAvengers(final SageEyeAvengers card) { + super(card); + } + + @Override + public SageEyeAvengers copy() { + return new SageEyeAvengers(this); + } +} + +class SageEyeAvengersEffect extends OneShotEffect { + + public SageEyeAvengersEffect() { + super(Outcome.ReturnToHand); + this.staticText = "you may return target creature to its owner's hand if its power is less than {this}'s power"; + } + + public SageEyeAvengersEffect(final SageEyeAvengersEffect effect) { + super(effect); + } + + @Override + public SageEyeAvengersEffect copy() { + return new SageEyeAvengersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null && controller != null) { + Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (targetCreature != null && targetCreature.getPower().getValue() < sourceObject.getPower().getValue()) { + controller.moveCardToHandWithInfo(targetCreature, source.getSourceId(), game, Zone.BATTLEFIELD); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/ScrollOfTheMasters.java b/Mage.Sets/src/mage/sets/fatereforged/ScrollOfTheMasters.java new file mode 100644 index 0000000000..87b72be8d3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/ScrollOfTheMasters.java @@ -0,0 +1,87 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.CountersCount; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class ScrollOfTheMasters extends CardImpl { + + private static final FilterSpell filterNonCreature = new FilterSpell("a noncreature spell"); + + static { + filterNonCreature.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + } + + public ScrollOfTheMasters(UUID ownerId) { + super(ownerId, 163, "Scroll of the Masters", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "FRF"; + + // Whenever you cast a noncreature spell, put a lore counter on Scroll of the Masters. + this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.LORE.createInstance()), filterNonCreature, false)); + + // {3}, {T}: Target creature you control gets +1/+1 until end of turn for each lore counter on Scroll of the Masters. + Ability ability = new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), new CountersCount(CounterType.LORE)), + new ManaCostsImpl("{3}")); + ability.addTarget(new TargetControlledCreaturePermanent()); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + } + + public ScrollOfTheMasters(final ScrollOfTheMasters card) { + super(card); + } + + @Override + public ScrollOfTheMasters copy() { + return new ScrollOfTheMasters(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/ShiftingLoyalties.java b/Mage.Sets/src/mage/sets/fatereforged/ShiftingLoyalties.java new file mode 100644 index 0000000000..be282207e1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/ShiftingLoyalties.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.fatereforged; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.common.continious.ExchangeControlTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.TargetPermanent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class ShiftingLoyalties extends CardImpl { + + public ShiftingLoyalties(UUID ownerId) { + super(ownerId, 51, "Shifting Loyalties", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{5}{U}"); + this.expansionSetCode = "FRF"; + + // Exchange control of two target permanents that share a card type. (Artifact, creature, enchantment, land, and planeswalker are card types.) + this.getSpellAbility().addEffect(new ExchangeControlTargetEffect(Duration.EndOfGame, "Exchange control of two target permanents that share a card type. (Artifact, creature, enchantment, land, and planeswalker are card types.)")); + this.getSpellAbility().addTarget(new TargetpermanentsThatShareCardType()); + + } + + public ShiftingLoyalties(final ShiftingLoyalties card) { + super(card); + } + + @Override + public ShiftingLoyalties copy() { + return new ShiftingLoyalties(this); + } +} + +class TargetpermanentsThatShareCardType extends TargetPermanent { + + public TargetpermanentsThatShareCardType() { + super(2, 2, new FilterPermanent(), false); + targetName = "permanents that share a card type"; + } + + public TargetpermanentsThatShareCardType(final TargetpermanentsThatShareCardType target) { + super(target); + } + + @Override + public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) { + if (super.canTarget(controllerId, id, source, game)) { + if (!getTargets().isEmpty()) { + Permanent targetOne = game.getPermanent(getTargets().get(0)); + Permanent targetTwo = game.getPermanent(id); + if (targetOne == null || targetTwo == null) { + return false; + } + return CardUtil.shareTypes(targetOne, targetTwo); + } + return true; + } + return false; + } + + @Override + public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { + Set cardTypes = new HashSet<>(); + MageObject targetSource = game.getObject(sourceId); + for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) { + if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) { + for (CardType cardType :permanent.getCardType()) { + if (cardTypes.contains(cardType)) { + return true; + } + } + cardTypes.addAll(permanent.getCardType()); + } + } + return false; + } + + @Override + public TargetpermanentsThatShareCardType copy() { + return new TargetpermanentsThatShareCardType(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/ShockmawDragon.java b/Mage.Sets/src/mage/sets/fatereforged/ShockmawDragon.java new file mode 100644 index 0000000000..ee6416c370 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/ShockmawDragon.java @@ -0,0 +1,106 @@ +/* + * 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.fatereforged; + +import java.util.List; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public class ShockmawDragon extends CardImpl { + + public ShockmawDragon(UUID ownerId) { + super(ownerId, 114, "Shockmaw Dragon", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{R}{R}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Dragon"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever Shockmaw Dragon deals combat damage to a player, it deals 1 damage to each creature that player controls. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new ShockmawDragonEffect(), false, true)); + } + + public ShockmawDragon(final ShockmawDragon card) { + super(card); + } + + @Override + public ShockmawDragon copy() { + return new ShockmawDragon(this); + } +} + +class ShockmawDragonEffect extends OneShotEffect { + + public ShockmawDragonEffect() { + super(Outcome.Damage); + staticText = "it deals 1 damage to each creature that player controls"; + } + + public ShockmawDragonEffect(final ShockmawDragonEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if (player != null) { + List creatures = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), player.getId(), game); + for (Permanent creature : creatures) { + if (creature != null) { + creature.damage(1, source.getSourceId(), game, false, true); + } + } + return true; + } + return false; + } + + @Override + public ShockmawDragonEffect copy() { + return new ShockmawDragonEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/ShuYunTheSilentTempest.java b/Mage.Sets/src/mage/sets/fatereforged/ShuYunTheSilentTempest.java new file mode 100644 index 0000000000..3effd5f311 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/ShuYunTheSilentTempest.java @@ -0,0 +1,92 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.ProwessAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class ShuYunTheSilentTempest extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("a noncreature spell"); + + static { + filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); + } + + public ShuYunTheSilentTempest(UUID ownerId) { + super(ownerId, 52, "Shu Yun, the Silent Tempest", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{U}"); + this.expansionSetCode = "FRF"; + this.supertype.add("Legendary"); + this.subtype.add("Human"); + this.subtype.add("Monk"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Prowess + this.addAbility(new ProwessAbility()); + // Whenever you cast a noncreature spell, you may pay {R/W}{R/W}. If you do, target creature gains double strike until end of turn. + Ability ability = new SpellCastControllerTriggeredAbility( + new DoIfCostPaid( + new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn), + new ManaCostsImpl("{R/W}{R/W}"), + "Pay to let target creature gain double strike?"), + filter, false); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + + } + + public ShuYunTheSilentTempest(final ShuYunTheSilentTempest card) { + super(card); + } + + @Override + public ShuYunTheSilentTempest copy() { + return new ShuYunTheSilentTempest(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/SilumgarTheDriftingDeath.java b/Mage.Sets/src/mage/sets/fatereforged/SilumgarTheDriftingDeath.java new file mode 100644 index 0000000000..fb77948903 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/SilumgarTheDriftingDeath.java @@ -0,0 +1,145 @@ +/* + * 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.fatereforged; + +import java.util.Iterator; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.AttacksAllTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.continious.BoostAllEffect; +import mage.abilities.effects.common.continious.BoostControlledEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.HexproofAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.SubLayer; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class SilumgarTheDriftingDeath extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dragon you control"); + + static { + filter.add(new SubtypePredicate("Dragon")); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public SilumgarTheDriftingDeath(UUID ownerId) { + super(ownerId, 157, "Silumgar, the Drifting Death", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{U}{B}"); + this.expansionSetCode = "FRF"; + this.supertype.add("Legendary"); + this.subtype.add("Dragon"); + this.power = new MageInt(3); + this.toughness = new MageInt(7); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Hexproof + this.addAbility(HexproofAbility.getInstance()); + // Whenever a Dragon you control attacks, creatures defending player controls get -1/-1 until end of turn. + this.addAbility( + new AttacksAllTriggeredAbility( + new UnboostCreaturesTargetPlayerEffect(-1, -1), + false, filter, SetTargetPointer.PLAYER, false)); + } + + public SilumgarTheDriftingDeath(final SilumgarTheDriftingDeath card) { + super(card); + } + + @Override + public SilumgarTheDriftingDeath copy() { + return new SilumgarTheDriftingDeath(this); + } +} + + +class UnboostCreaturesTargetPlayerEffect extends ContinuousEffectImpl { + + private final int power; + private final int toughness; + + public UnboostCreaturesTargetPlayerEffect(int power, int toughness) { + super(Duration.EndOfTurn, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature); + this.power = power; + this.toughness = toughness; + staticText = "creatures defending player controls get -1/-1 until end of turn"; + } + + public UnboostCreaturesTargetPlayerEffect(final UnboostCreaturesTargetPlayerEffect effect) { + super(effect); + this.power = effect.power; + this.toughness = effect.toughness; + } + + @Override + public UnboostCreaturesTargetPlayerEffect copy() { + return new UnboostCreaturesTargetPlayerEffect(this); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + if (this.affectedObjectsSet) { + for (Permanent creature : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), getTargetPointer().getFirst(game, source), game)) { + affectedObjectList.add(new MageObjectReference(creature)); + } + } + } + + @Override + public boolean apply(Game game, Ability source) { + for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { + Permanent permanent = it.next().getPermanent(game); + if (permanent != null) { + permanent.addPower(power); + permanent.addToughness(toughness); + } else { + it.remove(); + } + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/fatereforged/SuddenReclamation.java b/Mage.Sets/src/mage/sets/fatereforged/SuddenReclamation.java new file mode 100644 index 0000000000..3d9e62e256 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/SuddenReclamation.java @@ -0,0 +1,114 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.filter.common.FilterLandCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LevelX2 + */ +public class SuddenReclamation extends CardImpl { + + public SuddenReclamation(UUID ownerId) { + super(ownerId, 139, "Sudden Reclamation", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{3}{G}"); + this.expansionSetCode = "FRF"; + + // Put the top four cards of your library into your graveyard, then return a creature card and a land card from your graveyard to your hand. + this.getSpellAbility().addEffect(new PutTopCardOfLibraryIntoGraveControllerEffect(4)); + this.getSpellAbility().addEffect(new SuddenReclamationEffect()); + } + + public SuddenReclamation(final SuddenReclamation card) { + super(card); + } + + @Override + public SuddenReclamation copy() { + return new SuddenReclamation(this); + } +} + +class SuddenReclamationEffect extends OneShotEffect { + + public SuddenReclamationEffect() { + super(Outcome.ReturnToHand); + this.staticText = ", then return a creature card and a land card from your graveyard to your hand"; + } + + public SuddenReclamationEffect(final SuddenReclamationEffect effect) { + super(effect); + } + + @Override + public SuddenReclamationEffect copy() { + return new SuddenReclamationEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Target target = new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard")); + target.setNotTarget(true); + if (target.canChoose(source.getSourceId(), controller.getId(), game) && + controller.chooseTarget(outcome, target, source, game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + } + } + target = new TargetCardInYourGraveyard(new FilterLandCard("land card from your graveyard")); + target.setNotTarget(true); + if (target.canChoose(source.getSourceId(), controller.getId(), game) && + controller.chooseTarget(outcome, target, source, game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/SupplantForm.java b/Mage.Sets/src/mage/sets/fatereforged/SupplantForm.java new file mode 100644 index 0000000000..13914d02aa --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/SupplantForm.java @@ -0,0 +1,97 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.EmptyToken; +import mage.target.common.TargetCreaturePermanent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class SupplantForm extends CardImpl { + + public SupplantForm(UUID ownerId) { + super(ownerId, 54, "Supplant Form", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{4}{U}{U}"); + this.expansionSetCode = "FRF"; + + // Return target creature to its owner's hand. You put a token onto the battlefield that's a copy of that creature. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + this.getSpellAbility().addEffect(new SupplantFormEffect()); + } + + public SupplantForm(final SupplantForm card) { + super(card); + } + + @Override + public SupplantForm copy() { + return new SupplantForm(this); + } +} + +class SupplantFormEffect extends OneShotEffect { + + public SupplantFormEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "You put a token onto the battlefield that's a copy of that creature"; + } + + public SupplantFormEffect(final SupplantFormEffect effect) { + super(effect); + } + + @Override + public SupplantFormEffect copy() { + return new SupplantFormEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetPermanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); + if (targetPermanent != null) { + EmptyToken token = new EmptyToken(); + CardUtil.copyTo(token).from(targetPermanent); + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/TemurBattleRage.java b/Mage.Sets/src/mage/sets/fatereforged/TemurBattleRage.java new file mode 100644 index 0000000000..98fc599d25 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/TemurBattleRage.java @@ -0,0 +1,71 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.condition.common.FerociousCondition; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.keyword.DoubleStrikeAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public class TemurBattleRage extends CardImpl { + + private final static String rule = "
Ferocious — That creature also gains trample until end of turn if you control a creature with power 4 or greater"; + + public TemurBattleRage(UUID ownerId) { + super(ownerId, 116, "Temur Battle Rage", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{R}"); + this.expansionSetCode = "FRF"; + + // Target creature gains double strike until end of turn. + this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent()); + + // Ferocious That creature also gains trample until end of turn if you control a creature with power 4 or greater. + this.getSpellAbility().addEffect(new ConditionalContinousEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), FerociousCondition.getInstance(), rule)); + + } + + public TemurBattleRage(final TemurBattleRage card) { + super(card); + } + + @Override + public TemurBattleRage copy() { + return new TemurBattleRage(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java b/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java new file mode 100644 index 0000000000..4e0ff31bcd --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/TemurSabertooth.java @@ -0,0 +1,121 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.AnotherPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; + +/** + * + * @author LevelX2 + */ +public class TemurSabertooth extends CardImpl { + + public TemurSabertooth(UUID ownerId) { + super(ownerId, 141, "Temur Sabertooth", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Cat"); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // {1}{G}: You may return another creature you control to its owner's hand. If you do, Temur Sabertooth gains indestructible until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TemurSabertoothEffect(), new ManaCostsImpl("{1}{G}"))); + + } + + public TemurSabertooth(final TemurSabertooth card) { + super(card); + } + + @Override + public TemurSabertooth copy() { + return new TemurSabertooth(this); + } +} + +class TemurSabertoothEffect extends OneShotEffect { + + private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another creature you control"); + + static { + filter.add(new AnotherPredicate()); + } + + public TemurSabertoothEffect() { + super(Outcome.Detriment); + this.staticText = "You may return another creature you control to its owner's hand. If you do, {this} gains indestructible until end of turn"; + } + + public TemurSabertoothEffect(final TemurSabertoothEffect effect) { + super(effect); + } + + @Override + public TemurSabertoothEffect copy() { + return new TemurSabertoothEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Target target = new TargetPermanent(1,1, filter, true); + if (target.canChoose(source.getSourceId(), controller.getId(), game)) { + if (controller.chooseUse(outcome, "Return another creature to hand?", game) && + controller.chooseTarget(outcome, target, source, game)) { + Permanent toHand = game.getPermanent(target.getFirstTarget()); + if (toHand != null) { + controller.moveCardToHandWithInfo(toHand, source.getSourceId(), game, Zone.BATTLEFIELD); + } + game.addEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), source); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java b/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java new file mode 100644 index 0000000000..a4bbe3f58f --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/TorrentElemental.java @@ -0,0 +1,175 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SetTargetPointer; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class TorrentElemental extends CardImpl { + + public TorrentElemental(UUID ownerId) { + super(ownerId, 56, "Torrent Elemental", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{4}{U}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Elemental"); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Whenever Torrent Elemental attacks, tap all creatures defending player controls. + this.addAbility(new AttacksTriggeredAbility(new TorrentElementalEffect(), false, null, SetTargetPointer.PLAYER)); + + // {3}{B/G}{B/G}: Put Torrent Elemental from exile onto the battlefield tapped. Activate this ability only any time you could cast a sorcery. + Ability ability = new ActivateAsSorceryActivatedAbility(Zone.EXILED, new ReturnSourceFromExileToBattlefieldEffect(true), new ManaCostsImpl("{3}{B/G}{B/G}")); + this.addAbility(ability); + + } + + public TorrentElemental(final TorrentElemental card) { + super(card); + } + + @Override + public TorrentElemental copy() { + return new TorrentElemental(this); + } +} + +class TorrentElementalEffect extends OneShotEffect { + + public TorrentElementalEffect() { + super(Outcome.Tap); + this.staticText = "tap all creatures defending player controls"; + } + + public TorrentElementalEffect(final TorrentElementalEffect effect) { + super(effect); + } + + @Override + public TorrentElementalEffect copy() { + return new TorrentElementalEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), getTargetPointer().getFirst(game, source), game)) { + permanent.tap(game); + } + return true; + } +} + +class ReturnSourceFromExileToBattlefieldEffect extends OneShotEffect { + + private boolean tapped; + private boolean ownerControl; + + public ReturnSourceFromExileToBattlefieldEffect() { + this(false); + } + + public ReturnSourceFromExileToBattlefieldEffect(boolean tapped) { + super(Outcome.PutCreatureInPlay); + this.tapped = tapped; + setText(); + } + public ReturnSourceFromExileToBattlefieldEffect(boolean tapped, boolean ownerControl) { + super(Outcome.PutCreatureInPlay); + this.tapped = tapped; + this.ownerControl = ownerControl; + setText(); + } + + public ReturnSourceFromExileToBattlefieldEffect(final ReturnSourceFromExileToBattlefieldEffect effect) { + super(effect); + this.tapped = effect.tapped; + this.ownerControl = effect.ownerControl; + } + + @Override + public ReturnSourceFromExileToBattlefieldEffect copy() { + return new ReturnSourceFromExileToBattlefieldEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (!game.getState().getZone(source.getSourceId()).equals(Zone.EXILED)) { + return false; + } + Card card = game.getCard(source.getSourceId()); + if (card == null) { + return false; + } + + Player player; + if (ownerControl) { + player = game.getPlayer(card.getOwnerId()); + } else { + player = game.getPlayer(source.getControllerId()); + } + if (player == null) { + return false; + } + + return player.putOntoBattlefieldWithInfo(card, game, Zone.EXILED, source.getSourceId(), tapped); + } + + private void setText() { + StringBuilder sb = new StringBuilder("Put {this} from exile onto the battlefield"); + if (tapped) { + sb.append(" tapped"); + } + if (ownerControl) { + sb.append(" under its owner's control"); + } + staticText = sb.toString(); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/fatereforged/UginsConstruct.java b/Mage.Sets/src/mage/sets/fatereforged/UginsConstruct.java new file mode 100644 index 0000000000..533e5346c3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/UginsConstruct.java @@ -0,0 +1,73 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.SacrificeControllerEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorlessPredicate; + +/** + * + * @author LevelX2 + */ +public class UginsConstruct extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("permanent that's one or more colors"); + + static { + filter.add(Predicates.not(new ColorlessPredicate())); + } + + public UginsConstruct(UUID ownerId) { + super(ownerId, 164, "Ugin's Construct", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Construct"); + this.power = new MageInt(4); + this.toughness = new MageInt(5); + + // When Ugin's Construct enters the battlefield, sacrifice a permanent that's one or more colors. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SacrificeControllerEffect(filter, 1, null))); + } + + public UginsConstruct(final UginsConstruct card) { + super(card); + } + + @Override + public UginsConstruct copy() { + return new UginsConstruct(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/Vaultbreaker.java b/Mage.Sets/src/mage/sets/fatereforged/Vaultbreaker.java new file mode 100644 index 0000000000..d0e3f58f16 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/Vaultbreaker.java @@ -0,0 +1,104 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.AttacksTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.keyword.DashAbility; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author jeffwadsworth + */ +public class Vaultbreaker extends CardImpl { + + public Vaultbreaker(UUID ownerId) { + super(ownerId, 117, "Vaultbreaker", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{R}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Orc"); + this.subtype.add("Rogue"); + this.power = new MageInt(4); + this.toughness = new MageInt(2); + + // Whenever Vaultbreaker attacks, you may discard a card. If you do, draw a card. + this.addAbility(new AttacksTriggeredAbility(new VaultbreakerEffect(), true)); + + // Dash {2}{R} + this.addAbility(new DashAbility(this, "{2}{R}")); + + } + + public Vaultbreaker(final Vaultbreaker card) { + super(card); + } + + @Override + public Vaultbreaker copy() { + return new Vaultbreaker(this); + } +} + +class VaultbreakerEffect extends OneShotEffect { + + VaultbreakerEffect() { + super(Outcome.Neutral); + staticText = "you may discard a card. If you do, draw a card"; + } + + VaultbreakerEffect(final VaultbreakerEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Cards discardedCard = controller.discard(1, true, source, game); + if (discardedCard != null) { + controller.drawCards(1, game); + return true; + } + } + return false; + } + + @Override + public VaultbreakerEffect copy() { + return new VaultbreakerEffect(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/WardenOfTheFirstTree.java b/Mage.Sets/src/mage/sets/fatereforged/WardenOfTheFirstTree.java new file mode 100644 index 0000000000..71c56b1fc4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/WardenOfTheFirstTree.java @@ -0,0 +1,138 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.LockedInCondition; +import mage.abilities.condition.common.SourceMatchesFilterCondition; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.continious.BecomesCreatureSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.LifelinkAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.permanent.token.Token; + +/** + * + * @author LevelX2 + */ +public class WardenOfTheFirstTree extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent(); + + static { + filter.add(new SubtypePredicate("Warrior")); + filter2.add(new SubtypePredicate("Spirit")); + } + + public WardenOfTheFirstTree(UUID ownerId) { + super(ownerId, 143, "Warden of the First Tree", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Human"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {1}{W/B}: Warden of the First Tree becomes a Human Warrior with base power and toughness 3/3. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new BecomesCreatureSourceEffect(new WardenOfTheFirstTree1(), "", Duration.Custom), + new ManaCostsImpl("{1}{W/B}"))); + + // {2}{W/B}{W/B}: If Warden of the First Tree is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new ConditionalContinousEffect( + new BecomesCreatureSourceEffect(new WardenOfTheFirstTree2(), "", Duration.Custom), + new LockedInCondition(new SourceMatchesFilterCondition(filter)), + "If {this} is a Warrior, it becomes a Human Spirit Warrior with trample and lifelink"), + new ManaCostsImpl("{2}{W/B}{W/B}") + )); + + // {3}{W/B}{W/B}{W/B}: If Warden of the First Tree is a Spirit, put five +1/+1 counters on it. + this.addAbility(new SimpleActivatedAbility( + Zone.BATTLEFIELD, + new ConditionalOneShotEffect( + new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)), + new SourceMatchesFilterCondition(filter2), + "If {this} is a Spirit, put five +1/+1 counters on it"), + new ManaCostsImpl("{3}{W/B}{W/B}{W/B}") + )); + } + + public WardenOfTheFirstTree(final WardenOfTheFirstTree card) { + super(card); + } + + @Override + public WardenOfTheFirstTree copy() { + return new WardenOfTheFirstTree(this); + } +} + +class WardenOfTheFirstTree1 extends Token { + + public WardenOfTheFirstTree1() { + super("Warden of the First Tree", "Human Warrior with base power and toughness 3/3"); + this.cardType.add(CardType.CREATURE); + this.subtype.add("Human"); + this.subtype.add("Warrior"); + + this.power = new MageInt(3); + this.toughness = new MageInt(3); + } +} + +class WardenOfTheFirstTree2 extends Token { + + public WardenOfTheFirstTree2() { + super("Warden of the First Tree", "Human Spirit Warrior with trample and lifelink"); + this.cardType.add(CardType.CREATURE); + this.subtype.add("Human"); + this.subtype.add("Spirit"); + this.subtype.add("Warrior"); + + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + this.addAbility(TrampleAbility.getInstance()); + this.addAbility(LifelinkAbility.getInstance()); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/WhispererOfTheWilds.java b/Mage.Sets/src/mage/sets/fatereforged/WhispererOfTheWilds.java new file mode 100644 index 0000000000..ae58a337ea --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/WhispererOfTheWilds.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.fatereforged; + +import java.util.UUID; +import mage.MageInt; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.condition.common.FerociousCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.common.BasicManaEffect; +import mage.abilities.mana.ActivateIfConditionManaAbility; +import mage.abilities.mana.GreenManaAbility; +import mage.cards.CardImpl; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LevelX2 + */ +public class WhispererOfTheWilds extends CardImpl { + + public WhispererOfTheWilds(UUID ownerId) { + super(ownerId, 144, "Whisperer of the Wilds", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "FRF"; + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.power = new MageInt(0); + this.toughness = new MageInt(2); + + // {T}: Add {G} to your mana pool. + this.addAbility(new GreenManaAbility()); + + // Ferocious - {T}: Add {G}{G} to your mana pool. Activate this ability only if you control a creature with power 4 or greater. + Ability ability = new ActivateIfConditionManaAbility(Zone.BATTLEFIELD, new BasicManaEffect(Mana.GreenMana(2)), new TapSourceCost(), FerociousCondition.getInstance()); + ability.setAbilityWord(AbilityWord.FEROCIOUS); + this.addAbility(ability); + } + + public WhispererOfTheWilds(final WhispererOfTheWilds card) { + super(card); + } + + @Override + public WhispererOfTheWilds copy() { + return new WhispererOfTheWilds(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/WildSlash.java b/Mage.Sets/src/mage/sets/fatereforged/WildSlash.java new file mode 100644 index 0000000000..f27ccc2cb5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/WildSlash.java @@ -0,0 +1,108 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.FerociousCondition; +import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect; +import mage.abilities.effects.ContinuousRuleModifiyingEffect; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.cards.CardImpl; +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.game.events.GameEvent; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author jeffwadsworth + */ +public class WildSlash extends CardImpl { + + public WildSlash(UUID ownerId) { + super(ownerId, 118, "Wild Slash", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{R}"); + this.expansionSetCode = "FRF"; + + // Ferocious If you control a creature with power 4 or greater, damage can't be prevented this turn. + ContinuousRuleModifiyingEffect effect = new DamageCantBePreventedEffect(); + effect.setText("Ferocious — If you control a creature with power 4 or greater, damage can't be prevented this turn"); + this.addAbility(new SimpleStaticAbility(Zone.ALL, new ConditionalContinuousRuleModifyingEffect(effect, + FerociousCondition.getInstance()))); + + // Wild Slash deals 2 damage to target creature or player. + this.getSpellAbility().addEffect(new DamageTargetEffect(2)); + this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); + + } + + public WildSlash(final WildSlash card) { + super(card); + } + + @Override + public WildSlash copy() { + return new WildSlash(this); + } +} + +class DamageCantBePreventedEffect extends ContinuousRuleModifiyingEffectImpl { + + public DamageCantBePreventedEffect() { + super(Duration.EndOfTurn, Outcome.Benefit, false, false); + staticText = "Damage can't be prevented this turn"; + } + + public DamageCantBePreventedEffect(final DamageCantBePreventedEffect effect) { + super(effect); + } + + @Override + public DamageCantBePreventedEffect copy() { + return new DamageCantBePreventedEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType().equals(GameEvent.EventType.PREVENT_DAMAGE)) { + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/Wildcall.java b/Mage.Sets/src/mage/sets/fatereforged/Wildcall.java new file mode 100644 index 0000000000..a7fd2a83ed --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/Wildcall.java @@ -0,0 +1,105 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.keyword.ManifestEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class Wildcall extends CardImpl { + + public Wildcall(UUID ownerId) { + super(ownerId, 146, "Wildcall", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{G}{G}"); + this.expansionSetCode = "FRF"; + + // Manifest the top card of your library, then put X +1/+1 counters on it. + this.getSpellAbility().addEffect(new WildcallEffect()); + + } + + public Wildcall(final Wildcall card) { + super(card); + } + + @Override + public Wildcall copy() { + return new Wildcall(this); + } +} + +class WildcallEffect extends OneShotEffect { + + public WildcallEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Manifest the top card of your library, then put X +1/+1 counters on it"; + } + + public WildcallEffect(final WildcallEffect effect) { + super(effect); + } + + @Override + public WildcallEffect copy() { + return new WildcallEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Card card = controller.getLibrary().getFromTop(game); + if (card != null) { + new ManifestEffect(1).apply(game, source); + int xValue = source.getManaCostsToPay().getX(); + if (xValue > 0) { + Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(xValue)); + effect.setTargetPointer(new FixedTarget(card.getId())); + return effect.apply(game, source); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/WindsOfQalSisma.java b/Mage.Sets/src/mage/sets/fatereforged/WindsOfQalSisma.java new file mode 100644 index 0000000000..ce0b351213 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/WindsOfQalSisma.java @@ -0,0 +1,79 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.abilities.condition.LockedInCondition; +import mage.abilities.condition.common.FerociousCondition; +import mage.abilities.decorator.ConditionalReplacementEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.PreventAllDamageByAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LevelX2 + */ +public class WindsOfQalSisma extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + } + + public WindsOfQalSisma(UUID ownerId) { + super(ownerId, 147, "Winds of Qal Sisma", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{G}"); + this.expansionSetCode = "FRF"; + + // Prevent all combat damage that would be dealt this turn. + // Ferocious - If you control a creature with power 4 or greater, instead prevent all combat damage that would be dealt this turn by creatures your opponents control. + Effect effect = new ConditionalReplacementEffect( + new PreventAllDamageByAllEffect(filter, Duration.EndOfTurn, true), + new LockedInCondition(FerociousCondition.getInstance()), + new PreventAllDamageByAllEffect(Duration.EndOfTurn, true)); + effect.setText("Prevent all combat damage that would be dealt this turn.
" + + "Ferocious — If you control a creature with power 4 or greater, instead prevent all combat damage that would be dealt this turn by creatures your opponents control"); + this.getSpellAbility().addEffect(effect); + } + + public WindsOfQalSisma(final WindsOfQalSisma card) { + super(card); + } + + @Override + public WindsOfQalSisma copy() { + return new WindsOfQalSisma(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fatereforged/WriteIntoBeing.java b/Mage.Sets/src/mage/sets/fatereforged/WriteIntoBeing.java new file mode 100644 index 0000000000..601df1b7a6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/fatereforged/WriteIntoBeing.java @@ -0,0 +1,122 @@ +/* + * 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.fatereforged; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.keyword.ManifestEffect; +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.FilterCard; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetCard; + +/** + * + * @author LevelX2 + */ +public class WriteIntoBeing extends CardImpl { + + public WriteIntoBeing(UUID ownerId) { + super(ownerId, 59, "Write into Being", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{U}"); + this.expansionSetCode = "FRF"; + + // Look at the top two cards of your library. Manifest one of those cards, then put the other on the top or bottom of your library. + this.getSpellAbility().addEffect(new WriteIntoBeingEffect()); + } + + public WriteIntoBeing(final WriteIntoBeing card) { + super(card); + } + + @Override + public WriteIntoBeing copy() { + return new WriteIntoBeing(this); + } +} + +class WriteIntoBeingEffect extends OneShotEffect { + + public WriteIntoBeingEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Look at the top two cards of your library. Manifest one of those cards, then put the other on the top or bottom of your library. (To manifest a card, put it onto the battlefield face down as a 2/2 creature. Turn it face up any time for its mana cost if it's a creature card.)"; + } + + public WriteIntoBeingEffect(final WriteIntoBeingEffect effect) { + super(effect); + } + + @Override + public WriteIntoBeingEffect copy() { + return new WriteIntoBeingEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (sourceObject != null && controller != null) { + Cards cards = new CardsImpl(); + cards.addAll(controller.getLibrary().getTopCards(game, 2)); + controller.lookAtCards(sourceObject.getLogName(), cards, game); + Card cardToManifest = null; + if (cards.size() > 1) { + TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to manifest")); + if (controller.chooseTarget(outcome, cards, target, source, game)) { + cardToManifest = cards.get(target.getFirstTarget(), game); + } + } else { + cardToManifest = cards.getRandom(game); + } + if (!controller.getLibrary().getFromTop(game).equals(cardToManifest)) { + Card cardToPutBack = controller.getLibrary().removeFromTop(game); + cardToManifest = controller.getLibrary().removeFromTop(game); + controller.getLibrary().putOnTop(cardToPutBack, game); + controller.getLibrary().putOnTop(cardToManifest, game); + } + new ManifestEffect(1).apply(game, source); + if (controller.getLibrary().size() > 0) { + Card cardToPutBack = controller.getLibrary().removeFromTop(game); + if (controller.chooseUse(Outcome.Detriment, "Put " + cardToPutBack.getName() + " on buttom of library?", game)) { + controller.moveCardToLibraryWithInfo(cardToPutBack, source.getSourceId(), game, Zone.LIBRARY, false, false); + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/DolmenGate.java b/Mage.Sets/src/mage/sets/lorwyn/DolmenGate.java new file mode 100644 index 0000000000..10d1e3700d --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/DolmenGate.java @@ -0,0 +1,73 @@ +/* + * 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.lorwyn; + +import java.util.UUID; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.PreventAllDamageToAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.FilterInPlay; +import mage.filter.common.FilterControlledCreatureInPlay; +import mage.filter.predicate.permanent.AttackingPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; + +/** + * + * @author LevelX2 + */ +public class DolmenGate extends CardImpl { + + private static final FilterInPlay filter = new FilterControlledCreatureInPlay("attacking creatures you control"); + + static { + filter.add(new AttackingPredicate()); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public DolmenGate(UUID ownerId) { + super(ownerId, 256, "Dolmen Gate", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "LRW"; + + // Prevent all combat damage that would be dealt to attacking creatures you control. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToAllEffect(Duration.WhileOnBattlefield, filter, true))); + } + + public DolmenGate(final DolmenGate card) { + super(card); + } + + @Override + public DolmenGate copy() { + return new DolmenGate(this); + } +} diff --git a/Mage.Sets/src/mage/sets/magic2013/OdricMasterTactician.java b/Mage.Sets/src/mage/sets/magic2013/OdricMasterTactician.java index c4e614d305..b73b61801a 100644 --- a/Mage.Sets/src/mage/sets/magic2013/OdricMasterTactician.java +++ b/Mage.Sets/src/mage/sets/magic2013/OdricMasterTactician.java @@ -115,7 +115,7 @@ class OdricMasterTacticianTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Whenever Odric, Master Tactician and at least three other creatures attack, you choose which creatures block this combat and how those creatures block."; + return "Whenever {this} and at least three other creatures attack, you choose which creatures block this combat and how those creatures block."; } } @@ -150,17 +150,19 @@ class OdricMasterTacticianEffect extends ReplacementEffectImpl { return false; } + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARING_BLOCKERS; + } + @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == GameEvent.EventType.DECLARING_BLOCKERS) { - Object object = getValue("apply_" + source.getSourceId()); - if (object != null && object instanceof Boolean) { - if ((Boolean)object) { - return true; // replace event - } + Object object = getValue("apply_" + source.getSourceId()); + if (object != null && object instanceof Boolean) { + if ((Boolean)object) { + return true; // replace event } } - return false; } } diff --git a/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java b/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java index c31b5c9cd4..2b20eea57a 100644 --- a/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java +++ b/Mage.Sets/src/mage/sets/magic2015/GoblinRabblemaster.java @@ -46,6 +46,7 @@ import mage.constants.Rarity; import mage.constants.TargetController; import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.AttackingPredicate; import mage.filter.predicate.permanent.ControllerPredicate; diff --git a/Mage.Sets/src/mage/sets/magic2015/InvasiveSpecies.java b/Mage.Sets/src/mage/sets/magic2015/InvasiveSpecies.java index 8abc56d165..82e592a4b6 100644 --- a/Mage.Sets/src/mage/sets/magic2015/InvasiveSpecies.java +++ b/Mage.Sets/src/mage/sets/magic2015/InvasiveSpecies.java @@ -61,9 +61,8 @@ public class InvasiveSpecies extends CardImpl { this.toughness = new MageInt(3); // When Invasive Species enters the battlefield, return another permanent you control to its owner's hand. - Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(filter))); - this.addAbility(ability); } public InvasiveSpecies(final InvasiveSpecies card) { diff --git a/Mage.Sets/src/mage/sets/mirrodin/GoblinCharbelcher.java b/Mage.Sets/src/mage/sets/mirrodin/GoblinCharbelcher.java index 6de8c2341c..b4f651fee8 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/GoblinCharbelcher.java +++ b/Mage.Sets/src/mage/sets/mirrodin/GoblinCharbelcher.java @@ -28,6 +28,7 @@ package mage.sets.mirrodin; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -41,11 +42,9 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; -import mage.filter.FilterCard; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.TargetCard; import mage.target.common.TargetCreatureOrPlayer; /** @@ -94,29 +93,27 @@ class GoblinCharbelcherEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { boolean isMountain = false; - Card sourceCard = game.getCard(source.getSourceId()); - Player player = game.getPlayer(source.getControllerId()); - - if (player == null || sourceCard == null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null || sourceObject == null) { return false; } Cards cards = new CardsImpl(); - while (player.getLibrary().size() > 0) { - Card card = player.getLibrary().removeFromTop(game); + while (controller.getLibrary().size() > 0) { + Card card = controller.getLibrary().removeFromTop(game); if (card != null) { cards.add(card); - if(card.getCardType().contains(CardType.LAND)){ + if (card.getCardType().contains(CardType.LAND)){ if(card.getSubtype().contains("Mountain")){ isMountain = true; } break; } - } - else{ + } else { break; } } - player.revealCards(sourceCard.getName(), cards, game); + controller.revealCards(sourceObject.getLogName(), cards, game); int damage = cards.size(); if(isMountain == true){ damage *= 2; @@ -132,7 +129,7 @@ class GoblinCharbelcherEffect extends OneShotEffect { targetPlayer.damage(damage, source.getSourceId(), game, false, true); } } - player.putCardsOnBottomOfLibrary(cards, game, source, true); + controller.putCardsOnBottomOfLibrary(cards, game, source, true); return true; } } diff --git a/Mage.Sets/src/mage/sets/shadowmoor/DinOfTheFireherd.java b/Mage.Sets/src/mage/sets/shadowmoor/DinOfTheFireherd.java new file mode 100644 index 0000000000..0600bd8dd1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/DinOfTheFireherd.java @@ -0,0 +1,134 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.SacrificeEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.permanent.token.Token; +import mage.players.Player; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author jeffwadsworth + */ +public class DinOfTheFireherd extends CardImpl { + + public DinOfTheFireherd(UUID ownerId) { + super(ownerId, 184, "Din of the Fireherd", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{5}{B/R}{B/R}{B/R}"); + this.expansionSetCode = "SHM"; + + // Put a 5/5 black and red Elemental creature token onto the battlefield. Target opponent sacrifices a creature for each black creature you control, then sacrifices a land for each red creature you control. + this.getSpellAbility().addEffect(new DinOfTheFireherdEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + + } + + public DinOfTheFireherd(final DinOfTheFireherd card) { + super(card); + } + + @Override + public DinOfTheFireherd copy() { + return new DinOfTheFireherd(this); + } +} + +class DinOfTheFireherdEffect extends OneShotEffect { + + private final static FilterControlledCreaturePermanent blackCreatureFilter = new FilterControlledCreaturePermanent("black creatures you control"); + private final static FilterControlledCreaturePermanent redCreatureFilter = new FilterControlledCreaturePermanent("red creatures you control"); + + static { + blackCreatureFilter.add(new ColorPredicate(ObjectColor.BLACK)); + redCreatureFilter.add(new ColorPredicate(ObjectColor.RED)); + } + + public DinOfTheFireherdEffect() { + super(Outcome.Neutral); + this.staticText = "Put a 5/5 black and red Elemental creature token onto the battlefield. Target opponent sacrifices a creature for each black creature you control, then sacrifices a land for each red creature you control"; + } + + public DinOfTheFireherdEffect(final DinOfTheFireherdEffect effect) { + super(effect); + } + + @Override + public DinOfTheFireherdEffect copy() { + return new DinOfTheFireherdEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + boolean applied = false; + int blackCreaturesControllerControls = game.getBattlefield().countAll(blackCreatureFilter, source.getControllerId(), game); + int redCreaturesControllerControls = game.getBattlefield().countAll(redCreatureFilter, source.getControllerId(), game); + + Token token = new DinOfTheFireherdToken(); + applied = token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); + + Player targetOpponent = game.getPlayer(targetPointer.getFirst(game, source)); + if (targetOpponent != null) { + Effect effect = new SacrificeEffect(new FilterControlledCreaturePermanent(), blackCreaturesControllerControls, "Target Opponent"); + effect.setTargetPointer(new FixedTarget(targetOpponent.getId())); + effect.apply(game, source); + + Effect effect2 = new SacrificeEffect(new FilterControlledLandPermanent(), redCreaturesControllerControls, "Target Opponent"); + effect2.setTargetPointer(new FixedTarget(targetOpponent.getId())); + effect2.apply(game, source); + applied = true; + } + return applied; + } +} + +class DinOfTheFireherdToken extends Token { + public DinOfTheFireherdToken() { + super("", "5/5 black and red Elemental creature"); + cardType.add(CardType.CREATURE); + subtype.add("Elemental"); + color.setBlack(true); + color.setRed(true); + power = new MageInt(5); + toughness = new MageInt(5); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/shadowmoor/EverlastingTorment.java b/Mage.Sets/src/mage/sets/shadowmoor/EverlastingTorment.java new file mode 100644 index 0000000000..3bf0565a86 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/EverlastingTorment.java @@ -0,0 +1,145 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.continious.CantGainLifeAllEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.Counter; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; + +/** + * + * @author jeffwadsworth + */ +public class EverlastingTorment extends CardImpl { + + public EverlastingTorment(UUID ownerId) { + super(ownerId, 186, "Everlasting Torment", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{B/R}"); + this.expansionSetCode = "SHM"; + + // Players can't gain life. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantGainLifeAllEffect())); + + // Damage can't be prevented. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DamageCantBePreventedEffect(Duration.WhileOnBattlefield))); + + // All damage is dealt as though its source had wither. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DamageDealtAsIfSourceHadWitherEffect())); + + } + + public EverlastingTorment(final EverlastingTorment card) { + super(card); + } + + @Override + public EverlastingTorment copy() { + return new EverlastingTorment(this); + } +} + +class DamageCantBePreventedEffect extends ContinuousRuleModifiyingEffectImpl { + + public DamageCantBePreventedEffect(Duration duration) { + super(duration, Outcome.Benefit); + staticText = "Damage can't be prevented"; + } + + public DamageCantBePreventedEffect(final DamageCantBePreventedEffect effect) { + super(effect); + } + + @Override + public DamageCantBePreventedEffect copy() { + return new DamageCantBePreventedEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getType().equals(GameEvent.EventType.PREVENT_DAMAGE); + } +} + +class DamageDealtAsIfSourceHadWitherEffect extends ReplacementEffectImpl { + + public DamageDealtAsIfSourceHadWitherEffect() { + super(Duration.WhileOnBattlefield, Outcome.Neutral); + staticText = "All damage is dealt as though its source had wither"; + } + + public DamageDealtAsIfSourceHadWitherEffect(final DamageDealtAsIfSourceHadWitherEffect effect) { + super(effect); + } + + @Override + public DamageDealtAsIfSourceHadWitherEffect copy() { + return new DamageDealtAsIfSourceHadWitherEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + int damageAmount = event.getAmount(); + if (damageAmount > 0) { + Counter counter = CounterType.M1M1.createInstance(damageAmount); + Permanent creatureDamaged = game.getPermanent(event.getTargetId()); + if (creatureDamaged != null) { + creatureDamaged.addCounters(counter, game); + } + } + return true; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return (event.getType() == EventType.DAMAGE_CREATURE); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/GriefTyrant.java b/Mage.Sets/src/mage/sets/shadowmoor/GriefTyrant.java new file mode 100644 index 0000000000..8dd07ee046 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/GriefTyrant.java @@ -0,0 +1,106 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author jeffwadsworth + */ +public class GriefTyrant extends CardImpl { + + public GriefTyrant(UUID ownerId) { + super(ownerId, 189, "Grief Tyrant", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{5}{B/R}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Horror"); + this.power = new MageInt(8); + this.toughness = new MageInt(8); + + // Grief Tyrant enters the battlefield with four -1/-1 counters on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(4)))); + + // When Grief Tyrant dies, put a -1/-1 counter on target creature for each -1/-1 counter on Grief Tyrant. + Ability ability = new DiesTriggeredAbility(new GriefTyrantEffect()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + } + + public GriefTyrant(final GriefTyrant card) { + super(card); + } + + @Override + public GriefTyrant copy() { + return new GriefTyrant(this); + } +} + +class GriefTyrantEffect extends OneShotEffect { + + public GriefTyrantEffect() { + super(Outcome.Neutral); + this.staticText = "put a -1/-1 counter on target creature for each -1/-1 counter on {this}"; + } + + public GriefTyrantEffect(final GriefTyrantEffect effect) { + super(effect); + } + + @Override + public GriefTyrantEffect copy() { + return new GriefTyrantEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source)); + Permanent griefTyrant = game.getPermanentOrLKIBattlefield(source.getSourceId()); + int countersOnGriefTyrant = griefTyrant.getCounters().getCount(CounterType.M1M1); + if (targetCreature != null) { + targetCreature.addCounters(CounterType.M1M1.createInstance(countersOnGriefTyrant), game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/KulrathKnight.java b/Mage.Sets/src/mage/sets/shadowmoor/KulrathKnight.java new file mode 100644 index 0000000000..b64a82666e --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/KulrathKnight.java @@ -0,0 +1,121 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.RestrictionEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.WitherAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.CounterAnyPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author jeffwadsworth + */ +public class KulrathKnight extends CardImpl { + + public KulrathKnight(UUID ownerId) { + super(ownerId, 190, "Kulrath Knight", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B/R}{B/R}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Elemental"); + this.subtype.add("Knight"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Wither + this.addAbility(WitherAbility.getInstance()); + + // Creatures your opponents control with counters on them can't attack or block. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KulrathKnightRestrictionEffect())); + + } + + public KulrathKnight(final KulrathKnight card) { + super(card); + } + + @Override + public KulrathKnight copy() { + return new KulrathKnight(this); + } +} + +class KulrathKnightRestrictionEffect extends RestrictionEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures your opponents control with counters on them"); + + static { + filter.add(new ControllerPredicate(TargetController.OPPONENT)); + filter.add(new CounterAnyPredicate()); + } + + public KulrathKnightRestrictionEffect() { + super(Duration.WhileOnBattlefield); + staticText = "Creatures your opponents control with counters on them can't attack or block."; + } + + public KulrathKnightRestrictionEffect(final KulrathKnightRestrictionEffect effect) { + super(effect); + } + + @Override + public KulrathKnightRestrictionEffect copy() { + return new KulrathKnightRestrictionEffect(this); + } + + @Override + public boolean canAttack(Game game) { + return false; + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { + return false; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return filter.match(permanent, source.getSourceId(), source.getControllerId(), game); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/ManaforgeCinder.java b/Mage.Sets/src/mage/sets/shadowmoor/ManaforgeCinder.java new file mode 100644 index 0000000000..52b766ce9b --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/ManaforgeCinder.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.shadowmoor; + +import java.util.UUID; +import mage.MageInt; +import mage.Mana; +import mage.abilities.common.LimitedTimesPerTurnActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.BasicManaEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author jeffwadsworth + */ +public class ManaforgeCinder extends CardImpl { + + public ManaforgeCinder(UUID ownerId) { + super(ownerId, 191, "Manaforge Cinder", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{B/R}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Elemental"); + this.subtype.add("Shaman"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // {1}: Add {B} or {R} to your mana pool. Activate this ability no more than three times each turn. + this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new BasicManaEffect(Mana.BlackMana), new ManaCostsImpl("{1}"), 3)); + + } + + public ManaforgeCinder(final ManaforgeCinder card) { + super(card); + } + + @Override + public ManaforgeCinder copy() { + return new ManaforgeCinder(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shadowmoor/PoisonTheWell.java b/Mage.Sets/src/mage/sets/shadowmoor/PoisonTheWell.java new file mode 100644 index 0000000000..fd886b2e53 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/PoisonTheWell.java @@ -0,0 +1,97 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import static jdk.nashorn.internal.runtime.Debug.id; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author jeffwadsworth + */ +public class PoisonTheWell extends CardImpl { + + public PoisonTheWell(UUID ownerId) { + super(ownerId, 193, "Poison the Well", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{B/R}{B/R}"); + this.expansionSetCode = "SHM"; + + // Destroy target land. Poison the Well deals 2 damage to that land's controller. + this.getSpellAbility().addEffect(new PoisonTheWellEffect()); + this.getSpellAbility().addTarget(new TargetLandPermanent()); + } + + public PoisonTheWell(final PoisonTheWell card) { + super(card); + } + + @Override + public PoisonTheWell copy() { + return new PoisonTheWell(this); + } +} + +class PoisonTheWellEffect extends OneShotEffect { + + public PoisonTheWellEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Destroy target land. {this} deals 2 damage to that land's controller"; + } + + public PoisonTheWellEffect(final PoisonTheWellEffect effect) { + super(effect); + } + + @Override + public PoisonTheWellEffect copy() { + return new PoisonTheWellEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetedLand = game.getPermanent(source.getFirstTarget()); + if (targetedLand != null) { + Player controller = game.getPlayer(targetedLand.getControllerId()); + targetedLand.destroy(source.getId(), game, true); + controller.damage(2, source.getId(), game, false, true); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/shadowmoor/Sootwalkers.java b/Mage.Sets/src/mage/sets/shadowmoor/Sootwalkers.java new file mode 100644 index 0000000000..039bc5ac96 --- /dev/null +++ b/Mage.Sets/src/mage/sets/shadowmoor/Sootwalkers.java @@ -0,0 +1,75 @@ +/* + * 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.shadowmoor; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.SimpleEvasionAbility; +import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author jeffwadsworth + */ +public class Sootwalkers extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("white creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + } + + public Sootwalkers(UUID ownerId) { + super(ownerId, 196, "Sootwalkers", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B/R}{B/R}"); + this.expansionSetCode = "SHM"; + this.subtype.add("Elemental"); + this.subtype.add("Rogue"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Sootwalkers can't be blocked by white creatures. + this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + + } + + public Sootwalkers(final Sootwalkers card) { + super(card); + } + + @Override + public Sootwalkers copy() { + return new Sootwalkers(this); + } +} diff --git a/Mage.Sets/src/mage/sets/shardsofalara/BanewaspAffliction.java b/Mage.Sets/src/mage/sets/shardsofalara/BanewaspAffliction.java index a5080df5dd..00d12c9dd4 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/BanewaspAffliction.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/BanewaspAffliction.java @@ -28,10 +28,6 @@ package mage.sets.shardsofalara; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.Zone; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.DiesAttachedTriggeredAbility; @@ -39,6 +35,9 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -64,9 +63,9 @@ public class BanewaspAffliction extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); + // When enchanted creature dies, that creature's controller loses life equal to its toughness. - ability = new DiesAttachedTriggeredAbility(new LoseLifeEffect(), "enchanted creature"); - this.addAbility(ability); + this.addAbility( new DiesAttachedTriggeredAbility(new BanewaspAfflictionLoseLifeEffect(), "enchanted creature")); } public BanewaspAffliction(final BanewaspAffliction card) { @@ -80,33 +79,30 @@ public class BanewaspAffliction extends CardImpl { } -class LoseLifeEffect extends OneShotEffect { +class BanewaspAfflictionLoseLifeEffect extends OneShotEffect { - public LoseLifeEffect() { + public BanewaspAfflictionLoseLifeEffect() { super(Outcome.LoseLife); } - public LoseLifeEffect(LoseLifeEffect copy) { + public BanewaspAfflictionLoseLifeEffect(BanewaspAfflictionLoseLifeEffect copy) { super(copy); } @Override - public LoseLifeEffect copy() { - return new LoseLifeEffect(this); + public BanewaspAfflictionLoseLifeEffect copy() { + return new BanewaspAfflictionLoseLifeEffect(this); } @Override public boolean apply(Game game, Ability source) { - Permanent banewaspAffliction = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD); - if(banewaspAffliction != null){ - Permanent creature = (Permanent) game.getLastKnownInformation(banewaspAffliction.getAttachedTo(), Zone.BATTLEFIELD); - if(creature != null){ - Player player = game.getPlayer(creature.getOwnerId()); - if (player != null) { - player.loseLife(creature.getToughness().getValue(), game); - return true; - } + Permanent creature = (Permanent) getValue("attachedTo"); + if(creature != null){ + Player player = game.getPlayer(creature.getOwnerId()); + if (player != null) { + player.loseLife(creature.getToughness().getValue(), game); + return true; } } return false; @@ -117,5 +113,4 @@ class LoseLifeEffect extends OneShotEffect { return "that creature's controller loses life equal to its toughness"; } - } diff --git a/Mage.Sets/src/mage/sets/worldwake/PilgrimsEye.java b/Mage.Sets/src/mage/sets/worldwake/PilgrimsEye.java index 56833f6528..cb7602bf7b 100644 --- a/Mage.Sets/src/mage/sets/worldwake/PilgrimsEye.java +++ b/Mage.Sets/src/mage/sets/worldwake/PilgrimsEye.java @@ -37,6 +37,7 @@ import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.filter.FilterCard; +import mage.filter.common.FilterBasicLandCard; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.SupertypePredicate; import mage.target.common.TargetCardInLibrary; @@ -63,7 +64,7 @@ public class PilgrimsEye extends CardImpl { this.addAbility(FlyingAbility.getInstance()); // When Pilgrim's Eye enters the battlefield, you may search your library for a basic land card, reveal it, put it into your hand, then shuffle your library. - this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filter), true, true), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterBasicLandCard()), true, true), true)); } public PilgrimsEye (final PilgrimsEye card) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java index ed7cbf314f..57593d88f0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/DeathtouchTest.java @@ -90,7 +90,7 @@ public class DeathtouchTest extends CardTestPlayerBase { activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Equip {2}", "Marath, Will of the Wild"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath: Choose one -
&bull Put X +1/+1 counters on target creature.
&bull {source} deals X damage to target creature or player.
&bull Put an X/X green Elemental creature token onto the battlefield.
", "Archangel of Thune"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{X},Remove X +1/+1 counters from Marath: Choose one —
&bull Put X +1/+1 counters on target creature.
&bull {source} deals X damage to target creature or player.
&bull Put an X/X green Elemental creature token onto the battlefield.
", "Archangel of Thune"); setChoice(playerA, "X=3"); setModeChoice(playerA, "2"); // Marath deals X damage to target creature or player diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java new file mode 100644 index 0000000000..9055fc5763 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/ManifestTest.java @@ -0,0 +1,74 @@ +/* + * 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.abilities.keywords; + +import mage.abilities.keyword.HexproofAbility; +import mage.constants.PhaseStep; +import mage.constants.Zone; +import mage.game.permanent.Permanent; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ + +public class ManifestTest extends CardTestPlayerBase { + + /** + * Tests that ETB triggered abilities did not trigger for manifested cards + */ + @Test + public void testETBTriggeredAbilities() { + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + // Manifest the top card of your library {1}{W} + addCard(Zone.HAND, playerA, "Soul Summons"); + + // Tranquil Cove enters the battlefield tapped. + // When Tranquil Cove enters the battlefield, you gain 1 life. + // {T}: Add {W} or {U} to your mana pool. + addCard(Zone.LIBRARY, playerA, "Tranquil Cove"); + skipInitShuffling(); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Soul Summons"); + + setStopAt(1, PhaseStep.BEGIN_COMBAT); + execute(); + + // no life gain + assertLife(playerA, 20); + assertLife(playerB, 20); + // a facedown creature is on the battlefield + assertPermanentCount(playerA, "face down creature", 1); + assertPowerToughness(playerA, "face down creature", 2, 2); + // not tapped + assertTapped("face down creature", false); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java index 8614aeb60f..28b75a0588 100644 --- a/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java +++ b/Mage.Tests/src/test/java/org/mage/test/serverside/base/impl/CardTestPlayerAPIImpl.java @@ -538,7 +538,7 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement public void assertTapped(String cardName, boolean tapped) throws AssertionError { Permanent found = null; for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents()) { - if (permanent.getName().equals(cardName)) { + if (permanent.getLogName().equals(cardName)) { found = permanent; } } diff --git a/Mage/src/mage/abilities/common/AttacksAllTriggeredAbility.java b/Mage/src/mage/abilities/common/AttacksAllTriggeredAbility.java index 67e5086387..6fd5d61f82 100644 --- a/Mage/src/mage/abilities/common/AttacksAllTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/AttacksAllTriggeredAbility.java @@ -27,6 +27,7 @@ */ package mage.abilities.common; +import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.constants.CardType; @@ -90,10 +91,21 @@ public class AttacksAllTriggeredAbility extends TriggeredAbilityImpl { return false; } } - if (SetTargetPointer.PERMANENT.equals(setTargetPointer)) { - for (Effect effect: getEffects()) { - effect.setTargetPointer(new FixedTarget(permanent.getId())); - } + switch(setTargetPointer) { + case PERMANENT: + for (Effect effect: getEffects()) { + effect.setTargetPointer(new FixedTarget(permanent.getId())); + } + break; + case PLAYER: + UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(permanent.getId(), game); + if (defendingPlayerId != null) { + for (Effect effect: getEffects()) { + effect.setTargetPointer(new FixedTarget(defendingPlayerId)); + } + } + break; + } return true; } diff --git a/Mage/src/mage/abilities/common/AttacksTriggeredAbility.java b/Mage/src/mage/abilities/common/AttacksTriggeredAbility.java index 3f1ade5d1d..e8cea4c144 100644 --- a/Mage/src/mage/abilities/common/AttacksTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/AttacksTriggeredAbility.java @@ -28,12 +28,15 @@ package mage.abilities.common; +import java.util.UUID; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; +import mage.constants.SetTargetPointer; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.target.targetpointer.FixedTarget; /** * @@ -41,26 +44,44 @@ import mage.game.events.GameEvent.EventType; */ public class AttacksTriggeredAbility extends TriggeredAbilityImpl { + protected SetTargetPointer setTargetPointer; protected String text; public AttacksTriggeredAbility(Effect effect, boolean optional) { - super(Zone.BATTLEFIELD, effect, optional); + this(effect, optional, null); } public AttacksTriggeredAbility(Effect effect, boolean optional, String text) { + this(effect, optional, text, SetTargetPointer.NONE); + } + + public AttacksTriggeredAbility(Effect effect, boolean optional, String text, SetTargetPointer setTargetPointer) { super(Zone.BATTLEFIELD, effect, optional); this.text = text; + this.setTargetPointer = setTargetPointer; } public AttacksTriggeredAbility(final AttacksTriggeredAbility ability) { super(ability); this.text = ability.text; + this.setTargetPointer = ability.setTargetPointer; } @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == EventType.DECLARED_ATTACKERS && game.getCombat().getAttackers().contains(this.getSourceId()) ) { + switch(setTargetPointer) { + case PLAYER: + UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(getSourceId(), game); + if (defendingPlayerId != null) { + for (Effect effect: getEffects()) { + effect.setTargetPointer(new FixedTarget(defendingPlayerId)); + } + } + break; + + } return true; } return false; diff --git a/Mage/src/mage/abilities/condition/common/ControlsBiggestOrTiedCreatureCondition.java b/Mage/src/mage/abilities/condition/common/ControlsCreatureGreatestPowerCondition.java similarity index 88% rename from Mage/src/mage/abilities/condition/common/ControlsBiggestOrTiedCreatureCondition.java rename to Mage/src/mage/abilities/condition/common/ControlsCreatureGreatestPowerCondition.java index eaed22f3d5..83f5d27381 100644 --- a/Mage/src/mage/abilities/condition/common/ControlsBiggestOrTiedCreatureCondition.java +++ b/Mage/src/mage/abilities/condition/common/ControlsCreatureGreatestPowerCondition.java @@ -27,26 +27,25 @@ */ package mage.abilities.condition.common; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; import mage.abilities.Ability; import mage.abilities.condition.Condition; import mage.filter.common.FilterCreaturePermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.UUID; - /** * Condition for: * - if you control the creature with the greatest power or tied for the greatest power * * @author noxx */ -public class ControlsBiggestOrTiedCreatureCondition implements Condition { +public class ControlsCreatureGreatestPowerCondition implements Condition { - private static ControlsBiggestOrTiedCreatureCondition fInstance = new ControlsBiggestOrTiedCreatureCondition(); + private static final ControlsCreatureGreatestPowerCondition fInstance = new ControlsCreatureGreatestPowerCondition(); private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); @@ -76,4 +75,10 @@ public class ControlsBiggestOrTiedCreatureCondition implements Condition { } return controllers.contains(source.getControllerId()); } + + @Override + public String toString() { + return "you control the creature with the greatest power or tied for the greatest power"; + } + } diff --git a/Mage/src/mage/abilities/condition/common/ControlsCreatureGreatestToughnessCondition.java b/Mage/src/mage/abilities/condition/common/ControlsCreatureGreatestToughnessCondition.java new file mode 100644 index 0000000000..2ebe0b066b --- /dev/null +++ b/Mage/src/mage/abilities/condition/common/ControlsCreatureGreatestToughnessCondition.java @@ -0,0 +1,84 @@ +/* + * 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.condition.common; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * Condition for: + * - if you control the creature with the greatest toughness or tied for the greatest toughness + * + * @author LevelX2 + */ +public class ControlsCreatureGreatestToughnessCondition implements Condition { + + private static final ControlsCreatureGreatestToughnessCondition fInstance = new ControlsCreatureGreatestToughnessCondition(); + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + public static Condition getInstance() { + return fInstance; + } + + @Override + public boolean apply(Game game, Ability source) { + Set controllers = new HashSet<>(); + Integer maxToughness = null; + + List permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game); + for (Permanent permanent : permanents) { + if (permanent == null) { + continue; + } + + int toughness = permanent.getToughness().getValue(); + if (maxToughness == null || toughness > maxToughness) { + maxToughness = permanent.getToughness().getValue(); + controllers.clear(); + } + if (toughness == maxToughness) { + controllers.add(permanent.getControllerId()); + } + } + return controllers.contains(source.getControllerId()); + } + + @Override + public String toString() { + return "you control the creature with the greatest toughness or tied for the greatest toughness"; + } + +} \ No newline at end of file diff --git a/Mage/src/mage/abilities/condition/common/FerociousCondition.java b/Mage/src/mage/abilities/condition/common/FerociousCondition.java index ebabb79a59..22f900d7de 100644 --- a/Mage/src/mage/abilities/condition/common/FerociousCondition.java +++ b/Mage/src/mage/abilities/condition/common/FerociousCondition.java @@ -60,4 +60,10 @@ public class FerociousCondition implements Condition { return game.getBattlefield().countAll(filter, source.getControllerId(), game) > 0; } + @Override + public String toString() { + return "you control a creature with power 4 or greater"; + } + + } diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index 0800d65801..d769ef989a 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -410,6 +410,13 @@ public class ContinuousEffects implements Serializable { exists = permanent.getCard().getAbilities().contains(ability); } } + } else { + if (object instanceof PermanentCard) { + PermanentCard permanent = (PermanentCard)object; + if (permanent.isFaceDown() && !ability.getWorksFaceDown()) { + return false; + } + } } return exists; } diff --git a/Mage/src/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java b/Mage/src/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java index 81659d90b4..946bbf9613 100644 --- a/Mage/src/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java +++ b/Mage/src/mage/abilities/effects/common/AddConditionalManaOfAnyColorEffect.java @@ -29,6 +29,8 @@ package mage.abilities.effects.common; import mage.Mana; import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.mana.builder.ConditionalManaBuilder; import mage.choices.ChoiceColor; import mage.game.Game; @@ -39,20 +41,34 @@ import mage.players.Player; */ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { - private final int amount; + private final DynamicValue amount; private final ConditionalManaBuilder manaBuilder; + private final boolean oneChoice; public AddConditionalManaOfAnyColorEffect(int amount, ConditionalManaBuilder manaBuilder) { + this(new StaticValue(amount), manaBuilder); + } + + public AddConditionalManaOfAnyColorEffect(DynamicValue amount, ConditionalManaBuilder manaBuilder) { + this(amount, manaBuilder, true); + } + + public AddConditionalManaOfAnyColorEffect(DynamicValue amount, ConditionalManaBuilder manaBuilder, boolean oneChoice) { super(); this.amount = amount; this.manaBuilder = manaBuilder; - staticText = "Add " + amount + " mana of any one color to your mana pool. " + manaBuilder.getRule(); + this.oneChoice = oneChoice; + // + staticText = "Add " + amount + " mana of " + + (oneChoice ? "any one color":"in any combination of colors") + + " to your mana pool. " + manaBuilder.getRule(); } public AddConditionalManaOfAnyColorEffect(final AddConditionalManaOfAnyColorEffect effect) { super(effect); this.amount = effect.amount; this.manaBuilder = effect.manaBuilder; + this.oneChoice = effect.oneChoice; } @Override @@ -62,15 +78,20 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { @Override public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } + int value = amount.calculate(game, source, this); boolean result = false; - for (int i = 0; i < amount; i++) { - ChoiceColor choice = (ChoiceColor) source.getChoices().get(i); - + ChoiceColor choice = new ChoiceColor(); + for (int i = 0; i < value; i++) { + if (!choice.isChosen()) { + if (!controller.choose(outcome, choice, game)) { + return false; + } + } Mana mana = null; if (choice.getColor().isBlack()) { mana = manaBuilder.setMana(Mana.BlackMana(1), source, game).build(); @@ -85,10 +106,12 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect { } if (mana != null) { - player.getManaPool().addMana(mana, game, source); + controller.getManaPool().addMana(mana, game, source); result = true; } - + if (!oneChoice) { + choice.clearChoice(); + } } diff --git a/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java b/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java index 2bd0f6317a..2e6ce2a8e4 100644 --- a/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java +++ b/Mage/src/mage/abilities/effects/common/AddManaInAnyCombinationEffect.java @@ -90,7 +90,7 @@ public class AddManaInAnyCombinationEffect extends ManaEffect { sb.append(CardUtil.numberToText(amount.toString())); sb.append(" mana in any combination of "); if (manaSymbols.size() == 5) { - sb.append("of colors"); + sb.append("colors"); } else { int i = 0; for (ColoredManaSymbol coloredManaSymbol: manaSymbols) { diff --git a/Mage/src/mage/abilities/effects/common/PreventAllDamageByAllEffect.java b/Mage/src/mage/abilities/effects/common/PreventAllDamageByAllEffect.java index 690263f520..e2087c588c 100644 --- a/Mage/src/mage/abilities/effects/common/PreventAllDamageByAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/PreventAllDamageByAllEffect.java @@ -80,7 +80,7 @@ public class PreventAllDamageByAllEffect extends PreventionEffectImpl { return true; } Permanent permanent = game.getPermanent(damageEvent.getSourceId()); - if (permanent != null && filter.match(permanent, game)) { + if (permanent != null && filter.match(permanent, source.getSourceId(), source.getControllerId(), game)) { return true; } } diff --git a/Mage/src/mage/abilities/effects/common/PreventAllDamageToAllEffect.java b/Mage/src/mage/abilities/effects/common/PreventAllDamageToAllEffect.java index c7addcf81b..6fe9320041 100644 --- a/Mage/src/mage/abilities/effects/common/PreventAllDamageToAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/PreventAllDamageToAllEffect.java @@ -29,16 +29,13 @@ package mage.abilities.effects.common; import java.util.UUID; -import mage.constants.Duration; import mage.abilities.Ability; import mage.abilities.effects.PreventionEffectImpl; -import mage.constants.TargetController; +import mage.constants.Duration; import mage.filter.FilterInPlay; import mage.filter.common.FilterCreatureOrPlayer; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.other.PlayerIdPredicate; -import mage.filter.predicate.permanent.ControllerPredicate; -import mage.filter.predicate.permanent.TokenPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; @@ -57,9 +54,17 @@ public class PreventAllDamageToAllEffect extends PreventionEffectImpl { } public PreventAllDamageToAllEffect(Duration duration, FilterInPlay filter) { - super(duration); + this(duration, filter, false); + } + + public PreventAllDamageToAllEffect(Duration duration, FilterInPlay filter, boolean onlyCombat) { + super(duration, Integer.MAX_VALUE, onlyCombat); this.filter = filter; - staticText = "Prevent all damage that would be dealt to " + filter.getMessage() + (duration.toString().isEmpty() ?"": " "+ duration.toString()); + staticText = "Prevent all " + + (onlyCombat ? "combat ":"") + + "damage that would be dealt to " + + filter.getMessage() + + (duration.toString().isEmpty() ?"": " "+ duration.toString()); } public PreventAllDamageToAllEffect(final PreventAllDamageToAllEffect effect) { diff --git a/Mage/src/mage/abilities/effects/common/SacrificeEffect.java b/Mage/src/mage/abilities/effects/common/SacrificeEffect.java index 60e159e6d9..079d90fd37 100644 --- a/Mage/src/mage/abilities/effects/common/SacrificeEffect.java +++ b/Mage/src/mage/abilities/effects/common/SacrificeEffect.java @@ -89,8 +89,8 @@ public class SacrificeEffect extends OneShotEffect{ Target target = new TargetControlledPermanent(amount, amount, filter, true); - //A spell or ability could have removed the only legal target this player - //had, if thats the case this ability should fizzle. + // A spell or ability could have removed the only legal target this player + // had, if thats the case this ability should fizzle. if (amount > 0 && target.canChoose(source.getSourceId(), player.getId(), game)) { boolean abilityApplied = false; while (!target.isChosen() && target.canChoose(player.getId(), game) && player.isInGame()) { diff --git a/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java b/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java index 28fc7f2b62..4cdc3b8317 100644 --- a/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/combat/AttacksIfAbleAllEffect.java @@ -22,8 +22,15 @@ public class AttacksIfAbleAllEffect extends RequirementEffect { private final FilterCreaturePermanent filter; public AttacksIfAbleAllEffect(FilterCreaturePermanent filter) { - super(Duration.WhileOnBattlefield); - staticText = new StringBuilder(filter.getMessage()).append(" attack each turn if able").toString(); + this(filter, Duration.WhileOnBattlefield); + } + + public AttacksIfAbleAllEffect(FilterCreaturePermanent filter, Duration duration) { + super(duration); + staticText = new StringBuilder(filter.getMessage()) + .append(" attack ") + .append(duration.equals(Duration.EndOfTurn) ? "this":"each") + .append(" turn if able").toString(); this.filter = filter; } diff --git a/Mage/src/mage/abilities/effects/common/combat/BlocksIfAbleAllEffect.java b/Mage/src/mage/abilities/effects/common/combat/BlocksIfAbleAllEffect.java new file mode 100644 index 0000000000..d8f0ab6f92 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/combat/BlocksIfAbleAllEffect.java @@ -0,0 +1,83 @@ +/* + * 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.effects.common.combat; + +import mage.abilities.Ability; +import mage.abilities.effects.RequirementEffect; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ + +public class BlocksIfAbleAllEffect extends RequirementEffect { + + private final FilterCreaturePermanent filter; + + public BlocksIfAbleAllEffect(FilterCreaturePermanent filter) { + this(filter,Duration.WhileOnBattlefield); + } + + public BlocksIfAbleAllEffect(FilterCreaturePermanent filter, Duration duration) { + super(duration); + staticText = new StringBuilder(filter.getMessage()) + .append(" block ") + .append(duration.equals(Duration.EndOfTurn) ? "this":"each") + .append(" turn if able").toString(); + this.filter = filter; + } + public BlocksIfAbleAllEffect(final BlocksIfAbleAllEffect effect) { + super(effect); + this.filter = effect.filter; + } + + @Override + public BlocksIfAbleAllEffect copy() { + return new BlocksIfAbleAllEffect(this); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return filter.match(permanent, source.getSourceId(), source.getControllerId(), game); + } + + @Override + public boolean mustAttack(Game game) { + return false; + } + + @Override + public boolean mustBlock(Game game) { + return true; + } + +} diff --git a/Mage/src/mage/abilities/effects/common/continious/BecomesFaceDownCreatureEffect.java b/Mage/src/mage/abilities/effects/common/continious/BecomesFaceDownCreatureEffect.java index 07e69e3631..5f9f9e2ca5 100644 --- a/Mage/src/mage/abilities/effects/common/continious/BecomesFaceDownCreatureEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/BecomesFaceDownCreatureEffect.java @@ -62,6 +62,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl implemen protected int zoneChangeCounter; protected Ability turnFaceUpAbility = null; protected boolean useTargetPointer; + protected boolean foundPermanent; public BecomesFaceDownCreatureEffect(Costs morphCosts) { @@ -84,6 +85,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl implemen this.turnFaceUpAbility = new TurnFaceUpAbility(morphCosts); } staticText = "{this} becomes a 2/2 face-down creature, with no text, no name, no subtypes, and no mana cost"; + foundPermanent = false; } @@ -94,6 +96,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl implemen this.turnFaceUpAbility = effect.turnFaceUpAbility.copy(); } this.useTargetPointer = effect.useTargetPointer; + this.foundPermanent = effect.foundPermanent; } @Override @@ -120,6 +123,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl implemen } if (permanent != null && permanent.isFaceDown()) { + foundPermanent = true; switch (layer) { case TypeChangingEffects_4: permanent.setName(""); @@ -164,7 +168,7 @@ public class BecomesFaceDownCreatureEffect extends ContinuousEffectImpl implemen } } } else { - if (duration.equals(Duration.Custom)) { + if (duration.equals(Duration.Custom) && foundPermanent == true) { discard(); } } diff --git a/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java b/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java index 3b39158ca9..ddfc2a1c26 100644 --- a/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/GainAbilityTargetEffect.java @@ -164,7 +164,7 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl { sb.append(target.getMaxNumberOfTargets()).append(" target ").append(target.getTargetName()).append(" gain "); } else { if (!target.getTargetName().toUpperCase().startsWith("ANOTHER")) { - sb.append("Target "); + sb.append("target "); } sb.append(target.getTargetName()).append(" gains "); diff --git a/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java b/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java index 753c224a64..4ac634ce94 100644 --- a/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java +++ b/Mage/src/mage/abilities/effects/keyword/ManifestEffect.java @@ -86,6 +86,7 @@ public class ManifestEffect extends OneShotEffect { ContinuousEffect effect = new BecomesFaceDownCreatureEffect(manaCosts, true, Duration.Custom); effect.setTargetPointer(new FixedTarget(card.getId())); game.addEffect(effect, source); + game.applyEffects(); // to apply nefore ETB triggered or replace Effects are executed } return true; } diff --git a/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java new file mode 100644 index 0000000000..eea0163b2f --- /dev/null +++ b/Mage/src/mage/abilities/effects/keyword/ManifestTargetPlayerEffect.java @@ -0,0 +1,118 @@ +/* + * 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.effects.keyword; + +import java.util.List; +import mage.abilities.Ability; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continious.BecomesFaceDownCreatureEffect; +import mage.cards.Card; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ + +public class ManifestTargetPlayerEffect extends OneShotEffect { + + private final int amount; + private final String prefix; + + public ManifestTargetPlayerEffect(int amount, String prefix) { + super(Outcome.PutCreatureInPlay); + this.amount = amount; + this.prefix = prefix; + this.staticText = setText(); + } + + public ManifestTargetPlayerEffect(final ManifestTargetPlayerEffect effect) { + super(effect); + this.amount = effect.amount; + this.prefix = effect.prefix; + } + + @Override + public ManifestTargetPlayerEffect copy() { + return new ManifestTargetPlayerEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetPlayer != null) { + List cards = targetPlayer.getLibrary().getTopCards(game, amount); + for (Card card: cards) { + card.setFaceDown(true); + targetPlayer.putOntoBattlefieldWithInfo(card, game, Zone.LIBRARY, source.getSourceId()); + ManaCosts manaCosts = null; + if (card.getCardType().contains(CardType.CREATURE)) { + manaCosts = card.getSpellAbility().getManaCosts(); + if (manaCosts == null) { + manaCosts = new ManaCostsImpl("{0}"); + } + } + ContinuousEffect effect = new BecomesFaceDownCreatureEffect(manaCosts, true, Duration.Custom); + effect.setTargetPointer(new FixedTarget(card.getId())); + game.addEffect(effect, source); + } + return true; + } + return false; + } + + private String setText() { + StringBuilder sb = new StringBuilder(); + if (prefix != null && !prefix.isEmpty()) { + sb.append(prefix).append(" "); + } + sb.append("manifest the top "); + if (amount > 1) { + sb.append(CardUtil.numberToText(amount)).append(" cards "); + } else { + sb.append("card "); + } + sb.append("of his or her library. "); + if (amount > 1) { + sb.append("(To manifest a card, put it onto the battlefield face down as a 2/2 creature. The controller may turn it face up at any time for its mana cost if it's a creature card.)"); + } else { + sb.append("(That player puts the top card of his or her library onto the battlefield face down as a 2/2 creature. If it's a creature card, it can be turned face up any time for its mana cost.)"); + } + return sb.toString(); + } +} diff --git a/Mage/src/mage/abilities/mana/ConditionalAnyColorManaAbility.java b/Mage/src/mage/abilities/mana/ConditionalAnyColorManaAbility.java index a5892859e2..5aa3331e23 100644 --- a/Mage/src/mage/abilities/mana/ConditionalAnyColorManaAbility.java +++ b/Mage/src/mage/abilities/mana/ConditionalAnyColorManaAbility.java @@ -27,13 +27,16 @@ */ package mage.abilities.mana; +import java.util.List; import mage.Mana; import mage.abilities.costs.Cost; import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.common.AddConditionalManaOfAnyColorEffect; import mage.abilities.mana.builder.ConditionalManaBuilder; -import mage.choices.ChoiceColor; import mage.constants.Zone; +import mage.game.Game; /** * For cards like: @@ -43,6 +46,8 @@ import mage.constants.Zone; */ public class ConditionalAnyColorManaAbility extends ManaAbility { + private DynamicValue amount; + public ConditionalAnyColorManaAbility(int amount, ConditionalManaBuilder manaBuilder) { this(new TapSourceCost(), amount, manaBuilder); } @@ -52,22 +57,24 @@ public class ConditionalAnyColorManaAbility extends ManaAbility { } public ConditionalAnyColorManaAbility(Cost cost, int amount, ConditionalManaBuilder manaBuilder, boolean oneChoice) { - super(Zone.BATTLEFIELD, new AddConditionalManaOfAnyColorEffect(oneChoice ? 1 :amount, manaBuilder), cost); - int choices = amount; - if (oneChoice) { - for (int i = 1; i < amount; i++) { - this.addEffect(new AddConditionalManaOfAnyColorEffect(1 , manaBuilder)); - } - choices = 1; - } - for (int i = 0; i < choices; i++) { - this.addChoice(new ChoiceColor()); - } - this.netMana.add(new Mana(0,0,0,0,0,0,amount)); + this(cost, new StaticValue(amount), manaBuilder, oneChoice); + } + + public ConditionalAnyColorManaAbility(Cost cost, DynamicValue amount, ConditionalManaBuilder manaBuilder, boolean oneChoice) { + super(Zone.BATTLEFIELD, new AddConditionalManaOfAnyColorEffect(amount, manaBuilder, oneChoice), cost); + this.amount = amount; } public ConditionalAnyColorManaAbility(final ConditionalAnyColorManaAbility ability) { super(ability); + this.amount = ability.amount; + } + + @Override + public List getNetMana(Game game) { + this.netMana.clear(); + this.netMana.add(new Mana(0,0,0,0,0,0, amount.calculate(game, this, null))); + return super.getNetMana(game); } @Override diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 83b777ba94..081cb14a20 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -277,7 +277,7 @@ public abstract class GameImpl implements Game, Serializable { card = ((PermanentCard)card).getCard(); } card.setOwnerId(ownerId); - card.setFaceDown(false); // can be set face dwon from previous game + card.setFaceDown(false); // can be set face down from previous game gameCards.put(card.getId(), card); state.addCard(card); if (card.isSplitCard()) { diff --git a/Utils/release/getting_implemented_cards.txt b/Utils/release/getting_implemented_cards.txt index 455cfbeddc..887d71b56f 100644 --- a/Utils/release/getting_implemented_cards.txt +++ b/Utils/release/getting_implemented_cards.txt @@ -84,6 +84,9 @@ git log c4ad51c4af2467f3483204e29f23b76c53f8f880..HEAD --diff-filter=A --name-st since 1.3.0-2014-11-29v7 (2015-01-01) git log c370189787cff7fc129b1ccf1b223807143460de..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt +since 1.3.0-2014-11-29v8 (2015-01-17) +git log 79ceae999a72151e2fadd1e15ddd37ec76c3f205..HEAD --diff-filter=A --name-status | sed -ne "s/^A[^u]Mage.Sets\/src\/mage\/sets\///p" | sort > added_cards.txt + 3. Copy added_cards.txt to trunk\Utils folder 4. Run script: > perl extract_in_wiki_format.perl