diff --git a/Mage.Sets/src/mage/sets/apocalypse/Spiritmonger.java b/Mage.Sets/src/mage/sets/apocalypse/Spiritmonger.java index 41d8070f2c..0d08b363d4 100644 --- a/Mage.Sets/src/mage/sets/apocalypse/Spiritmonger.java +++ b/Mage.Sets/src/mage/sets/apocalypse/Spiritmonger.java @@ -29,27 +29,18 @@ package mage.sets.apocalypse; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.DealsDamageToACreatureTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ContinuousEffect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.RegenerateSourceEffect; -import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; -import mage.choices.ChoiceColor; import mage.constants.CardType; import mage.constants.Duration; -import mage.constants.Outcome; import mage.constants.Rarity; import mage.constants.Zone; import mage.counters.CounterType; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.targetpointer.FixedTarget; /** * @@ -70,7 +61,7 @@ public class Spiritmonger extends CardImpl { // {B}: Regenerate Spiritmonger. this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}"))); // {G}: Spiritmonger becomes the color of your choice until end of turn. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SpiritmongerChangeColorEffect(), new ManaCostsImpl("{G}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesColorSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{G}"))); } public Spiritmonger(final Spiritmonger card) { @@ -82,37 +73,3 @@ public class Spiritmonger extends CardImpl { return new Spiritmonger(this); } } - -class SpiritmongerChangeColorEffect extends OneShotEffect { - - public SpiritmongerChangeColorEffect() { - super(Outcome.Neutral); - staticText = "{this} becomes the color of your choice until end of turn"; - } - - public SpiritmongerChangeColorEffect(final SpiritmongerChangeColorEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent wildMongrel = game.getPermanent(source.getSourceId()); - if (player != null && wildMongrel != null) { - ChoiceColor colorChoice = new ChoiceColor(); - if (player.choose(Outcome.Neutral, colorChoice, game)) { - game.informPlayers(wildMongrel.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice()); - ContinuousEffect effect = new BecomesColorTargetEffect(colorChoice.getColor(), Duration.EndOfTurn, "is " + colorChoice.getChoice()); - effect.setTargetPointer(new FixedTarget(source.getSourceId())); - game.addEffect(effect, source); - return true; - } - } - return false; - } - - @Override - public SpiritmongerChangeColorEffect copy() { - return new SpiritmongerChangeColorEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/BattleMadRonin.java b/Mage.Sets/src/mage/sets/championsofkamigawa/BattleMadRonin.java index 198c99246b..c57a246e79 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/BattleMadRonin.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/BattleMadRonin.java @@ -25,16 +25,15 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.sets.championsofkamigawa; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Rarity; import mage.MageInt; import mage.abilities.common.AttacksEachTurnStaticAbility; import mage.abilities.keyword.BushidoAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; /** * @@ -42,7 +41,7 @@ import mage.cards.CardImpl; */ public class BattleMadRonin extends CardImpl { - public BattleMadRonin (UUID ownerId) { + public BattleMadRonin(UUID ownerId) { super(ownerId, 156, "Battle-Mad Ronin", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.expansionSetCode = "CHK"; this.subtype.add("Human"); @@ -50,11 +49,15 @@ public class BattleMadRonin extends CardImpl { this.power = new MageInt(1); this.toughness = new MageInt(1); + + // Bushido 2 (When this blocks or becomes blocked, it gets +2/+2 until end of turn.) this.addAbility(new BushidoAbility(2)); + + // Battle-Mad Ronin attacks each turn if able. this.addAbility(new AttacksEachTurnStaticAbility()); } - public BattleMadRonin (final BattleMadRonin card) { + public BattleMadRonin(final BattleMadRonin card) { super(card); } diff --git a/Mage.Sets/src/mage/sets/commander/Flusterstorm.java b/Mage.Sets/src/mage/sets/commander/Flusterstorm.java index 47a6947376..2d6e491b2c 100644 --- a/Mage.Sets/src/mage/sets/commander/Flusterstorm.java +++ b/Mage.Sets/src/mage/sets/commander/Flusterstorm.java @@ -28,13 +28,12 @@ package mage.sets.commander; import java.util.UUID; - -import mage.constants.CardType; -import mage.constants.Rarity; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.common.CounterUnlessPaysEffect; import mage.abilities.keyword.StormAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; import mage.filter.FilterSpell; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.CardTypePredicate; @@ -47,15 +46,15 @@ import mage.target.TargetSpell; public class Flusterstorm extends CardImpl { private static final FilterSpell filter = new FilterSpell("instant or sorcery spell"); + static { filter.add(Predicates.or(new CardTypePredicate(CardType.INSTANT), new CardTypePredicate(CardType.SORCERY))); } - + public Flusterstorm(UUID ownerId) { super(ownerId, 46, "Flusterstorm", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{U}"); this.expansionSetCode = "CMD"; - // Counter target instant or sorcery spell unless its controller pays {1}. this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new ManaCostsImpl("{1}"))); this.getSpellAbility().addTarget(new TargetSpell(filter)); diff --git a/Mage.Sets/src/mage/sets/dissension/AzoriusFirstWing.java b/Mage.Sets/src/mage/sets/dissension/AzoriusFirstWing.java new file mode 100644 index 0000000000..fe31a8c266 --- /dev/null +++ b/Mage.Sets/src/mage/sets/dissension/AzoriusFirstWing.java @@ -0,0 +1,67 @@ +/* + * 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.dissension; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterEnchantmentCard; + +/** + * + * @author LoneFox + + */ +public class AzoriusFirstWing extends CardImpl { + + public AzoriusFirstWing(UUID ownerId) { + super(ownerId, 105, "Azorius First-Wing", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{W}{U}"); + this.expansionSetCode = "DIS"; + this.subtype.add("Griffin"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // protection from enchantments + this.addAbility(new ProtectionAbility(new FilterEnchantmentCard("enchantments"))); + } + + public AzoriusFirstWing(final AzoriusFirstWing card) { + super(card); + } + + @Override + public AzoriusFirstWing copy() { + return new AzoriusFirstWing(this); + } +} diff --git a/Mage.Sets/src/mage/sets/fifthedition/EvilEyeOfOrmsByGore.java b/Mage.Sets/src/mage/sets/fifthedition/EvilEyeOfOrmsByGore.java index 1330a2c5b9..dbf4cce772 100644 --- a/Mage.Sets/src/mage/sets/fifthedition/EvilEyeOfOrmsByGore.java +++ b/Mage.Sets/src/mage/sets/fifthedition/EvilEyeOfOrmsByGore.java @@ -29,23 +29,19 @@ package mage.sets.fifthedition; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; 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.Predicates; 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.filter.predicate.permanent.ControllerPredicate; /** * @@ -53,12 +49,15 @@ import mage.game.permanent.Permanent; */ public class EvilEyeOfOrmsByGore extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("except by Walls"); + private static final FilterCreaturePermanent cantAttackFilter = new FilterCreaturePermanent("Non-Eye creatures you control"); + private static final FilterCreaturePermanent cantBeBlockedByFilter = new FilterCreaturePermanent("except by Walls"); static { - filter.add(Predicates.not(new SubtypePredicate("Wall"))); + cantBeBlockedByFilter.add(Predicates.not(new SubtypePredicate("Wall"))); + cantAttackFilter.add(Predicates.not((new SubtypePredicate("Eye")))); + cantAttackFilter.add(new ControllerPredicate(TargetController.YOU)); } - + public EvilEyeOfOrmsByGore(UUID ownerId) { super(ownerId, 21, "Evil Eye of Orms-by-Gore", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{4}{B}"); this.expansionSetCode = "5ED"; @@ -68,10 +67,10 @@ public class EvilEyeOfOrmsByGore extends CardImpl { this.toughness = new MageInt(6); // Non-Eye creatures you control can't attack. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EvilEyeOfOrmsByGoreEffect())); - + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, cantAttackFilter))); + // Evil Eye of Orms-by-Gore can't be blocked except by Walls. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBeBlockedByCreaturesSourceEffect(cantBeBlockedByFilter, Duration.WhileOnBattlefield))); } public EvilEyeOfOrmsByGore(final EvilEyeOfOrmsByGore card) { @@ -83,43 +82,3 @@ public class EvilEyeOfOrmsByGore extends CardImpl { return new EvilEyeOfOrmsByGore(this); } } - -class EvilEyeOfOrmsByGoreEffect extends ReplacementEffectImpl { - - public EvilEyeOfOrmsByGoreEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Non-Eye creatures you control can't attack"; - } - - public EvilEyeOfOrmsByGoreEffect(final EvilEyeOfOrmsByGoreEffect effect) { - super(effect); - } - - @Override - public EvilEyeOfOrmsByGoreEffect copy() { - return new EvilEyeOfOrmsByGoreEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DECLARE_ATTACKER; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null) { - if (permanent.getControllerId().equals(source.getControllerId())) { - if (!permanent.hasSubtype("Eye")) { - return true; - } - } - } - return false; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } -} diff --git a/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoat.java b/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoat.java index 6d104151f5..64d2d6b131 100644 --- a/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoat.java +++ b/Mage.Sets/src/mage/sets/futuresight/MagusOfTheMoat.java @@ -30,7 +30,7 @@ package mage.sets.futuresight; import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.combat.CantAttackAllAnyPlayerEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -62,7 +62,7 @@ public class MagusOfTheMoat extends CardImpl { this.toughness = new MageInt(3); // Creatures without flying can't attack. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAllAnyPlayerEffect(Duration.WhileOnBattlefield, filter))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter))); } public MagusOfTheMoat(final MagusOfTheMoat card) { diff --git a/Mage.Sets/src/mage/sets/futuresight/OrissSamiteGuardian.java b/Mage.Sets/src/mage/sets/futuresight/OrissSamiteGuardian.java index b9c7b6a04c..eddf92e329 100644 --- a/Mage.Sets/src/mage/sets/futuresight/OrissSamiteGuardian.java +++ b/Mage.Sets/src/mage/sets/futuresight/OrissSamiteGuardian.java @@ -33,14 +33,19 @@ import mage.abilities.Ability; import mage.abilities.abilityword.GrandeurAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; +import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.PreventDamageToTargetEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; 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.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; @@ -68,10 +73,9 @@ public class OrissSamiteGuardian extends CardImpl { Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PreventDamageToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE), new TapSourceCost()); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); - + // Grandeur - Discard another card named Oriss, Samite Guardian: Target player can't cast spells this turn, and creatures that player controls can't attack this turn. ability = new GrandeurAbility(new OrissSamiteGuardianCantCastEffect(), "Oriss, Samite Guardian"); - ability.addEffect(new OrissSamiteGuardianCantAttackEffect()); ability.addTarget(new TargetPlayer()); this.addAbility(ability); } @@ -86,6 +90,37 @@ public class OrissSamiteGuardian extends CardImpl { } } +class OrissSamiteGuardianEffect extends OneShotEffect { + + public OrissSamiteGuardianEffect() { + super(Outcome.Benefit); + this.staticText = "Target player can't cast spells this turn, and creatures that player controls can't attack this turn"; + } + + public OrissSamiteGuardianEffect(final OrissSamiteGuardianEffect effect) { + super(effect); + } + + @Override + public OrissSamiteGuardianEffect copy() { + return new OrissSamiteGuardianEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + game.addEffect(new OrissSamiteGuardianCantCastEffect(), source); + FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures that player controls"); + filter.add(new ControllerIdPredicate(getTargetPointer().getFirst(game, source))); + ContinuousEffect effect = new CantAttackAnyPlayerAllEffect(Duration.EndOfTurn, filter); + game.addEffect(effect, source); + return true; + } + return false; + } +} + class OrissSamiteGuardianCantCastEffect extends ContinuousRuleModifyingEffectImpl { OrissSamiteGuardianCantCastEffect() { @@ -106,38 +141,10 @@ class OrissSamiteGuardianCantCastEffect extends ContinuousRuleModifyingEffectImp public boolean checksEventType(GameEvent event, Game game) { return event.getType() == EventType.CAST_SPELL; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); return player != null && player.getId().equals(event.getPlayerId()); } } - -class OrissSamiteGuardianCantAttackEffect extends ContinuousRuleModifyingEffectImpl { - - OrissSamiteGuardianCantAttackEffect() { - super(Duration.EndOfTurn, Outcome.Detriment); - staticText = ", and creatures that player controls can't attack this turn"; - } - - OrissSamiteGuardianCantAttackEffect(final OrissSamiteGuardianCantAttackEffect effect) { - super(effect); - } - - @Override - public OrissSamiteGuardianCantAttackEffect copy() { - return new OrissSamiteGuardianCantAttackEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DECLARE_ATTACKER; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); - return player != null && player.getId().equals(event.getPlayerId()); - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/homelands/IhsansShade.java b/Mage.Sets/src/mage/sets/homelands/IhsansShade.java new file mode 100644 index 0000000000..3e4dc11a06 --- /dev/null +++ b/Mage.Sets/src/mage/sets/homelands/IhsansShade.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 mage.sets.homelands; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class IhsansShade extends CardImpl { + + private static final FilterCard filter = new FilterCard("white"); + + static { + filter.add(new ColorPredicate(ObjectColor.WHITE)); + } + + public IhsansShade(UUID ownerId) { + super(ownerId, 16, "Ihsan's Shade", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}{B}"); + this.expansionSetCode = "HML"; + this.supertype.add("Legendary"); + this.subtype.add("Shade"); + this.subtype.add("Knight"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Protection from white + this.addAbility(new ProtectionAbility(filter)); + } + + public IhsansShade(final IhsansShade card) { + super(card); + } + + @Override + public IhsansShade copy() { + return new IhsansShade(this); + } +} diff --git a/Mage.Sets/src/mage/sets/iceage/GlacialChasm.java b/Mage.Sets/src/mage/sets/iceage/GlacialChasm.java index 80c73192bb..1ec0ed34f4 100644 --- a/Mage.Sets/src/mage/sets/iceage/GlacialChasm.java +++ b/Mage.Sets/src/mage/sets/iceage/GlacialChasm.java @@ -33,7 +33,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.costs.common.PayLifeCost; import mage.abilities.effects.common.PreventAllDamageToControllerEffect; import mage.abilities.effects.common.SacrificeControllerEffect; -import mage.abilities.effects.common.combat.CantAttackAllAnyPlayerEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; import mage.abilities.keyword.CumulativeUpkeepAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -62,7 +62,7 @@ public class GlacialChasm extends CardImpl { // Creatures you control can't attack. FilterCreaturePermanent filter = new FilterCreaturePermanent("creatures you control"); filter.add(new ControllerPredicate(TargetController.YOU)); - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAllAnyPlayerEffect(Duration.WhileOnBattlefield, filter))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter))); // Prevent all damage that would be dealt to you. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageToControllerEffect(Duration.WhileOnBattlefield))); } diff --git a/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java b/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java new file mode 100644 index 0000000000..92799396ef --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/AlloyGolem.java @@ -0,0 +1,67 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class AlloyGolem extends CardImpl { + + public AlloyGolem(UUID ownerId) { + super(ownerId, 297, "Alloy Golem", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}"); + this.expansionSetCode = "INV"; + this.subtype.add("Golem"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // As Alloy Golem enters the battlefield, choose a color. + // Alloy Golem is the chosen color. + this.addAbility(new EntersBattlefieldAbility(new BecomesColorSourceEffect(Duration.WhileOnBattlefield), + null, true, "As {this} enters the battlefield, choose a color.\n{this} is the chosen color.", "")); + } + + public AlloyGolem(final AlloyGolem card) { + super(card); + } + + @Override + public AlloyGolem copy() { + return new AlloyGolem(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java b/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.java new file mode 100644 index 0000000000..8fb23c7cc3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/ArdentSoldier.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 mage.sets.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.KickerAbility; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; + +/** + * + * @author LoneFox + + */ +public class ArdentSoldier extends CardImpl { + + public ArdentSoldier(UUID ownerId) { + super(ownerId, 3, "Ardent Soldier", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Soldier"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Kicker {2} + this.addAbility(new KickerAbility("{2}")); + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + // If Ardent Soldier was kicked, it enters the battlefield with a +1/+1 counter on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), + KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); + } + + public ArdentSoldier(final ArdentSoldier card) { + super(card); + } + + @Override + public ArdentSoldier copy() { + return new ArdentSoldier(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/BenalishEmissary.java b/Mage.Sets/src/mage/sets/invasion/BenalishEmissary.java new file mode 100644 index 0000000000..b57b7f379a --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/BenalishEmissary.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author LoneFox + + */ +public class BenalishEmissary extends CardImpl { + + public BenalishEmissary(UUID ownerId) { + super(ownerId, 5, "Benalish Emissary", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(4); + + // Kicker {1}{G} + this.addAbility(new KickerAbility("{1}{G}")); + // When Benalish Emissary enters the battlefield, if it was kicked, destroy target land. + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetLandPermanent()); + this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.getInstance(), + "When {this} enters the battlefield, if it was kicked, destroy target land.")); + } + + public BenalishEmissary(final BenalishEmissary card) { + super(card); + } + + @Override + public BenalishEmissary copy() { + return new BenalishEmissary(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java b/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.java new file mode 100644 index 0000000000..d463f15af2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/FaerieSquadron.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.invasion; + + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.counters.CounterType; + +/** + * + * @author LoneFox + + */ +public class FaerieSquadron extends CardImpl { + + public FaerieSquadron(UUID ownerId) { + super(ownerId, 58, "Faerie Squadron", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Faerie"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Kicker {3}{U} + this.addAbility(new KickerAbility("{3}{U}")); + // If Faerie Squadron was kicked, it enters the battlefield with two +1/+1 counters on it and with flying. + Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), + KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with two +1/+1 counters on it and with flying.", ""); + ability.addEffect(new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.WhileOnBattlefield)); + this.addAbility(ability); + } + + public FaerieSquadron(final FaerieSquadron card) { + super(card); + } + + @Override + public FaerieSquadron copy() { + return new FaerieSquadron(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/GlimmeringAngel.java b/Mage.Sets/src/mage/sets/invasion/GlimmeringAngel.java new file mode 100644 index 0000000000..445e6635ef --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/GlimmeringAngel.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + + */ +public class GlimmeringAngel extends CardImpl { + + public GlimmeringAngel(UUID ownerId) { + super(ownerId, 17, "Glimmering Angel", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Angel"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // {U}: Glimmering Angel gains shroud until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(ShroudAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{U}"))); + } + + public GlimmeringAngel(final GlimmeringAngel card) { + super(card); + } + + @Override + public GlimmeringAngel copy() { + return new GlimmeringAngel(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/HoodedKavu.java b/Mage.Sets/src/mage/sets/invasion/HoodedKavu.java new file mode 100644 index 0000000000..183e345912 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/HoodedKavu.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FearAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + + */ +public class HoodedKavu extends CardImpl { + + public HoodedKavu(UUID ownerId) { + super(ownerId, 147, "Hooded Kavu", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "INV"; + this.subtype.add("Kavu"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {B}: Hooded Kavu gains fear until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FearAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{B}"))); + } + + public HoodedKavu(final HoodedKavu card) { + super(card); + } + + @Override + public HoodedKavu copy() { + return new HoodedKavu(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java b/Mage.Sets/src/mage/sets/invasion/KavuAggressor.java new file mode 100644 index 0000000000..b0ce21efa9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/KavuAggressor.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.CantBlockAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.counters.CounterType; + +/** + * + * @author LoneFox + + */ +public class KavuAggressor extends CardImpl { + + public KavuAggressor(UUID ownerId) { + super(ownerId, 148, "Kavu Aggressor", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "INV"; + this.subtype.add("Kavu"); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Kicker {4} + this.addAbility(new KickerAbility("{4}")); + // Kavu Aggressor can't block. + this.addAbility(new CantBlockAbility()); + // If Kavu Aggressor was kicked, it enters the battlefield with a +1/+1 counter on it. + this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), + KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it.", "")); + } + + public KavuAggressor(final KavuAggressor card) { + super(card); + } + + @Override + public KavuAggressor copy() { + return new KavuAggressor(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/KavuChameleon.java b/Mage.Sets/src/mage/sets/invasion/KavuChameleon.java new file mode 100644 index 0000000000..3390be985b --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/KavuChameleon.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CantBeCounteredSourceEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + + */ +public class KavuChameleon extends CardImpl { + + public KavuChameleon(UUID ownerId) { + super(ownerId, 191, "Kavu Chameleon", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + this.expansionSetCode = "INV"; + this.subtype.add("Kavu"); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Kavu Chameleon can't be countered. + this.addAbility(new SimpleStaticAbility(Zone.STACK, new CantBeCounteredSourceEffect())); + // {G}: Kavu Chameleon becomes the color of your choice until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesColorSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{G}"))); + } + + public KavuChameleon(final KavuChameleon card) { + super(card); + } + + @Override + public KavuChameleon copy() { + return new KavuChameleon(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/NoblePanther.java b/Mage.Sets/src/mage/sets/invasion/NoblePanther.java new file mode 100644 index 0000000000..6c36ac2b5b --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/NoblePanther.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + + */ +public class NoblePanther extends CardImpl { + + public NoblePanther(UUID ownerId) { + super(ownerId, 257, "Noble Panther", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{G}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Cat"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // {1}: Noble Panther gains first strike until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{1}"))); + } + + public NoblePanther(final NoblePanther card) { + super(card); + } + + @Override + public NoblePanther copy() { + return new NoblePanther(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/ObsidianAcolyte.java b/Mage.Sets/src/mage/sets/invasion/ObsidianAcolyte.java new file mode 100644 index 0000000000..c66eca2dcf --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/ObsidianAcolyte.java @@ -0,0 +1,86 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class ObsidianAcolyte extends CardImpl { + + private static final FilterCard filter = new FilterCard("black"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + public ObsidianAcolyte(UUID ownerId) { + super(ownerId, 22, "Obsidian Acolyte", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Cleric"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Protection from black + this.addAbility(new ProtectionAbility(filter)); + // {W}: Target creature gains protection from black until end of turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new GainAbilityTargetEffect(new ProtectionAbility(filter), Duration.EndOfTurn), new ManaCostsImpl("{W}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + + } + + public ObsidianAcolyte(final ObsidianAcolyte card) { + super(card); + } + + @Override + public ObsidianAcolyte copy() { + return new ObsidianAcolyte(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java b/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java new file mode 100644 index 0000000000..308b7b9a5f --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/PrisonBarricade.java @@ -0,0 +1,80 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.effects.common.combat.CanAttackAsThoughtItDidntHaveDefenderSourceEffect; +import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.DefenderAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.counters.CounterType; + +/** + * + * @author LoneFox + + */ +public class PrisonBarricade extends CardImpl { + + public PrisonBarricade(UUID ownerId) { + super(ownerId, 25, "Prison Barricade", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Wall"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Defender + this.addAbility(DefenderAbility.getInstance()); + // Kicker {1}{W} + this.addAbility(new KickerAbility("{1}{W}")); + // If Prison Barricade was kicked, it enters the battlefield with a +1/+1 counter on it and with "Prison Barricade can attack as though it didn't have defender." + Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)), + KickedCondition.getInstance(), true, "If {this} was kicked, it enters the battlefield with a +1/+1 counter on it and with \"{this} can attack as though it didn't have defender.\"", ""); + ability.addEffect(new CanAttackAsThoughtItDidntHaveDefenderSourceEffect(Duration.WhileOnBattlefield)); + this.addAbility(ability); + } + + public PrisonBarricade(final PrisonBarricade card) { + super(card); + } + + @Override + public PrisonBarricade copy() { + return new PrisonBarricade(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/RainbowCrow.java b/Mage.Sets/src/mage/sets/invasion/RainbowCrow.java new file mode 100644 index 0000000000..eea212e746 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/RainbowCrow.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + + */ +public class RainbowCrow extends CardImpl { + + public RainbowCrow(UUID ownerId) { + super(ownerId, 69, "Rainbow Crow", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Bird"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // + // {1}: Rainbow Crow becomes the color of your choice until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesColorSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{1}"))); + } + + public RainbowCrow(final RainbowCrow card) { + super(card); + } + + @Override + public RainbowCrow copy() { + return new RainbowCrow(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/RiptideCrab.java b/Mage.Sets/src/mage/sets/invasion/RiptideCrab.java new file mode 100644 index 0000000000..f84917c312 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/RiptideCrab.java @@ -0,0 +1,67 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.DiesTriggeredAbility; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class RiptideCrab extends CardImpl { + + public RiptideCrab(UUID ownerId) { + super(ownerId, 266, "Riptide Crab", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{W}{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Crab"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + // When Riptide Crab dies, draw a card. + this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(1), false)); + } + + public RiptideCrab(final RiptideCrab card) { + super(card); + } + + @Override + public RiptideCrab copy() { + return new RiptideCrab(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/SabertoothNishoba.java b/Mage.Sets/src/mage/sets/invasion/SabertoothNishoba.java new file mode 100644 index 0000000000..1865864369 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/SabertoothNishoba.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.ProtectionAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class SabertoothNishoba extends CardImpl { + + private static final FilterCard filter = new FilterCard("blue and from red"); + + static { + filter.add(Predicates.or(new ColorPredicate(ObjectColor.BLUE), new ColorPredicate(ObjectColor.RED))); + } + + public SabertoothNishoba(UUID ownerId) { + super(ownerId, 268, "Sabertooth Nishoba", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{G}{W}"); + this.expansionSetCode = "INV"; + this.subtype.add("Cat"); + this.subtype.add("Beast"); + this.subtype.add("Warrior"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // protection from blue and from red + this.addAbility(new ProtectionAbility(filter)); + } + + public SabertoothNishoba(final SabertoothNishoba card) { + super(card); + } + + @Override + public SabertoothNishoba copy() { + return new SabertoothNishoba(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/ShivanEmissary.java b/Mage.Sets/src/mage/sets/invasion/ShivanEmissary.java new file mode 100644 index 0000000000..b99c94748f --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/ShivanEmissary.java @@ -0,0 +1,85 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LoneFox + + */ +public class ShivanEmissary extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("black creature"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + + public ShivanEmissary(UUID ownerId) { + super(ownerId, 166, "Shivan Emissary", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Kicker {1}{B} + this.addAbility(new KickerAbility("{1}{B}")); + // When Shivan Emissary enters the battlefield, if it was kicked, destroy target nonblack creature. It can't be regenerated. + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect(true)); + ability.addTarget(new TargetCreaturePermanent(filter)); + this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.getInstance(), + "When {this} enters the battlefield, if it was kicked, destroy target nonblack creature. It can't be regenerated.")); + } + + public ShivanEmissary(final ShivanEmissary card) { + super(card); + } + + @Override + public ShivanEmissary copy() { + return new ShivanEmissary(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/ShorelineRaider.java b/Mage.Sets/src/mage/sets/invasion/ShorelineRaider.java new file mode 100644 index 0000000000..1e12aeb986 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/ShorelineRaider.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author LoneFox + + */ +public class ShorelineRaider extends CardImpl { + + private static final FilterCard filter = new FilterCard("Kavu"); + + static { + filter.add(new SubtypePredicate("Kavu")); + } + + + public ShorelineRaider(UUID ownerId) { + super(ownerId, 73, "Shoreline Raider", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Merfolk"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Protection from Kavu + this.addAbility(new ProtectionAbility(filter)); + } + + public ShorelineRaider(final ShorelineRaider card) { + super(card); + } + + @Override + public ShorelineRaider copy() { + return new ShorelineRaider(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/TolarianEmissary.java b/Mage.Sets/src/mage/sets/invasion/TolarianEmissary.java new file mode 100644 index 0000000000..91d7eff0e1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/TolarianEmissary.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.common.TargetEnchantmentPermanent; + +/** + * + * @author LoneFox + + */ +public class TolarianEmissary extends CardImpl { + + public TolarianEmissary(UUID ownerId) { + super(ownerId, 81, "Tolarian Emissary", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{U}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(2); + + // Kicker {1}{W} + this.addAbility(new KickerAbility("{1}{W}")); + // Flying + this.addAbility(FlyingAbility.getInstance()); + // When Tolarian Emissary enters the battlefield, if it was kicked, destroy target enchantment. + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new DestroyTargetEffect()); + ability.addTarget(new TargetEnchantmentPermanent()); + this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.getInstance(), + "When {this} enters the battlefield, if it was kicked, destroy target enchantment.")); + } + + public TolarianEmissary(final TolarianEmissary card) { + super(card); + } + + @Override + public TolarianEmissary copy() { + return new TolarianEmissary(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/UrborgDrake.java b/Mage.Sets/src/mage/sets/invasion/UrborgDrake.java new file mode 100644 index 0000000000..70b2e6962c --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/UrborgDrake.java @@ -0,0 +1,66 @@ +/* + * 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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksEachTurnStaticAbility; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class UrborgDrake extends CardImpl { + + public UrborgDrake(UUID ownerId) { + super(ownerId, 283, "Urborg Drake", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{U}{B}"); + this.expansionSetCode = "INV"; + this.subtype.add("Drake"); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Urborg Drake attacks each turn if able. + this.addAbility(new AttacksEachTurnStaticAbility()); + } + + public UrborgDrake(final UrborgDrake card) { + super(card); + } + + @Override + public UrborgDrake copy() { + return new UrborgDrake(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/UrborgEmissary.java b/Mage.Sets/src/mage/sets/invasion/UrborgEmissary.java new file mode 100644 index 0000000000..8ebec497e4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/UrborgEmissary.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbility; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.condition.common.KickedCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.KickerAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.target.TargetPermanent; + +/** + * + * @author LoneFox + + */ +public class UrborgEmissary extends CardImpl { + + public UrborgEmissary(UUID ownerId) { + super(ownerId, 131, "Urborg Emissary", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "INV"; + this.subtype.add("Human"); + this.subtype.add("Wizard"); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // Kicker {1}{U} + this.addAbility(new KickerAbility("{1}{U}")); + // When Urborg Emissary enters the battlefield, if it was kicked, return target permanent to its owner's hand. + TriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect()); + ability.addTarget(new TargetPermanent()); + this.addAbility(new ConditionalTriggeredAbility(ability, KickedCondition.getInstance(), + "When {this} enters the battlefield, if it was kicked, return target permanent to its owner's hand.")); + } + + public UrborgEmissary(final UrborgEmissary card) { + super(card); + } + + @Override + public UrborgEmissary copy() { + return new UrborgEmissary(this); + } +} diff --git a/Mage.Sets/src/mage/sets/invasion/YavimayaBarbarian.java b/Mage.Sets/src/mage/sets/invasion/YavimayaBarbarian.java new file mode 100644 index 0000000000..7ac05ce33a --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/YavimayaBarbarian.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.invasion; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.keyword.ProtectionAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.ColorPredicate; + +/** + * + * @author LoneFox + + */ +public class YavimayaBarbarian extends CardImpl { + + private static final FilterCard filter = new FilterCard("blue"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLUE)); + } + + public YavimayaBarbarian(UUID ownerId) { + super(ownerId, 290, "Yavimaya Barbarian", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{R}{G}"); + this.expansionSetCode = "INV"; + this.subtype.add("Elf"); + this.subtype.add("Barbarian"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Protection from blue + this.addAbility(new ProtectionAbility(filter)); + } + + public YavimayaBarbarian(final YavimayaBarbarian card) { + super(card); + } + + @Override + public YavimayaBarbarian copy() { + return new YavimayaBarbarian(this); + } +} diff --git a/Mage.Sets/src/mage/sets/legends/AkronLegionnaire.java b/Mage.Sets/src/mage/sets/legends/AkronLegionnaire.java index 307b1ff995..270a51c208 100644 --- a/Mage.Sets/src/mage/sets/legends/AkronLegionnaire.java +++ b/Mage.Sets/src/mage/sets/legends/AkronLegionnaire.java @@ -31,7 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.combat.CantAttackAllAnyPlayerEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; @@ -67,7 +67,7 @@ public class AkronLegionnaire extends CardImpl { this.toughness = new MageInt(4); // Except for creatures named Akron Legionnaire and artifact creatures, creatures you control can't attack. - Effect effect = new CantAttackAllAnyPlayerEffect(Duration.WhileOnBattlefield, filter); + Effect effect = new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter); effect.setText("Except for creatures named Akron Legionnaire and artifact creatures, creatures you control can't attack"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); diff --git a/Mage.Sets/src/mage/sets/legends/Moat.java b/Mage.Sets/src/mage/sets/legends/Moat.java index bcba86caf4..260b367eae 100644 --- a/Mage.Sets/src/mage/sets/legends/Moat.java +++ b/Mage.Sets/src/mage/sets/legends/Moat.java @@ -29,7 +29,7 @@ package mage.sets.legends; import java.util.UUID; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.common.combat.CantAttackAllAnyPlayerEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -58,7 +58,7 @@ public class Moat extends CardImpl { // Creatures without flying can't attack. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAllAnyPlayerEffect(Duration.WhileOnBattlefield, filter))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter))); } public Moat(final Moat card) { diff --git a/Mage.Sets/src/mage/sets/magic2011/StormtideLeviathan.java b/Mage.Sets/src/mage/sets/magic2011/StormtideLeviathan.java index 67605e8c76..d4b4fce8aa 100644 --- a/Mage.Sets/src/mage/sets/magic2011/StormtideLeviathan.java +++ b/Mage.Sets/src/mage/sets/magic2011/StormtideLeviathan.java @@ -33,7 +33,7 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.common.combat.CantAttackAllAnyPlayerEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.IslandwalkAbility; import mage.abilities.mana.BlueManaAbility; @@ -80,7 +80,7 @@ public class StormtideLeviathan extends CardImpl { // All lands are Islands in addition to their other types. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new StormtideLeviathanEffect())); // Creatures without flying or islandwalk can't attack. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAllAnyPlayerEffect(Duration.WhileOnBattlefield, filter))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter))); } diff --git a/Mage.Sets/src/mage/sets/masterseditionii/IhsansShade.java b/Mage.Sets/src/mage/sets/masterseditionii/IhsansShade.java new file mode 100644 index 0000000000..c252e9874c --- /dev/null +++ b/Mage.Sets/src/mage/sets/masterseditionii/IhsansShade.java @@ -0,0 +1,55 @@ +/* + * 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.masterseditionii; + +import java.util.UUID; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + + */ +public class IhsansShade extends mage.sets.homelands.IhsansShade { + + public IhsansShade(UUID ownerId) { + super(ownerId); + this.cardNumber = 95; + this.expansionSetCode = "ME2"; + this.rarity = Rarity.RARE; + } + + public IhsansShade(final IhsansShade card) { + super(card); + } + + @Override + public IhsansShade copy() { + return new IhsansShade(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/CrumblingSanctuary.java b/Mage.Sets/src/mage/sets/mercadianmasques/CrumblingSanctuary.java new file mode 100644 index 0000000000..69087dd02a --- /dev/null +++ b/Mage.Sets/src/mage/sets/mercadianmasques/CrumblingSanctuary.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.mercadianmasques; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.PreventionEffectImpl; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; + +/** + * + * @author LoneFox + + */ +public class CrumblingSanctuary extends CardImpl { + + public CrumblingSanctuary(UUID ownerId) { + super(ownerId, 292, "Crumbling Sanctuary", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{5}"); + this.expansionSetCode = "MMQ"; + + // If damage would be dealt to a player, that player exiles that many cards from the top of his or her library instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CrumblingSanctuaryEffect())); + } + + public CrumblingSanctuary(final CrumblingSanctuary card) { + super(card); + } + + @Override + public CrumblingSanctuary copy() { + return new CrumblingSanctuary(this); + } +} + +class CrumblingSanctuaryEffect extends PreventionEffectImpl { + + public CrumblingSanctuaryEffect() { + super(Duration.WhileOnBattlefield, Integer.MAX_VALUE, false, false); + staticText = "If damage would be dealt to a player, that player exiles that many cards from the top of his or her library instead."; + } + + public CrumblingSanctuaryEffect(final CrumblingSanctuaryEffect effect) { + super(effect); + } + + @Override + public CrumblingSanctuaryEffect copy() { + return new CrumblingSanctuaryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + int amount = event.getAmount(); + Player player = game.getPlayer(event.getTargetId()); + if(player != null) { + preventDamageAction(event, source, game); + player.moveCards(player.getLibrary().getTopCards(game, amount), Zone.LIBRARY, Zone.EXILED, source, game); + return true; + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return super.applies(event, source, game) && (game.getPlayer(event.getTargetId()) != null); + } + +} diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/LavaRunner.java b/Mage.Sets/src/mage/sets/mercadianmasques/LavaRunner.java new file mode 100644 index 0000000000..3ab5e2cfe7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mercadianmasques/LavaRunner.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.mercadianmasques; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.keyword.HasteAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.common.FilterLandPermanent; +import mage.game.Game; +import mage.game.events.GameEvent.EventType; +import mage.game.events.GameEvent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LoneFox + + */ +public class LavaRunner extends CardImpl { + + public LavaRunner(UUID ownerId) { + super(ownerId, 200, "Lava Runner", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{R}{R}"); + this.expansionSetCode = "MMQ"; + this.subtype.add("Lizard"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Haste + this.addAbility(HasteAbility.getInstance()); + // Whenever Lava Runner becomes the target of a spell or ability, that spell or ability's controller sacrifices a land. + this.addAbility(new LavaRunnerAbility()); + } + + public LavaRunner(final LavaRunner card) { + super(card); + } + + @Override + public LavaRunner copy() { + return new LavaRunner(this); + } +} + +class LavaRunnerAbility extends TriggeredAbilityImpl { + + public LavaRunnerAbility() { + super(Zone.BATTLEFIELD, new SacrificeEffect(new FilterLandPermanent(), 1, ""), false); + } + + public LavaRunnerAbility(final LavaRunnerAbility ability) { + super(ability); + } + + @Override + public LavaRunnerAbility copy() { + return new LavaRunnerAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == EventType.TARGETED; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if(event.getTargetId().equals(this.getSourceId())) { + getEffects().get(0).setTargetPointer(new FixedTarget(event.getPlayerId())); + return true; + } + return false; + } + + @Override + public String getRule() { + return "Whenever {this} becomes the target of a spell or ability, that spell or ability's controller sacrifices a land."; + } +} diff --git a/Mage.Sets/src/mage/sets/odyssey/DirtyWererat.java b/Mage.Sets/src/mage/sets/odyssey/DirtyWererat.java index 49de38d261..c29c20bb2f 100644 --- a/Mage.Sets/src/mage/sets/odyssey/DirtyWererat.java +++ b/Mage.Sets/src/mage/sets/odyssey/DirtyWererat.java @@ -66,16 +66,18 @@ public class DirtyWererat extends CardImpl { // {B}, Discard a card: Regenerate Dirty Wererat. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{B}")); ability.addCost(new DiscardCardCost()); + this.addAbility(ability); + // Threshold - As long as seven or more cards are in your graveyard, Dirty Wererat gets +2/+2 and can't block. Ability thresholdAbility = new SimpleStaticAbility(Zone.BATTLEFIELD, - new ConditionalContinuousEffect( - new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), - new CardsInControllerGraveCondition(7), - "Threshold - If seven or more cards are in your graveyard, Dirty Wererat gets +2/+2 and can't block" + new ConditionalContinuousEffect( + new BoostSourceEffect(2, 2, Duration.WhileOnBattlefield), + new CardsInControllerGraveCondition(7), + "Threshold - If seven or more cards are in your graveyard, Dirty Wererat gets +2/+2 and can't block" )); Effect effect = new ConditionalRestrictionEffect( - new CantBlockSourceEffect(Duration.WhileOnBattlefield), - new CardsInControllerGraveCondition(7)); + new CantBlockSourceEffect(Duration.WhileOnBattlefield), + new CardsInControllerGraveCondition(7)); effect.setText("and can't block"); thresholdAbility.addEffect(effect); this.addAbility(thresholdAbility); diff --git a/Mage.Sets/src/mage/sets/odyssey/WildMongrel.java b/Mage.Sets/src/mage/sets/odyssey/WildMongrel.java index 34bef98fed..99fa8ef85f 100644 --- a/Mage.Sets/src/mage/sets/odyssey/WildMongrel.java +++ b/Mage.Sets/src/mage/sets/odyssey/WildMongrel.java @@ -32,23 +32,15 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardTargetCost; -import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.Effect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.abilities.effects.common.continuous.BecomesColorTargetEffect; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; import mage.cards.CardImpl; -import mage.choices.ChoiceColor; 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.permanent.Permanent; -import mage.players.Player; import mage.target.common.TargetCardInHand; -import mage.target.targetpointer.FixedTarget; /** * @author magenoxx_at_gmail.com @@ -67,7 +59,9 @@ public class WildMongrel extends CardImpl { Effect effect = new BoostSourceEffect(1, 1, Duration.EndOfTurn); effect.setText("{this} gets +1/+1"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new DiscardTargetCost(new TargetCardInHand())); - ability.addEffect(new ChangeColorEffect()); + effect = new BecomesColorSourceEffect(Duration.EndOfTurn); + effect.setText("and becomes the color of your choice until end of turn."); + ability.addEffect(effect); this.addAbility(ability); } @@ -80,37 +74,3 @@ public class WildMongrel extends CardImpl { return new WildMongrel(this); } } - -class ChangeColorEffect extends OneShotEffect { - - public ChangeColorEffect() { - super(Outcome.Neutral); - staticText = "and becomes the color of your choice until end of turn"; - } - - public ChangeColorEffect(final ChangeColorEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - Permanent wildMongrel = game.getPermanent(source.getSourceId()); - if (player != null && wildMongrel != null) { - ChoiceColor colorChoice = new ChoiceColor(); - if (player.choose(Outcome.Neutral, colorChoice, game)) { - game.informPlayers(wildMongrel.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice()); - ContinuousEffect effect = new BecomesColorTargetEffect(colorChoice.getColor(), Duration.EndOfTurn, "is " + colorChoice.getChoice()); - effect.setTargetPointer(new FixedTarget(source.getSourceId())); - game.addEffect(effect, source); - return true; - } - } - return false; - } - - @Override - public ChangeColorEffect copy() { - return new ChangeColorEffect(this); - } -} diff --git a/Mage.Sets/src/mage/sets/planeshift/CalderaKavu.java b/Mage.Sets/src/mage/sets/planeshift/CalderaKavu.java new file mode 100644 index 0000000000..3ef6d7a9f1 --- /dev/null +++ b/Mage.Sets/src/mage/sets/planeshift/CalderaKavu.java @@ -0,0 +1,70 @@ +/* + * 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.planeshift; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.continuous.BecomesColorSourceEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author LoneFox + + */ +public class CalderaKavu extends CardImpl { + + public CalderaKavu(UUID ownerId) { + super(ownerId, 58, "Caldera Kavu", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{R}"); + this.expansionSetCode = "PLS"; + this.subtype.add("Kavu"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {1}{B}: Caldera Kavu gets +1/+1 until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{1}{B}"))); + // {G}: Caldera Kavu becomes the color of your choice until end of turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesColorSourceEffect(Duration.EndOfTurn), new ManaCostsImpl("{G}"))); + } + + public CalderaKavu(final CalderaKavu card) { + super(card); + } + + @Override + public CalderaKavu copy() { + return new CalderaKavu(this); + } +} diff --git a/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java b/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java index 38ad404ce2..6c87841a9e 100644 --- a/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java +++ b/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java @@ -33,7 +33,7 @@ import mage.abilities.Ability; import mage.abilities.condition.common.KickedCondition; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.combat.CantAttackAllAnyPlayerEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerAllEffect; import mage.abilities.keyword.KickerAbility; import mage.cards.CardImpl; import mage.constants.CardType; @@ -126,7 +126,7 @@ class OrimsChantEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && KickedCondition.getInstance().apply(game, source)) { - game.addEffect(new CantAttackAllAnyPlayerEffect(Duration.EndOfTurn, new FilterCreaturePermanent("creatures")), source); + game.addEffect(new CantAttackAnyPlayerAllEffect(Duration.EndOfTurn, new FilterCreaturePermanent("creatures")), source); return true; } return false; diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java index 0176bd77ec..9ad1c7827b 100644 --- a/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/CowedByWisdom.java @@ -30,8 +30,9 @@ package mage.sets.saviorsofkamigawa; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.PayCostToAttackBlockEffectImpl; import mage.abilities.effects.common.AttachEffect; import mage.abilities.keyword.EnchantAbility; import mage.cards.CardImpl; @@ -64,9 +65,9 @@ public class CowedByWisdom extends CardImpl { this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); this.addAbility(ability); - + // Enchanted creature can't attack or block unless its controller pays {1} for each card in your hand. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CowedByWisdomEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CowedByWisdomayCostToAttackBlockEffect())); } public CowedByWisdom(final CowedByWisdom card) { @@ -79,65 +80,35 @@ public class CowedByWisdom extends CardImpl { } } -class CowedByWisdomEffect extends ReplacementEffectImpl { +class CowedByWisdomayCostToAttackBlockEffect extends PayCostToAttackBlockEffectImpl { - private static final String effectText = "Enchanted creature can't attack or block unless its controller pays {1} for each card in your hand"; - - CowedByWisdomEffect ( ) { - super(Duration.WhileOnBattlefield, Outcome.Neutral); - staticText = effectText; + CowedByWisdomayCostToAttackBlockEffect() { + super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK_AND_BLOCK, null); + staticText = "Enchanted creature can't attack or block unless its controller pays {1} for each card in your hand"; } - CowedByWisdomEffect ( CowedByWisdomEffect effect ) { + CowedByWisdomayCostToAttackBlockEffect(CowedByWisdomayCostToAttackBlockEffect effect) { super(effect); } @Override - public boolean apply(Game game, Ability source) { - throw new UnsupportedOperationException("Not supported."); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.DECLARE_ATTACKER || event.getType().equals(GameEvent.EventType.DECLARE_BLOCKER); + public Cost getCostToPay(GameEvent event, Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && !controller.getHand().isEmpty()) { + return new GenericManaCost(controller.getHand().size()); + } + return null; } @Override public boolean applies(GameEvent event, Ability source, Game game) { - Permanent enchantment = game.getPermanent(event.getSourceId()); - return enchantment != null && enchantment.getAttachments().contains(source.getSourceId()); + Permanent enchantment = game.getPermanent(source.getSourceId()); + return enchantment != null && enchantment.getAttachedTo().equals(event.getSourceId()); } - + @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - Player player = game.getPlayer(event.getPlayerId()); - Player controller = game.getPlayer(source.getControllerId()); - if (player != null && controller != null) { - if (controller.getHand().isEmpty()) { - return false; - } - String chooseText; - int cardsInHand = controller.getHand().size(); - if (event.getType().equals(GameEvent.EventType.DECLARE_ATTACKER)) { - chooseText = "Pay {" + cardsInHand + "} to attack?"; - } else { - chooseText = "Pay {" + cardsInHand + "} to block?"; - } - ManaCostsImpl attackBlockTax = new ManaCostsImpl("{" + cardsInHand + "}"); - if (attackBlockTax.canPay(source, source.getSourceId(), event.getPlayerId(), game) - && player.chooseUse(Outcome.Neutral, chooseText, source, game)) { - if (attackBlockTax.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { - return false; - } - } - return true; - } - return false; - } - - @Override - public CowedByWisdomEffect copy() { - return new CowedByWisdomEffect(this); + public CowedByWisdomayCostToAttackBlockEffect copy() { + return new CowedByWisdomayCostToAttackBlockEffect(this); } } diff --git a/Mage.Sets/src/mage/sets/seventhedition/SouthernPaladin.java b/Mage.Sets/src/mage/sets/seventhedition/SouthernPaladin.java index 4a7cacace6..587f6b8ae1 100644 --- a/Mage.Sets/src/mage/sets/seventhedition/SouthernPaladin.java +++ b/Mage.Sets/src/mage/sets/seventhedition/SouthernPaladin.java @@ -50,7 +50,7 @@ import mage.target.TargetPermanent; */ public class SouthernPaladin extends CardImpl { - private static final FilterPermanent filter = new FilterPermanent("red"); + private static final FilterPermanent filter = new FilterPermanent("red permanent"); static { filter.add(new ColorPredicate(ObjectColor.RED)); diff --git a/Mage.Sets/src/mage/sets/tempest/LightOfDay.java b/Mage.Sets/src/mage/sets/tempest/LightOfDay.java index 17348a8cb6..c76f00a824 100644 --- a/Mage.Sets/src/mage/sets/tempest/LightOfDay.java +++ b/Mage.Sets/src/mage/sets/tempest/LightOfDay.java @@ -28,20 +28,16 @@ package mage.sets.tempest; import java.util.UUID; -import mage.abilities.Ability; +import mage.ObjectColor; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.combat.CantAttackBlockAllEffect; 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.game.events.GameEvent.EventType; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.ColorPredicate; /** * @@ -49,13 +45,19 @@ import mage.players.Player; */ public class LightOfDay extends CardImpl { + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Black creatures"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + public LightOfDay(UUID ownerId) { super(ownerId, 239, "Light of Day", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}"); this.expansionSetCode = "TMP"; - // Black creatures can't attack or block. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LightOfDayEffect())); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockAllEffect(Duration.WhileOnBattlefield, filter))); + } public LightOfDay(final LightOfDay card) { @@ -67,45 +69,3 @@ public class LightOfDay extends CardImpl { return new LightOfDay(this); } } - -class LightOfDayEffect extends ReplacementEffectImpl { - - public LightOfDayEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - staticText = "Black creatures can't attack or block"; - } - - public LightOfDayEffect(final LightOfDayEffect effect) { - super(effect); - } - - @Override - public LightOfDayEffect copy() { - return new LightOfDayEffect(this); - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == EventType.DECLARE_ATTACKER || event.getType() == EventType.DECLARE_BLOCKER; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Permanent permanent = game.getPermanent(event.getSourceId()); - if (permanent != null) { - Player player = game.getPlayer(source.getControllerId()); - if (player.getInRange().contains(permanent.getControllerId())) { - if (permanent.getColor(game).isBlack()) { - return true; - } - } - } - return false; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/theros/MedomaiTheAgeless.java b/Mage.Sets/src/mage/sets/theros/MedomaiTheAgeless.java index d65c2a269e..fa4074f436 100644 --- a/Mage.Sets/src/mage/sets/theros/MedomaiTheAgeless.java +++ b/Mage.Sets/src/mage/sets/theros/MedomaiTheAgeless.java @@ -35,7 +35,7 @@ import mage.abilities.common.SimpleStaticAbility; import mage.abilities.condition.Condition; import mage.abilities.decorator.ConditionalRestrictionEffect; import mage.abilities.effects.Effect; -import mage.abilities.effects.common.combat.CantAttackAllSourceEffect; +import mage.abilities.effects.common.combat.CantAttackAnyPlayerSourceEffect; import mage.abilities.effects.common.turn.AddExtraTurnControllerEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; @@ -65,7 +65,7 @@ public class MedomaiTheAgeless extends CardImpl { // Whenever Medomai the Ageless deals combat damage to a player, take an extra turn after this one. this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new AddExtraTurnControllerEffect(), false)); // Medomai the Ageless can't attack during extra turns. - Effect effect = new ConditionalRestrictionEffect(new CantAttackAllSourceEffect(Duration.WhileOnBattlefield), ExtraTurnCondition.getInstance()); + Effect effect = new ConditionalRestrictionEffect(new CantAttackAnyPlayerSourceEffect(Duration.WhileOnBattlefield), ExtraTurnCondition.getInstance()); effect.setText("{this} can't attack during extra turns"); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); } diff --git a/Mage.Sets/src/mage/sets/torment/NantukoCultivator.java b/Mage.Sets/src/mage/sets/torment/NantukoCultivator.java new file mode 100644 index 0000000000..56b910855e --- /dev/null +++ b/Mage.Sets/src/mage/sets/torment/NantukoCultivator.java @@ -0,0 +1,113 @@ +/* + * 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.torment; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.counters.CounterType; +import mage.filter.common.FilterLandCard; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInHand; + +/** + * + * @author LoneFox + + */ +public class NantukoCultivator extends CardImpl { + + public NantukoCultivator(UUID ownerId) { + super(ownerId, 133, "Nantuko Cultivator", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.expansionSetCode = "TOR"; + this.subtype.add("Insect"); + this.subtype.add("Druid"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Nantuko Cultivator enters the battlefield, you may discard any number of land cards. Put that many +1/+1 counters on Nantuko Cultivator and draw that many cards. + this.addAbility(new EntersBattlefieldTriggeredAbility(new NantukoCultivatorEffect(), true)); + } + + public NantukoCultivator(final NantukoCultivator card) { + super(card); + } + + @Override + public NantukoCultivator copy() { + return new NantukoCultivator(this); + } +} + +class NantukoCultivatorEffect extends OneShotEffect { + + public NantukoCultivatorEffect() { + super(Outcome.BoostCreature); + staticText = "you may discard any number of land cards. Put that many +1/+1 counters on {this} and draw that many cards."; + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if(player != null) { + TargetCardInHand toDiscard = new TargetCardInHand(0, Integer.MAX_VALUE, new FilterLandCard()); + if(player.chooseTarget(Outcome.Discard, toDiscard, source, game)) { + int count = 0; + for(UUID targetId: toDiscard.getTargets()) { + player.discard(game.getCard(targetId), source, game); + count++; + } + Permanent permanent = game.getPermanent(source.getSourceId()); + if(permanent != null) { + permanent.addCounters(CounterType.P1P1.createInstance(count), game); + } + player.drawCards(count, game); + } + return true; + } + return false; + } + + public NantukoCultivatorEffect(final NantukoCultivatorEffect effect) { + super(effect); + } + + @Override + public NantukoCultivatorEffect copy() { + return new NantukoCultivatorEffect(this); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java index 0de986e421..f7172974d0 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/MycosynthGolemTest.java @@ -25,7 +25,6 @@ * 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.other; import mage.constants.PhaseStep; @@ -41,17 +40,13 @@ import org.mage.test.serverside.base.CardTestPlayerBase; */ public class MycosynthGolemTest extends CardTestPlayerBase { - /** - * Mycosynth Golem - * Artifact Creature — Golem 4/5, 11 (11) - * Affinity for artifacts (This spell costs {1} less to cast for each - * artifact you control.) - * Artifact creature spells you cast have affinity for artifacts. (They cost - * {1} less to cast for each artifact you control.) + /** + * Mycosynth Golem Artifact Creature — Golem 4/5, 11 (11) Affinity for + * artifacts (This spell costs {1} less to cast for each artifact you + * control.) Artifact creature spells you cast have affinity for artifacts. + * (They cost {1} less to cast for each artifact you control.) * */ - - // @Ignore // at this time player.getPlayable() does not account for spells that gain abilities @Test public void testSpellsAffinity() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); @@ -60,13 +55,13 @@ public class MycosynthGolemTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Alpha Myr"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Alpha Myr"); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); assertPermanentCount(playerA, "Alpha Myr", 1); assertHandCount(playerA, "Alpha Myr", 0); - + Permanent mountain = getPermanent("Mountain", playerA); Permanent forest = getPermanent("Forest", playerA); int tappedLands = 0; @@ -79,5 +74,5 @@ public class MycosynthGolemTest extends CardTestPlayerBase { Assert.assertEquals("only one land may be tapped because the cost reduction", 1, tappedLands); } - + } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java index 795122d82e..bce6619569 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/other/SoulfireGrandMasterTest.java @@ -25,7 +25,6 @@ * 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.other; import mage.constants.PhaseStep; @@ -39,17 +38,13 @@ import org.mage.test.serverside.base.CardTestPlayerBase; */ public class SoulfireGrandMasterTest extends CardTestPlayerBase { - /** - * Soulfire Grand Master - * Creature - Human Monk 2/2, 1W (2) - * Lifelink - * Instant and sorcery spells you control have lifelink. - * {2}{U/R}{U/R}: The next time you cast an instant or sorcery spell from - * your hand this turn, put that card into your hand instead of into your - * graveyard as it resolves. + /** + * Soulfire Grand Master Creature - Human Monk 2/2, 1W (2) Lifelink Instant + * and sorcery spells you control have lifelink. {2}{U/R}{U/R}: The next + * time you cast an instant or sorcery spell from your hand this turn, put + * that card into your hand instead of into your graveyard as it resolves. * */ - @Test public void testSpellsGainLifelink() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); @@ -57,7 +52,7 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Lightning Bolt"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB); - + setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); @@ -75,9 +70,9 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Lightning Bolt"); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{U/R}{U/R}:"); - + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", playerB); - + setStopAt(1, PhaseStep.END_TURN); execute(); @@ -87,12 +82,11 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { assertLife(playerB, 17); } + /** - * Test with Searing Blood - * If the delayed triggered ability triggers, it has to give - * life from lifelink because the source is still Searing Blood + * Test with Searing Blood If the delayed triggered ability triggers, it has + * to give life from lifelink because the source is still Searing Blood */ - // @Ignore // Does not work because as the delayed triggered ability resolves, the source card is no longer on the stack and @Test public void testSearingBlood1() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2); @@ -117,9 +111,8 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { } /** - * Test with Searing Blood - * If the delayed triggered ability triggers, it has to give - * life from lifelink because the source is still Searing Blood + * Test with Searing Blood If the delayed triggered ability triggers, it has + * to give life from lifelink because the source is still Searing Blood */ @Test public void testSearinBlood2() { @@ -146,12 +139,12 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { assertLife(playerB, 17); assertLife(playerA, 28); // +2 from damage to Silvercoat Lion + 3 from Lighning Bolt + 3 from damage to Player B from Searing Blood - } - + } + /** * Test copied instant spell gives also life - * - */ + * + */ @Test public void testCopySpell() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 4); @@ -172,20 +165,18 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Lightning Bolt", 1); assertLife(playerB, 14); - assertLife(playerA, 26); + assertLife(playerA, 26); + + } - } - - /** * Test damage of activated ability of a permanent does not gain lifelink - * + * */ - @Test public void testActivatedAbility() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3); - + addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master", 1); // {3}, {T}: Rod of Ruin deals 1 damage to target creature or player. @@ -200,21 +191,22 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { assertPermanentCount(playerA, "Rod of Ruin", 1); assertLife(playerB, 19); - assertLife(playerA, 20); + assertLife(playerA, 20); + + } - } /** - * Test that if Soulfire Grand Master has left the battlefield - * spell has no longer lifelink + * Test that if Soulfire Grand Master has left the battlefield spell has no + * longer lifelink */ - + @Test public void testSoulfireLeft() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); - + addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master", 1); - + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); @@ -229,28 +221,30 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Soulfire Grand Master", 1); assertLife(playerB, 17); - assertLife(playerA, 20); + assertLife(playerA, 20); + + } - } /** - * I activated the ability of Soulfire grand master, it resolved, then i cast Stoke the Flames - * on Whisperwood Elemental, my opponenet sacrificed the elemental, so stoke didnt resolve, - * but i still got the life from lifelink. + * I activated the ability of Soulfire grand master, it resolved, then i + * cast Stoke the Flames on Whisperwood Elemental, my opponenet sacrificed + * the elemental, so stoke didnt resolve, but i still got the life from + * lifelink. */ - + @Test public void testSoulfireStokeTheFlames() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8); - + addCard(Zone.HAND, playerA, "Stoke the Flames"); addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master", 1); - + addCard(Zone.BATTLEFIELD, playerB, "Whisperwood Elemental", 1); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{U/R}{U/R}:"); - + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Stoke the Flames", "Whisperwood Elemental"); - activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice {this}", null ,"{this} deals 4 damage"); + activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Sacrifice {this}", null, "{this} deals 4 damage"); setStopAt(1, PhaseStep.END_TURN); execute(); @@ -259,29 +253,28 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { assertGraveyardCount(playerB, "Whisperwood Elemental", 1); assertLife(playerB, 20); - assertLife(playerA, 20); + assertLife(playerA, 20); - } - - /** - * Check if second ability resolved, the next spell that is counterer - * won't go to hand back because it did not resolve - * + } + + /** + * Check if second ability resolved, the next spell that is counterer won't + * go to hand back because it did not resolve + * */ - @Test public void testSoulfireCounteredSpellDontGoesBack() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 8); - + addCard(Zone.HAND, playerA, "Stoke the Flames"); addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master", 1); - + addCard(Zone.BATTLEFIELD, playerB, "Island", 2); addCard(Zone.HAND, playerB, "Counterspell", 1); addCard(Zone.BATTLEFIELD, playerB, "Whisperwood Elemental", 1); activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{U/R}{U/R}:"); - + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Stoke the Flames", "Whisperwood Elemental"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Counterspell", "Stoke the Flames"); @@ -292,26 +285,28 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { assertGraveyardCount(playerA, "Stoke the Flames", 1); // no legal target left so the spell is countered and goes to graveyard assertLife(playerB, 20); - assertLife(playerA, 20); + assertLife(playerA, 20); - } - /** - * With a Soulfire Grand Master in play, Deflecting Palm doesn't gain the caster life. - * It should as it has lifelink, and it's Deflecting Palm (an instant) dealing damage. - * I was playing against a human in Standard Constructed. - * + } + + /** + * With a Soulfire Grand Master in play, Deflecting Palm doesn't gain the + * caster life. It should as it has lifelink, and it's Deflecting Palm (an + * instant) dealing damage. I was playing against a human in Standard + * Constructed. + * */ - + @Test public void testWithDeflectingPalm() { addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1); addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); // Instant -{R}{W} - // The next time a source of your choice would deal damage to you this turn, prevent that damage. + // The next time a source of your choice would deal damage to you this turn, prevent that damage. // If damage is prevented this way, Deflecting Palm deals that much damage to that source's controller. addCard(Zone.HAND, playerA, "Deflecting Palm"); addCard(Zone.BATTLEFIELD, playerA, "Soulfire Grand Master", 1); - + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); addCard(Zone.HAND, playerB, "Lightning Bolt", 1); @@ -323,10 +318,10 @@ public class SoulfireGrandMasterTest extends CardTestPlayerBase { execute(); assertGraveyardCount(playerB, "Lightning Bolt", 1); - assertGraveyardCount(playerA, "Deflecting Palm", 1); + assertGraveyardCount(playerA, "Deflecting Palm", 1); assertLife(playerB, 17); assertLife(playerA, 23); // damage is prevented + lifelink + 3 - } + } } diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/GainedDiesTriggersTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/GainedDiesTriggersTest.java new file mode 100644 index 0000000000..a937b7ef34 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/triggers/dies/GainedDiesTriggersTest.java @@ -0,0 +1,69 @@ +/* + * 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.triggers.dies; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class GainedDiesTriggersTest extends CardTestPlayerBase { + + /** + * Tests that gained dies triggers work as intended + */ + @Test + public void testInfernalScarring() { + addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2); + addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 3); + + // Enchant creature + // Enchanted creature gets +2/+0 and has "When this creature dies, draw a card." + addCard(Zone.HAND, playerA, "Infernal Scarring", 1); + + addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); + addCard(Zone.HAND, playerB, "Lightning Bolt", 1); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Infernal Scarring", "Silvercoat Lion"); + + // Destroy all creatures. + castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", "Silvercoat Lion"); + + setStopAt(1, PhaseStep.END_TURN); + execute(); + + assertGraveyardCount(playerA, "Silvercoat Lion", 1); + assertGraveyardCount(playerB, "Lightning Bolt", 1); + assertHandCount(playerA, 1); // draw a card for dying Lion + } + +} diff --git a/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java b/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java index 20ae54c777..7767ea553c 100644 --- a/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java +++ b/Mage/src/mage/abilities/decorator/ConditionalRestrictionEffect.java @@ -33,7 +33,6 @@ import mage.abilities.condition.FixedCondition; import mage.abilities.condition.LockedInCondition; import mage.abilities.effects.RestrictionEffect; import mage.constants.Duration; -import mage.constants.EffectType; import mage.game.Game; import mage.game.permanent.Permanent; @@ -56,7 +55,6 @@ public class ConditionalRestrictionEffect extends RestrictionEffect { public ConditionalRestrictionEffect(Duration duration, RestrictionEffect effect, Condition condition, RestrictionEffect otherwiseEffect) { super(duration); - this.effectType = EffectType.RESTRICTION; this.effect = effect; this.baseCondition = condition; this.otherwiseEffect = otherwiseEffect; diff --git a/Mage/src/mage/abilities/effects/PayCostToAttackBlockEffect.java b/Mage/src/mage/abilities/effects/PayCostToAttackBlockEffect.java new file mode 100644 index 0000000000..63920ccddd --- /dev/null +++ b/Mage/src/mage/abilities/effects/PayCostToAttackBlockEffect.java @@ -0,0 +1,42 @@ +/* + * 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; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.game.Game; +import mage.game.events.GameEvent; + +/** + * + * @author LevelX2 + */ +public interface PayCostToAttackBlockEffect extends ReplacementEffect { + + Cost getCostToPay(GameEvent event, Ability source, Game game); +} diff --git a/Mage/src/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java b/Mage/src/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java new file mode 100644 index 0000000000..917665ca82 --- /dev/null +++ b/Mage/src/mage/abilities/effects/PayCostToAttackBlockEffectImpl.java @@ -0,0 +1,113 @@ +/* + * 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; + +import mage.abilities.Ability; +import mage.abilities.costs.Cost; +import mage.abilities.costs.mana.ManaCostImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public abstract class PayCostToAttackBlockEffectImpl extends ReplacementEffectImpl implements PayCostToAttackBlockEffect { + + public static enum RestrictType { + + ATTACK, ATTACK_AND_BLOCK, BLOCK + } + + private final Cost cost; + private final RestrictType restrictType; + + public PayCostToAttackBlockEffectImpl(Duration duration, Outcome outcome, RestrictType restrictType, Cost cost) { + super(duration, outcome, false); + this.restrictType = restrictType; + this.cost = cost; + } + + public PayCostToAttackBlockEffectImpl(PayCostToAttackBlockEffectImpl effect) { + super(effect); + if (effect.cost != null) { + this.cost = effect.cost.copy(); + } else { + this.cost = null; + } + this.restrictType = effect.restrictType; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + switch (restrictType) { + case ATTACK: + return event.getType() == GameEvent.EventType.DECLARE_ATTACKER; + case BLOCK: + return event.getType().equals(GameEvent.EventType.DECLARE_BLOCKER); + case ATTACK_AND_BLOCK: + return event.getType() == GameEvent.EventType.DECLARE_ATTACKER || event.getType().equals(GameEvent.EventType.DECLARE_BLOCKER); + } + return false; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Player player = game.getPlayer(event.getPlayerId()); + Cost attackBlockTax = getCostToPay(event, source, game); + if (player != null && attackBlockTax != null) { + String chooseText; + if (event.getType().equals(GameEvent.EventType.DECLARE_ATTACKER)) { + chooseText = "Pay " + attackBlockTax.getText() + " to attack?"; + } else { + chooseText = "Pay " + attackBlockTax.getText() + " to block?"; + } + if (attackBlockTax.canPay(source, source.getSourceId(), player.getId(), game) + && player.chooseUse(Outcome.Neutral, chooseText, source, game)) { + if (attackBlockTax instanceof ManaCostImpl) { + ManaCostsImpl manaCosts = new ManaCostsImpl(attackBlockTax.getText()); + if (manaCosts.payOrRollback(source, game, source.getSourceId(), event.getPlayerId())) { + return false; + } + } + } + return true; + } + return false; + } + + @Override + public Cost getCostToPay(GameEvent event, Ability source, Game game) { + return cost; + } + +} diff --git a/Mage/src/mage/abilities/effects/common/combat/CantAttackAllAnyPlayerEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantAttackAnyPlayerAllEffect.java similarity index 88% rename from Mage/src/mage/abilities/effects/common/combat/CantAttackAllAnyPlayerEffect.java rename to Mage/src/mage/abilities/effects/common/combat/CantAttackAnyPlayerAllEffect.java index d0c7b455ec..7c5b9abe96 100644 --- a/Mage/src/mage/abilities/effects/common/combat/CantAttackAllAnyPlayerEffect.java +++ b/Mage/src/mage/abilities/effects/common/combat/CantAttackAnyPlayerAllEffect.java @@ -40,11 +40,11 @@ import mage.game.permanent.Permanent; * * @author LevelX2 */ -public class CantAttackAllAnyPlayerEffect extends RestrictionEffect { +public class CantAttackAnyPlayerAllEffect extends RestrictionEffect { private final FilterCreaturePermanent filter; - public CantAttackAllAnyPlayerEffect(Duration duration, FilterCreaturePermanent filter) { + public CantAttackAnyPlayerAllEffect(Duration duration, FilterCreaturePermanent filter) { super(duration); this.filter = filter; StringBuilder sb = new StringBuilder(filter.getMessage()).append(" can't attack"); @@ -59,7 +59,7 @@ public class CantAttackAllAnyPlayerEffect extends RestrictionEffect { staticText = sb.toString(); } - public CantAttackAllAnyPlayerEffect(final CantAttackAllAnyPlayerEffect effect) { + public CantAttackAnyPlayerAllEffect(final CantAttackAnyPlayerAllEffect effect) { super(effect); this.filter = effect.filter; } @@ -75,8 +75,8 @@ public class CantAttackAllAnyPlayerEffect extends RestrictionEffect { } @Override - public CantAttackAllAnyPlayerEffect copy() { - return new CantAttackAllAnyPlayerEffect(this); + public CantAttackAnyPlayerAllEffect copy() { + return new CantAttackAnyPlayerAllEffect(this); } } diff --git a/Mage/src/mage/abilities/effects/common/combat/CantAttackAllSourceEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantAttackAnyPlayerSourceEffect.java similarity index 87% rename from Mage/src/mage/abilities/effects/common/combat/CantAttackAllSourceEffect.java rename to Mage/src/mage/abilities/effects/common/combat/CantAttackAnyPlayerSourceEffect.java index 4de5696153..fe1e7c6266 100644 --- a/Mage/src/mage/abilities/effects/common/combat/CantAttackAllSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/combat/CantAttackAnyPlayerSourceEffect.java @@ -39,13 +39,13 @@ import mage.game.permanent.Permanent; * * @author BetaSteward_at_googlemail.com */ -public class CantAttackAllSourceEffect extends RestrictionEffect { +public class CantAttackAnyPlayerSourceEffect extends RestrictionEffect { - public CantAttackAllSourceEffect(Duration duration) { + public CantAttackAnyPlayerSourceEffect(Duration duration) { super(duration); } - public CantAttackAllSourceEffect(final CantAttackAllSourceEffect effect) { + public CantAttackAnyPlayerSourceEffect(final CantAttackAnyPlayerSourceEffect effect) { super(effect); } @@ -60,8 +60,8 @@ public class CantAttackAllSourceEffect extends RestrictionEffect { } @Override - public CantAttackAllSourceEffect copy() { - return new CantAttackAllSourceEffect(this); + public CantAttackAnyPlayerSourceEffect copy() { + return new CantAttackAnyPlayerSourceEffect(this); } } diff --git a/Mage/src/mage/abilities/effects/common/combat/CantAttackBlockAllEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantAttackBlockAllEffect.java new file mode 100644 index 0000000000..1bc6f35fab --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/combat/CantAttackBlockAllEffect.java @@ -0,0 +1,85 @@ +/* + * 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.RestrictionEffect; +import mage.constants.Duration; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ +public class CantAttackBlockAllEffect extends RestrictionEffect { + + private final FilterCreaturePermanent filter; + + public CantAttackBlockAllEffect(Duration duration, FilterCreaturePermanent filter) { + super(duration); + this.filter = filter; + StringBuilder sb = new StringBuilder(filter.getMessage()).append(" can't attack or block"); + if (!duration.toString().isEmpty()) { + sb.append(" "); + if (duration.equals(Duration.EndOfTurn)) { + sb.append(" this turn"); + } else { + sb.append(" ").append(duration.toString()); + } + } + staticText = sb.toString(); + } + + public CantAttackBlockAllEffect(final CantAttackBlockAllEffect effect) { + super(effect); + this.filter = effect.filter; + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return filter.match(permanent, source.getSourceId(), source.getControllerId(), game); + } + + @Override + public boolean canAttack(Game game) { + return false; + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { + return false; + } + + @Override + public CantAttackBlockAllEffect copy() { + return new CantAttackBlockAllEffect(this); + } + +} diff --git a/Mage/src/mage/abilities/effects/common/continuous/BecomesColorSourceEffect.java b/Mage/src/mage/abilities/effects/common/continuous/BecomesColorSourceEffect.java new file mode 100644 index 0000000000..e7205a7b5b --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/continuous/BecomesColorSourceEffect.java @@ -0,0 +1,128 @@ +/* + * + * 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.continuous; + +import java.util.UUID; +import mage.MageObject; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.choices.ChoiceColor; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.SubLayer; +import mage.game.Game; +import mage.players.Player; + +/** + * @author LoneFox + */ +public class BecomesColorSourceEffect extends ContinuousEffectImpl { + + private ObjectColor setColor; + + public BecomesColorSourceEffect(Duration duration) { + this(null, duration); + } + + public BecomesColorSourceEffect(ObjectColor setColor, Duration duration) { + super(duration, Layer.ColorChangingEffects_5, SubLayer.NA, Outcome.Benefit); + this.setColor = setColor; + } + + public BecomesColorSourceEffect(final BecomesColorSourceEffect effect) { + super(effect); + this.setColor = effect.setColor; + } + + @Override + public BecomesColorSourceEffect copy() { + return new BecomesColorSourceEffect(this); + } + + @Override + public void init(Ability source, Game game) { + Player controller = game.getPlayer(source.getControllerId()); + if(controller == null) { + return; + } + if(setColor == null) { + ChoiceColor choice = new ChoiceColor(); + while(!choice.isChosen()) { + controller.choose(Outcome.PutManaInPool, choice, game); + if(!controller.isInGame()) { + return; + } + } + if(choice.getColor() != null) { + setColor = choice.getColor(); + } + else { + return; + } + if(!game.isSimulation()) { + game.informPlayers(controller.getLogName() + " has chosen the color: " + setColor.toString()); + } + } + super.init(source, game); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + if(setColor != null) { + MageObject sourceObject = game.getObject(source.getSourceId()); + if(sourceObject != null) { + sourceObject.getColor(game).setColor(setColor); + } + else { + this.discard(); + } + return true; + } else { + throw new UnsupportedOperationException("No color set"); + } + } + + @Override + public String getText(Mode mode) { + if(staticText != null && !staticText.isEmpty()) { + return staticText; + } + return "{this} becomes " + (setColor == null ? "the color of your choice" : setColor.getDescription()) + + " " + duration.toString(); + } +} diff --git a/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java b/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java index 6a0509da83..3029a00fc1 100644 --- a/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continuous/GainAbilityAttachedEffect.java @@ -1,16 +1,16 @@ /* * 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 @@ -20,21 +20,20 @@ * 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.continuous; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffectImpl; import mage.constants.AttachmentType; import mage.constants.Duration; import mage.constants.Layer; import mage.constants.Outcome; import mage.constants.SubLayer; -import mage.abilities.Ability; -import mage.abilities.effects.ContinuousEffectImpl; import mage.game.Game; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; @@ -70,7 +69,7 @@ public class GainAbilityAttachedEffect extends ContinuousEffectImpl { setText(); } - public GainAbilityAttachedEffect(Ability ability, AttachmentType attachmentType) { + public GainAbilityAttachedEffect(Ability ability, AttachmentType attachmentType) { super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); this.ability = ability; this.attachmentType = attachmentType; diff --git a/Mage/src/mage/filter/common/FilterEnchantmentCard.java b/Mage/src/mage/filter/common/FilterEnchantmentCard.java new file mode 100644 index 0000000000..d30a6c7fda --- /dev/null +++ b/Mage/src/mage/filter/common/FilterEnchantmentCard.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.filter.common; + +import mage.constants.CardType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.CardTypePredicate; + +/** + * + * @author LoneFox + */ +public class FilterEnchantmentCard extends FilterCard { + + public FilterEnchantmentCard() { + this("enchantment"); + } + + public FilterEnchantmentCard(String name) { + super(name); + this.add(new CardTypePredicate(CardType.ENCHANTMENT)); + } + + public FilterEnchantmentCard(final FilterEnchantmentCard filter) { + super(filter); + } + + @Override + public FilterEnchantmentCard copy() { + return new FilterEnchantmentCard(this); + } +} diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 1479a6a442..ae55b7bea4 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -1432,19 +1432,17 @@ public abstract class GameImpl implements Game, Serializable { */ @Override public boolean checkStateAndTriggered() { - boolean trigger = !getTurn().isEndTurnRequested(); boolean somethingHappened = false; //20091005 - 115.5 while (!isPaused() && !gameOver(null)) { if (!checkStateBasedActions()) { // nothing happened so check triggers - if (trigger) { - state.handleSimultaneousEvent(this); - } - if (isPaused() || gameOver(null) || !trigger || !checkTriggered()) { + state.handleSimultaneousEvent(this); + if (isPaused() || gameOver(null) || getTurn().isEndTurnRequested() || !checkTriggered()) { break; } } + state.handleSimultaneousEvent(this); applyEffects(); // needed e.g if boost effects end and cause creatures to die somethingHappened = true; } diff --git a/Mage/src/mage/game/GameState.java b/Mage/src/mage/game/GameState.java index e3a2a8a978..cdfdd6ccc9 100644 --- a/Mage/src/mage/game/GameState.java +++ b/Mage/src/mage/game/GameState.java @@ -77,12 +77,12 @@ import mage.watchers.Watchers; * * @author BetaSteward_at_googlemail.com * -* since at any time the game state may be copied and restored you cannot rely + * since at any time the game state may be copied and restored you cannot rely * on any object maintaining it's instance it then becomes necessary to only * refer to objects by their ids since these will always remain constant * throughout its lifetime * -*/ + */ public class GameState implements Serializable, Copyable { private static final transient ThreadLocalStringBuilder threadLocalBuilder = new ThreadLocalStringBuilder(1024); @@ -643,7 +643,7 @@ public class GameState implements Serializable, Copyable { } public void handleSimultaneousEvent(Game game) { - if (!simultaneousEvents.isEmpty()) { + if (!simultaneousEvents.isEmpty() && !getTurn().isEndTurnRequested()) { // it can happen, that the events add new simultaneous events, so copy the list before List eventsToHandle = new ArrayList<>(); eventsToHandle.addAll(simultaneousEvents);