diff --git a/Mage.Sets/src/mage/sets/commander/AnimarSoulOfElements.java b/Mage.Sets/src/mage/sets/commander/AnimarSoulOfElements.java new file mode 100644 index 0000000000..cfb44686fa --- /dev/null +++ b/Mage.Sets/src/mage/sets/commander/AnimarSoulOfElements.java @@ -0,0 +1,149 @@ +/* + * 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.commander; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.CostModificationEffectImpl; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.FlashbackAbility; +import mage.abilities.keyword.ProtectionAbility; +import mage.abilities.keyword.RetraceAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.CostModificationType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.FilterSpell; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class AnimarSoulOfElements extends CardImpl { + + private static final FilterSpell filterSpell = new FilterSpell("a creature spell"); + private static final FilterCard filter = new FilterCard("white and from black"); + static { + filter.add(Predicates.or( + new ColorPredicate(ObjectColor.WHITE), + new ColorPredicate(ObjectColor.BLACK))); + filterSpell.add(new CardTypePredicate(CardType.CREATURE)); + } + + public AnimarSoulOfElements(UUID ownerId) { + super(ownerId, 181, "Animar, Soul of Elements", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{U}{R}{G}"); + this.expansionSetCode = "CMD"; + this.supertype.add("Legendary"); + this.subtype.add("Elemental"); + + this.color.setRed(true); + this.color.setBlue(true); + this.color.setGreen(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Protection from white and from black + this.addAbility(new ProtectionAbility(filter)); + + // Whenever you cast a creature spell, put a +1/+1 counter on Animar, Soul of Elements. + this.addAbility(new SpellCastControllerTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filterSpell, false)); + + // Creature spells you cast cost {1} less to cast for each +1/+1 counter on Animar. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AnimarCostReductionEffect())); + + } + + public AnimarSoulOfElements(final AnimarSoulOfElements card) { + super(card); + } + + @Override + public AnimarSoulOfElements copy() { + return new AnimarSoulOfElements(this); + } +} + +class AnimarCostReductionEffect extends CostModificationEffectImpl { + + AnimarCostReductionEffect() { + super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST); + staticText = "Creature spells you cast cost {1} less to cast for each +1/+1 counter on Animar"; + } + + AnimarCostReductionEffect(AnimarCostReductionEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source, Ability abilityToModify) { + Ability spellAbility = (SpellAbility) abilityToModify; + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (sourcePermanent != null && spellAbility != null) { + int amount = sourcePermanent.getCounters().getCount(CounterType.P1P1); + if (amount > 0) { + CardUtil.reduceCost(spellAbility, amount); + return true; + } + } + return false; + } + + @Override + public boolean applies(Ability abilityToModify, Ability source, Game game) { + if (abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility || abilityToModify instanceof RetraceAbility) { + Card sourceCard = game.getCard(abilityToModify.getSourceId()); + if (sourceCard != null && abilityToModify.getControllerId().equals(source.getControllerId()) && (sourceCard.getCardType().contains(CardType.CREATURE))) { + return true; + } + } + return false; + } + + @Override + public AnimarCostReductionEffect copy() { + return new AnimarCostReductionEffect(this); + } + +} diff --git a/Mage.Sets/src/mage/sets/commander/FierceEmpath.java b/Mage.Sets/src/mage/sets/commander/FierceEmpath.java new file mode 100644 index 0000000000..ce93eed56b --- /dev/null +++ b/Mage.Sets/src/mage/sets/commander/FierceEmpath.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.commander; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.Filter; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author LevelX2 + */ +public class FierceEmpath extends CardImpl { + + private static final FilterCreatureCard filter = new FilterCreatureCard("a creature card with converted mana cost 6 or greater"); + static { + filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.GreaterThan, 5)); + } + public FierceEmpath(UUID ownerId) { + super(ownerId, 155, "Fierce Empath", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "CMD"; + this.subtype.add("Elf"); + + this.color.setGreen(true); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // When Fierce Empath enters the battlefield, you may search your library for a creature card with converted mana cost 6 or greater, reveal it, put it into your hand, then shuffle your library. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInHandEffect( + new TargetCardInLibrary(filter), true, true), true)); + } + + public FierceEmpath(final FierceEmpath card) { + super(card); + } + + @Override + public FierceEmpath copy() { + return new FierceEmpath(this); + } +} diff --git a/Mage.Sets/src/mage/sets/commander/HydraOmnivore.java b/Mage.Sets/src/mage/sets/commander/HydraOmnivore.java new file mode 100644 index 0000000000..01a69e264a --- /dev/null +++ b/Mage.Sets/src/mage/sets/commander/HydraOmnivore.java @@ -0,0 +1,107 @@ +/* + * 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.commander; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DealsDamageToOpponentTriggeredAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class HydraOmnivore extends CardImpl { + + public HydraOmnivore(UUID ownerId) { + super(ownerId, 161, "Hydra Omnivore", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{G}{G}"); + this.expansionSetCode = "CMD"; + this.subtype.add("Hydra"); + + this.color.setGreen(true); + this.power = new MageInt(8); + this.toughness = new MageInt(8); + + // Whenever Hydra Omnivore deals combat damage to an opponent, it deals that much damage to each other opponent. + this.addAbility(new DealsDamageToOpponentTriggeredAbility(new HydraOmnivoreEffect(), false, true)); + } + + public HydraOmnivore(final HydraOmnivore card) { + super(card); + } + + @Override + public HydraOmnivore copy() { + return new HydraOmnivore(this); + } +} + +class HydraOmnivoreEffect extends OneShotEffect { + + public HydraOmnivoreEffect() { + super(Outcome.Benefit); + this.staticText = "it deals that much damage to each other opponent"; + } + + public HydraOmnivoreEffect(final HydraOmnivoreEffect effect) { + super(effect); + } + + @Override + public HydraOmnivoreEffect copy() { + return new HydraOmnivoreEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + UUID damagedOpponent = this.getTargetPointer().getFirst(game, source); + int amount = (Integer) getValue("damage"); + MageObject object = game.getObject(source.getSourceId()); + if (object != null && amount > 0 && damagedOpponent != null) { + for (UUID playerId :game.getOpponents(source.getControllerId())) { + if (playerId != damagedOpponent) { + Player opponent = game.getPlayer(playerId); + if (opponent != null) { + int dealtDamage = opponent.damage(amount, source.getSourceId(), game, false, true); + game.informPlayers(new StringBuilder(object.getName()).append(" deals ").append(dealtDamage).append(" damage to ").append(opponent.getName()).toString()); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/commander/TributeToTheWild.java b/Mage.Sets/src/mage/sets/commander/TributeToTheWild.java new file mode 100644 index 0000000000..6205316709 --- /dev/null +++ b/Mage.Sets/src/mage/sets/commander/TributeToTheWild.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.commander; + +import java.util.UUID; +import mage.abilities.effects.common.SacrificeOpponentsEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.filter.FilterPermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.CardTypePredicate; + +/** + * + * @author LevelX2 + */ +public class TributeToTheWild extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("an artifact or enchantment"); + + static { + filter.add(Predicates.or( + new CardTypePredicate(CardType.ARTIFACT), + new CardTypePredicate(CardType.ENCHANTMENT))); + } + + public TributeToTheWild(UUID ownerId) { + super(ownerId, 175, "Tribute to the Wild", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{G}"); + this.expansionSetCode = "CMD"; + + this.color.setGreen(true); + + // Each opponent sacrifices an artifact or enchantment. + this.getSpellAbility().addEffect(new SacrificeOpponentsEffect(filter)); + } + + public TributeToTheWild(final TributeToTheWild card) { + super(card); + } + + @Override + public TributeToTheWild copy() { + return new TributeToTheWild(this); + } +} diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/PlasmCapture.java b/Mage.Sets/src/mage/sets/dragonsmaze/PlasmCapture.java index 99cbe3454c..61f7f58cd7 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/PlasmCapture.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/PlasmCapture.java @@ -35,7 +35,7 @@ import mage.constants.Rarity; import mage.constants.TargetController; import mage.Mana; import mage.abilities.Ability; -import mage.abilities.common.delayed.AtTheBeginOfPreCombatMainPhaseTriggeredAbility; +import mage.abilities.common.delayed.AtTheBeginOfPreCombatMainDelayedTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ManaEffect; import mage.cards.CardImpl; @@ -96,8 +96,8 @@ class PlasmCaptureCounterEffect extends OneShotEffect if (spell != null) { result = game.getStack().counter(getTargetPointer().getFirst(game, source), source.getSourceId(), game); int mana = spell.getManaCost().convertedManaCost(); - AtTheBeginOfPreCombatMainPhaseTriggeredAbility delayedAbility = - new AtTheBeginOfPreCombatMainPhaseTriggeredAbility(new PlasmCaptureManaEffect(mana), TargetController.YOU); + AtTheBeginOfPreCombatMainDelayedTriggeredAbility delayedAbility = + new AtTheBeginOfPreCombatMainDelayedTriggeredAbility(new PlasmCaptureManaEffect(mana), TargetController.YOU); delayedAbility.setSourceId(source.getSourceId()); delayedAbility.setControllerId(source.getControllerId()); game.addDelayedTriggeredAbility(delayedAbility); diff --git a/Mage.Sets/src/mage/sets/futuresight/CoalitionRelic.java b/Mage.Sets/src/mage/sets/futuresight/CoalitionRelic.java new file mode 100644 index 0000000000..4d8781e9a7 --- /dev/null +++ b/Mage.Sets/src/mage/sets/futuresight/CoalitionRelic.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.sets.futuresight; + +import java.util.UUID; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfPreCombatMainTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.delayed.AtTheBeginOfPreCombatMainDelayedTriggeredAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ManaInAnyCombinationEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.mana.AnyColorManaAbility; +import mage.cards.CardImpl; +import mage.choices.ChoiceColor; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author LevelX2 + */ +public class CoalitionRelic extends CardImpl { + + public CoalitionRelic(UUID ownerId) { + super(ownerId, 161, "Coalition Relic", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}"); + this.expansionSetCode = "FUT"; + + // {tap}: Add one mana of any color to your mana pool. + this.addAbility(new AnyColorManaAbility()); + // {tap}: Put a charge counter on Coalition Relic. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance(), true), new TapSourceCost())); + // At the beginning of your precombat main phase, remove all charge counters from Coalition Relic. Add one mana of any color to your mana pool for each charge counter removed this way. + this.addAbility(new BeginningOfPreCombatMainTriggeredAbility(new CoalitionRelicEffect(), TargetController.YOU, false)); + } + + public CoalitionRelic(final CoalitionRelic card) { + super(card); + } + + @Override + public CoalitionRelic copy() { + return new CoalitionRelic(this); + } +} + +class CoalitionRelicEffect extends OneShotEffect { + + public CoalitionRelicEffect() { + super(Outcome.PutManaInPool); + this.staticText = "remove all charge counters from Coalition Relic. Add one mana of any color to your mana pool for each charge counter removed this way"; + } + + public CoalitionRelicEffect(final CoalitionRelicEffect effect) { + super(effect); + } + + @Override + public CoalitionRelicEffect copy() { + return new CoalitionRelicEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + Player player = game.getPlayer(source.getControllerId()); + if (sourcePermanent != null && player != null) { + int chargeCounters = sourcePermanent.getCounters().getCount(CounterType.CHARGE); + sourcePermanent.removeCounters(CounterType.CHARGE.createInstance(chargeCounters), game); + Mana mana = new Mana(); + ChoiceColor choice = new ChoiceColor(); + for (int i = 0; i < chargeCounters; i++) { + while (player.isInGame() && !choice.isChosen()) { + player.choose(outcome, choice, game); + } + if (choice.getColor().isBlack()) { + mana.addBlack(); + } else if (choice.getColor().isBlue()) { + mana.addBlue(); + } else if (choice.getColor().isRed()) { + mana.addRed(); + } else if (choice.getColor().isGreen()) { + mana.addGreen(); + } else if (choice.getColor().isWhite()) { + mana.addWhite(); + } + choice.clearChoice(); + } + player.getManaPool().addMana(mana, game, source); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/WindbriskHeights.java b/Mage.Sets/src/mage/sets/lorwyn/WindbriskHeights.java new file mode 100644 index 0000000000..796ab1867a --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/WindbriskHeights.java @@ -0,0 +1,140 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.lorwyn; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.HideawayPlayEffect; +import mage.abilities.keyword.HideawayAbility; +import mage.abilities.mana.WhiteManaAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.WatcherScope; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; +import mage.watchers.WatcherImpl; + +/** + * + * @author LevelX2 + */ +public class WindbriskHeights extends CardImpl { + + public WindbriskHeights(UUID ownerId) { + super(ownerId, 281, "Windbrisk Heights", Rarity.RARE, new CardType[]{CardType.LAND}, ""); + this.expansionSetCode = "LRW"; + + // Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.) + this.addAbility(new HideawayAbility(this)); + // {tap}: Add {W} to your mana pool. + this.addAbility(new WhiteManaAbility()); + // {W}, {tap}: You may play the exiled card without paying its mana cost if you attacked with three or more creatures this turn. + Ability ability = new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, new HideawayPlayEffect(), new ManaCostsImpl("{W}"), WindbriskHeightsAttackersCondition.getInstance()); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + + this.addWatcher(new WindbriskHeightsWatcher()); + + } + + public WindbriskHeights(final WindbriskHeights card) { + super(card); + } + + @Override + public WindbriskHeights copy() { + return new WindbriskHeights(this); + } +} + +class WindbriskHeightsWatcher extends WatcherImpl { + + private int numberOfattackers; + + public WindbriskHeightsWatcher() { + super("WindbriskHeightsAttackersWatcher", WatcherScope.PLAYER); + } + + public WindbriskHeightsWatcher(final WindbriskHeightsWatcher watcher) { + super(watcher); + this.numberOfattackers = watcher.numberOfattackers; + } + + @Override + public WindbriskHeightsWatcher copy() { + return new WindbriskHeightsWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.DECLARED_ATTACKERS && game.getActivePlayerId().equals(this.getControllerId())) { + numberOfattackers += game.getCombat().getAttackers().size(); // because there are more than one attack phase possible, sum up the attackers + if (numberOfattackers > 2) { + condition = true; + } + } + } + + @Override + public void reset() { + super.reset(); + numberOfattackers = 0; + } +} + +class WindbriskHeightsAttackersCondition implements Condition { + + private static WindbriskHeightsAttackersCondition fInstance = new WindbriskHeightsAttackersCondition(); + + public static Condition getInstance() { + return fInstance; + } + + @Override + public boolean apply(Game game, Ability source) { + Watcher watcher = game.getState().getWatchers().get("WindbriskHeightsAttackersWatcher", source.getControllerId()); + if (watcher != null && watcher.conditionMet()) { + return true; + } + return false; + } + + @Override + public String toString() { + return "you attacked with three or more creatures this turn"; + } +} diff --git a/Mage.Sets/src/mage/sets/scourge/FierceEmpath.java b/Mage.Sets/src/mage/sets/scourge/FierceEmpath.java new file mode 100644 index 0000000000..e2a98bd53b --- /dev/null +++ b/Mage.Sets/src/mage/sets/scourge/FierceEmpath.java @@ -0,0 +1,52 @@ +/* + * 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.scourge; + +import java.util.UUID; + +/** + * + * @author LevelX2 + */ +public class FierceEmpath extends mage.sets.commander.FierceEmpath { + + public FierceEmpath(UUID ownerId) { + super(ownerId); + this.cardNumber = 119; + this.expansionSetCode = "SCG"; + } + + public FierceEmpath(final FierceEmpath card) { + super(card); + } + + @Override + public FierceEmpath copy() { + return new FierceEmpath(this); + } +} diff --git a/Mage/src/mage/abilities/common/BeginningOfPreCombatMainTriggeredAbility.java b/Mage/src/mage/abilities/common/BeginningOfPreCombatMainTriggeredAbility.java new file mode 100644 index 0000000000..737852c034 --- /dev/null +++ b/Mage/src/mage/abilities/common/BeginningOfPreCombatMainTriggeredAbility.java @@ -0,0 +1,102 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package mage.abilities.common; + +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ + +public class BeginningOfPreCombatMainTriggeredAbility extends TriggeredAbilityImpl { + + private TargetController targetController; + private boolean setTargetPointer; + + public BeginningOfPreCombatMainTriggeredAbility(Effect effect, TargetController targetController, boolean isOptional) { + this(Zone.BATTLEFIELD, effect, targetController, isOptional, false); + } + + public BeginningOfPreCombatMainTriggeredAbility(Zone zone, Effect effect, TargetController targetController, boolean isOptional, boolean setTargetPointer) { + super(zone, effect, isOptional); + this.targetController = targetController; + this.setTargetPointer = setTargetPointer; + } + + public BeginningOfPreCombatMainTriggeredAbility(final BeginningOfPreCombatMainTriggeredAbility ability) { + super(ability); + this.targetController = ability.targetController; + this.setTargetPointer = ability.setTargetPointer; + } + + @Override + public BeginningOfPreCombatMainTriggeredAbility copy() { + return new BeginningOfPreCombatMainTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == GameEvent.EventType.PRECOMBAT_MAIN_PHASE_PRE) { + switch (targetController) { + case YOU: + boolean yours = event.getPlayerId().equals(this.controllerId); + if (yours && setTargetPointer) { + if (getTargets().size() == 0) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getPlayerId())); + } + } + } + return yours; + case OPPONENT: + if (game.getOpponents(this.controllerId).contains(event.getPlayerId())) { + if (setTargetPointer) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getPlayerId())); + } + } + return true; + } + break; + case ANY: + if (setTargetPointer) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getPlayerId())); + } + } + return true; + } + } + return false; + } + + @Override + public String getRule() { + switch (targetController) { + case YOU: + return "At the beginning of your precombat main phase, " + generateZoneString() + getEffects().getText(modes.getMode()); + case OPPONENT: + return "At the beginning of each opponent's precombat main phase, " + generateZoneString() + getEffects().getText(modes.getMode()); + case ANY: + return "At the beginning of each precombat main phase, " + generateZoneString() + getEffects().getText(modes.getMode()); + } + return ""; + } + + private String generateZoneString() { + switch (getZone()) { + case GRAVEYARD: + return "if {this} is in your graveyard, "; + } + return ""; + } +} diff --git a/Mage/src/mage/abilities/common/delayed/AtTheBeginOfPreCombatMainPhaseTriggeredAbility.java b/Mage/src/mage/abilities/common/delayed/AtTheBeginOfPreCombatMainDelayedTriggeredAbility.java similarity index 86% rename from Mage/src/mage/abilities/common/delayed/AtTheBeginOfPreCombatMainPhaseTriggeredAbility.java rename to Mage/src/mage/abilities/common/delayed/AtTheBeginOfPreCombatMainDelayedTriggeredAbility.java index 418679bc96..b3ed748a17 100644 --- a/Mage/src/mage/abilities/common/delayed/AtTheBeginOfPreCombatMainPhaseTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/delayed/AtTheBeginOfPreCombatMainDelayedTriggeredAbility.java @@ -40,23 +40,23 @@ import mage.game.permanent.Permanent; * @author LevelX2 */ -public class AtTheBeginOfPreCombatMainPhaseTriggeredAbility extends DelayedTriggeredAbility { +public class AtTheBeginOfPreCombatMainDelayedTriggeredAbility extends DelayedTriggeredAbility { private TargetController targetController; - public AtTheBeginOfPreCombatMainPhaseTriggeredAbility(Effect effect, TargetController targetController) { + public AtTheBeginOfPreCombatMainDelayedTriggeredAbility(Effect effect, TargetController targetController) { super(effect); this.targetController = targetController; } - public AtTheBeginOfPreCombatMainPhaseTriggeredAbility(AtTheBeginOfPreCombatMainPhaseTriggeredAbility ability) { + public AtTheBeginOfPreCombatMainDelayedTriggeredAbility(AtTheBeginOfPreCombatMainDelayedTriggeredAbility ability) { super(ability); this.targetController = ability.targetController; } @Override - public AtTheBeginOfPreCombatMainPhaseTriggeredAbility copy() { - return new AtTheBeginOfPreCombatMainPhaseTriggeredAbility(this); + public AtTheBeginOfPreCombatMainDelayedTriggeredAbility copy() { + return new AtTheBeginOfPreCombatMainDelayedTriggeredAbility(this); } @Override diff --git a/Mage/src/mage/abilities/effects/common/DealsDamageToOpponentTriggeredAbility.java b/Mage/src/mage/abilities/effects/common/DealsDamageToOpponentTriggeredAbility.java index b89c439c1e..1071803319 100644 --- a/Mage/src/mage/abilities/effects/common/DealsDamageToOpponentTriggeredAbility.java +++ b/Mage/src/mage/abilities/effects/common/DealsDamageToOpponentTriggeredAbility.java @@ -31,6 +31,8 @@ import mage.abilities.TriggeredAbilityImpl; import mage.abilities.effects.Effect; import mage.constants.Zone; import mage.game.Game; +import mage.game.events.DamagePlayerEvent; +import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.target.targetpointer.FixedTarget; @@ -39,16 +41,24 @@ import mage.target.targetpointer.FixedTarget; */ public class DealsDamageToOpponentTriggeredAbility extends TriggeredAbilityImpl { + boolean onlyCombat; + public DealsDamageToOpponentTriggeredAbility(Effect effect) { - super(Zone.BATTLEFIELD, effect); - } + this(effect, false, false); + } public DealsDamageToOpponentTriggeredAbility(Effect effect, boolean optional) { + this(effect, optional, false); + } + + public DealsDamageToOpponentTriggeredAbility(Effect effect, boolean optional, boolean onlyCombat) { super(Zone.BATTLEFIELD, effect, optional); + this.onlyCombat = onlyCombat; } public DealsDamageToOpponentTriggeredAbility(final DealsDamageToOpponentTriggeredAbility ability) { super(ability); + this.onlyCombat = ability.onlyCombat; } @Override @@ -60,8 +70,15 @@ public class DealsDamageToOpponentTriggeredAbility extends TriggeredAbilityImpl< public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER && event.getSourceId().equals(this.sourceId) && game.getOpponents(this.getControllerId()).contains(event.getTargetId())) { + if (onlyCombat && event instanceof DamagedPlayerEvent) { + DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event; + if (!damageEvent.isCombatDamage()) { + return false; + } + } for (Effect effect : getEffects()) { effect.setTargetPointer(new FixedTarget(event.getTargetId())); + effect.setValue("damage", event.getAmount()); } return true; } @@ -70,6 +87,11 @@ public class DealsDamageToOpponentTriggeredAbility extends TriggeredAbilityImpl< @Override public String getRule() { - return "Whenever {this} deals damage to an opponent, " + super.getRule(); + StringBuilder sb = new StringBuilder("Whenever {this} deals "); + if (onlyCombat) { + sb.append("combat "); + } + sb.append("damage to an opponent, ").append(super.getRule()); + return sb.toString(); } -} \ No newline at end of file +} diff --git a/Mage/src/mage/abilities/effects/common/SacrificeOpponentsEffect.java b/Mage/src/mage/abilities/effects/common/SacrificeOpponentsEffect.java index 08f355a2f2..a893fe9bc0 100644 --- a/Mage/src/mage/abilities/effects/common/SacrificeOpponentsEffect.java +++ b/Mage/src/mage/abilities/effects/common/SacrificeOpponentsEffect.java @@ -111,7 +111,9 @@ public class SacrificeOpponentsEffect extends OneShotEffect