From 40ff62881abdd8c36cdc9ef450e7cb08b1a162a6 Mon Sep 17 00:00:00 2001 From: markedagain Date: Mon, 22 Feb 2016 13:57:17 -0500 Subject: [PATCH 01/17] Magemark cycle implemented --- .../sets/guildpact/BeastmastersMagemark.java | 140 ++++++++++++++++++ .../mage/sets/guildpact/FencersMagemark.java | 90 +++++++++++ .../sets/guildpact/GuardiansMagemark.java | 88 +++++++++++ .../sets/guildpact/NecromancersMagemark.java | 92 ++++++++++++ 4 files changed, 410 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java create mode 100644 Mage.Sets/src/mage/sets/guildpact/FencersMagemark.java create mode 100644 Mage.Sets/src/mage/sets/guildpact/GuardiansMagemark.java create mode 100644 Mage.Sets/src/mage/sets/guildpact/NecromancersMagemark.java diff --git a/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java b/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java new file mode 100644 index 00000000000..1771bdb8532 --- /dev/null +++ b/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.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.guildpact; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.EnchantedPredicate; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Markedagain + */ +public class BeastmastersMagemark extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control that are enchanted"); + static { + filter.add(new EnchantedPredicate()); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public BeastmastersMagemark(UUID ownerId) { + super(ownerId, 80, "Beastmaster's Magemark", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}"); + this.expansionSetCode = "GPT"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Creatures you control that are enchanted get +1/+1. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1, Duration.WhileOnBattlefield, filter, false)); + this.addAbility(ability); + // Whenever a creature you control that's enchanted becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. + this.addAbility(new BeastmastersMagemarkAbility()); + } + + public BeastmastersMagemark(final BeastmastersMagemark card) { + super(card); + } + + @Override + public BeastmastersMagemark copy() { + return new BeastmastersMagemark(this); + } +} + +class BeastmastersMagemarkAbility extends BecomesBlockedTriggeredAbility { + + public BeastmastersMagemarkAbility() { + super(null, false); + BeastmastersMagemarkValue value = new BeastmastersMagemarkValue(); + this.addEffect(new BoostSourceEffect(value, value, Duration.EndOfTurn)); + } + + public BeastmastersMagemarkAbility(final BeastmastersMagemarkAbility ability) { + super(ability); + } + + @Override + public BeastmastersMagemarkAbility copy() { + return new BeastmastersMagemarkAbility(this); + } + + @Override + public String getRule() { + return "Whenever {this} becomes blocked, it gets +1/+1 until end of turn for each creature blocking it."; + } +} + +class BeastmastersMagemarkValue implements DynamicValue { + + @Override + public BeastmastersMagemarkValue copy() { + return new BeastmastersMagemarkValue(); + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + for(CombatGroup combatGroup : game.getCombat().getGroups()) { + if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { + int blockers = combatGroup.getBlockers().size(); + return blockers > 1 ? (blockers) : 0; + } + } + return 0; + } + + @Override + public String getMessage() { + return "+1/+1 until end of turn for each creature blocking it"; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/guildpact/FencersMagemark.java b/Mage.Sets/src/mage/sets/guildpact/FencersMagemark.java new file mode 100644 index 00000000000..0889a07bcdd --- /dev/null +++ b/Mage.Sets/src/mage/sets/guildpact/FencersMagemark.java @@ -0,0 +1,90 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.guildpact; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.effects.common.continuous.GainAbilityAllEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.EnchantedPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Markedagain + */ +public class FencersMagemark extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control that are enchanted"); + static { + filter.add(new EnchantedPredicate()); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public FencersMagemark(UUID ownerId) { + super(ownerId, 65, "Fencer's Magemark", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); + this.expansionSetCode = "GPT"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Creatures you control that are enchanted get +1/+1 and have first strike. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1, Duration.WhileOnBattlefield, filter, false)); + Effect effect = new GainAbilityAllEffect(FirstStrikeAbility.getInstance(),Duration.WhileOnBattlefield,filter, " and have first strike"); + ability.addEffect(effect); + this.addAbility(ability); + } + + public FencersMagemark(final FencersMagemark card) { + super(card); + } + + @Override + public FencersMagemark copy() { + return new FencersMagemark(this); + } +} diff --git a/Mage.Sets/src/mage/sets/guildpact/GuardiansMagemark.java b/Mage.Sets/src/mage/sets/guildpact/GuardiansMagemark.java new file mode 100644 index 00000000000..39a1e80b938 --- /dev/null +++ b/Mage.Sets/src/mage/sets/guildpact/GuardiansMagemark.java @@ -0,0 +1,88 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.guildpact; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.FlashAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.EnchantedPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Markedagain + */ +public class GuardiansMagemark extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control that are enchanted"); + static { + filter.add(new EnchantedPredicate()); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public GuardiansMagemark(UUID ownerId) { + super(ownerId, 8, "Guardian's Magemark", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); + this.expansionSetCode = "GPT"; + this.subtype.add("Aura"); + + // Flash + this.addAbility(FlashAbility.getInstance()); + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Creatures you control that are enchanted get +1/+1. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1, Duration.WhileOnBattlefield, filter, false)); + this.addAbility(ability); + } + + public GuardiansMagemark(final GuardiansMagemark card) { + super(card); + } + + @Override + public GuardiansMagemark copy() { + return new GuardiansMagemark(this); + } +} diff --git a/Mage.Sets/src/mage/sets/guildpact/NecromancersMagemark.java b/Mage.Sets/src/mage/sets/guildpact/NecromancersMagemark.java new file mode 100644 index 00000000000..712648fca81 --- /dev/null +++ b/Mage.Sets/src/mage/sets/guildpact/NecromancersMagemark.java @@ -0,0 +1,92 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.guildpact; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.DiesCreatureTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.abilities.effects.common.continuous.BoostAllEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.filter.predicate.permanent.EnchantedPredicate; +import mage.target.TargetPermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author Markedagain + */ +public class NecromancersMagemark extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control that are enchanted"); + static { + filter.add(new EnchantedPredicate()); + filter.add(new ControllerPredicate(TargetController.YOU)); + } + + public NecromancersMagemark(UUID ownerId) { + super(ownerId, 53, "Necromancer's Magemark", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + this.expansionSetCode = "GPT"; + this.subtype.add("Aura"); + + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // Creatures you control that are enchanted get +1/+1. + ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1, Duration.WhileOnBattlefield, filter, false)); + this.addAbility(ability); + // If a creature you control that's enchanted would die, return it to its owner's hand instead. + Effect effect = new ReturnToHandSourceEffect(); + ability = new DiesCreatureTriggeredAbility(effect,false); + this.addAbility(ability); + } + + public NecromancersMagemark(final NecromancersMagemark card) { + super(card); + } + + @Override + public NecromancersMagemark copy() { + return new NecromancersMagemark(this); + } +} From 3ac7976dda57440e1621be28237a40fd59435117 Mon Sep 17 00:00:00 2001 From: markedagain Date: Mon, 22 Feb 2016 13:57:57 -0500 Subject: [PATCH 02/17] Requested Cards --- .../mage/sets/invasion/ElfhameSanctuary.java | 108 +++++++++++++++++ .../src/mage/sets/invasion/GlobalRuin.java | 112 ++++++++++++++++++ .../sets/lorwyn/GlenElendraPranksters.java | 102 ++++++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/invasion/ElfhameSanctuary.java create mode 100644 Mage.Sets/src/mage/sets/invasion/GlobalRuin.java create mode 100644 Mage.Sets/src/mage/sets/lorwyn/GlenElendraPranksters.java diff --git a/Mage.Sets/src/mage/sets/invasion/ElfhameSanctuary.java b/Mage.Sets/src/mage/sets/invasion/ElfhameSanctuary.java new file mode 100644 index 00000000000..00ff659c0b0 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/ElfhameSanctuary.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.invasion; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; +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.filter.common.FilterBasicLandCard; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetCardInLibrary; + +/** + * + * @author Markedagain + */ +public class ElfhameSanctuary extends CardImpl { + + public ElfhameSanctuary(UUID ownerId) { + super(ownerId, 185, "Elfhame Sanctuary", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); + this.expansionSetCode = "INV"; + + // At the beginning of your upkeep, you may search your library for a basic land card, reveal that card, and put it into your hand. If you do, you skip your draw step this turn and shuffle your library. + Ability ability = new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterBasicLandCard())), TargetController.YOU, true); + ability.addEffect(new SkipDrawStepThisTurn()); + + this.addAbility(ability); + } + + public ElfhameSanctuary(final ElfhameSanctuary card) { + super(card); + } + + @Override + public ElfhameSanctuary copy() { + return new ElfhameSanctuary(this); + } +} + +class SkipDrawStepThisTurn extends ReplacementEffectImpl { + + public SkipDrawStepThisTurn() { + super(Duration.UntilYourNextTurn, Outcome.Neutral); + staticText = "Skip your draw step this turn"; + } + + public SkipDrawStepThisTurn(final SkipDrawStepThisTurn effect) { + super(effect); + } + + @Override + public SkipDrawStepThisTurn copy() { + return new SkipDrawStepThisTurn(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + return true; + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DRAW_STEP; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return event.getPlayerId().equals(source.getControllerId()); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/invasion/GlobalRuin.java b/Mage.Sets/src/mage/sets/invasion/GlobalRuin.java new file mode 100644 index 00000000000..691ca31ce50 --- /dev/null +++ b/Mage.Sets/src/mage/sets/invasion/GlobalRuin.java @@ -0,0 +1,112 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.invasion; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.common.FilterLandPermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetControlledPermanent; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author Markedagain + */ +public class GlobalRuin extends CardImpl { + + public GlobalRuin(UUID ownerId) { + super(ownerId, 18, "Global Ruin", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{4}{W}"); + this.expansionSetCode = "INV"; + + // Each player chooses from the lands he or she controls a land of each basic land type, then sacrifices the rest. + this.getSpellAbility().addEffect(new GlobalRuinDestroyLandEffect()); + } + + public GlobalRuin(final GlobalRuin card) { + super(card); + } + + @Override + public GlobalRuin copy() { + return new GlobalRuin(this); + } +} + +class GlobalRuinDestroyLandEffect extends OneShotEffect { + + public GlobalRuinDestroyLandEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "Each player chooses from the lands he or she controls a land of each basic land type, then sacrifices the rest"; + } + + public GlobalRuinDestroyLandEffect(final GlobalRuinDestroyLandEffect effect) { + super(effect); + } + + @Override + public GlobalRuinDestroyLandEffect copy() { + return new GlobalRuinDestroyLandEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Set lands = new HashSet<>(); + + for (UUID playerId : game.getPlayerList()) { + Player player = game.getPlayer(playerId); + for (String landName : new String[]{"Forest", "Island", "Mountain", "Plains", "Swamp"}) { + FilterControlledLandPermanent filter = new FilterControlledLandPermanent(landName + " you control"); + filter.add(new SubtypePredicate(landName)); + Target target = new TargetControlledPermanent(1, 1, filter, true); + if (target.canChoose(player.getId(), game)) { + player.chooseTarget(outcome, target, source, game); + lands.add(target.getFirstTarget()); + } + } + } + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(new FilterLandPermanent(), game)){ + if (!lands.contains(permanent.getId())){ + permanent.sacrifice(permanent.getId(), game); + } + } + return true; + } +} diff --git a/Mage.Sets/src/mage/sets/lorwyn/GlenElendraPranksters.java b/Mage.Sets/src/mage/sets/lorwyn/GlenElendraPranksters.java new file mode 100644 index 00000000000..770af5089c2 --- /dev/null +++ b/Mage.Sets/src/mage/sets/lorwyn/GlenElendraPranksters.java @@ -0,0 +1,102 @@ +/* + * 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.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author Markedagain + */ +public class GlenElendraPranksters extends CardImpl { + + public GlenElendraPranksters(UUID ownerId) { + super(ownerId, 67, "Glen Elendra Pranksters", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "LRW"; + this.subtype.add("Faerie"); + this.subtype.add("Wizard"); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Whenever you cast a spell during an opponent's turn, you may return target creature you control to its owner's hand. + this.addAbility(new GlenElendraPrankstersTriggeredAbility()); + } + + public GlenElendraPranksters(final GlenElendraPranksters card) { + super(card); + } + + @Override + public GlenElendraPranksters copy() { + return new GlenElendraPranksters(this); + } +} +class GlenElendraPrankstersTriggeredAbility extends TriggeredAbilityImpl { + GlenElendraPrankstersTriggeredAbility() { + super(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), true); + this.addTarget(new TargetControlledCreaturePermanent()); + } + + GlenElendraPrankstersTriggeredAbility(final GlenElendraPrankstersTriggeredAbility ability) { + super(ability); + } + + @Override + public GlenElendraPrankstersTriggeredAbility copy() { + return new GlenElendraPrankstersTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.SPELL_CAST; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + return event.getPlayerId().equals(this.controllerId) + && game.getOpponents(this.controllerId).contains(game.getActivePlayerId()); + } + + @Override + public String getRule() { + return "Whenever you cast a spell during an opponent's turn, " + super.getRule(); + } +} \ No newline at end of file From 36e084990a9afc04d6fc5322a906d17eb26368b3 Mon Sep 17 00:00:00 2001 From: Goesta Date: Tue, 23 Feb 2016 17:27:01 +0100 Subject: [PATCH 03/17] Added Wizards.com multi-language cards download --- .../dl/sources/WizardCardsImageSource.java | 138 ++++++++++++------ 1 file changed, 97 insertions(+), 41 deletions(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java index c232330d94d..e964ed8d417 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java @@ -40,6 +40,7 @@ import java.util.HashMap; import java.util.Map; import java.util.prefs.Preferences; import mage.client.MageFrame; +import mage.client.dialog.PreferencesDialog; import mage.remote.Connection; import mage.remote.Connection.ProxyType; import org.jsoup.Jsoup; @@ -56,6 +57,7 @@ public class WizardCardsImageSource implements CardImageSource { private static CardImageSource instance; private static Map setsAliases; + private static Map languageAliases; private final Map> sets; public static CardImageSource getInstance() { @@ -236,42 +238,30 @@ public class WizardCardsImageSource implements CardImageSource { setsAliases.put("WTH", "Weatherlight"); setsAliases.put("WWK", "Worldwake"); setsAliases.put("ZEN", "Zendikar"); + + languageAliases = new HashMap<>(); + languageAliases.put("es", "Spanish"); + languageAliases.put("jp", "Japanese"); + languageAliases.put("it", "Italian"); + languageAliases.put("fr", "French"); + languageAliases.put("cn", "Chinese Simplified"); + languageAliases.put("de", "German"); + } private Map getSetLinks(String cardSet) { Map setLinks = new HashMap<>(); try { String setNames = setsAliases.get(cardSet); - Preferences prefs = MageFrame.getPreferences(); - Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None")); + String preferedLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en"); for (String setName : setNames.split("\\^")) { String URLSetName = URLEncoder.encode(setName, "UTF-8"); - String urlDocument; int page = 0; int firstMultiverseIdLastPage = 0; Pages: while (page < 999) { - Document doc; - if (proxyType.equals(ProxyType.NONE)) { - urlDocument = "http://gatherer.wizards.com/Pages/Search/Default.aspx?page=" + page +"&output=spoiler&method=visual&action=advanced&set=+[%22" + URLSetName + "%22]"; - doc = Jsoup.connect(urlDocument).get(); - } else { - String proxyServer = prefs.get("proxyAddress", ""); - int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0")); - URL url = new URL("http://gatherer.wizards.com/Pages/Search/Default.aspx?page=" + page +"&output=spoiler&method=visual&action=advanced&set=+[%22" + URLSetName + "%22]"); - Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort)); - HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy); - - uc.connect(); - - String line; - StringBuffer tmp = new StringBuffer(); - BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); - while ((line = in.readLine()) != null) { - tmp.append(line); - } - doc = Jsoup.parse(String.valueOf(tmp)); - } + String searchUrl = "http://gatherer.wizards.com/Pages/Search/Default.aspx?page=" + page +"&output=spoiler&method=visual&action=advanced&set=+[%22" + URLSetName + "%22]"; + Document doc = getDocument(searchUrl); Elements cardsImages = doc.select("img[src^=../../Handlers/]"); if (cardsImages.isEmpty()) { @@ -279,8 +269,8 @@ public class WizardCardsImageSource implements CardImageSource { } for (int i = 0; i < cardsImages.size(); i++) { + Integer multiverseId = Integer.parseInt(cardsImages.get(i).attr("src").replaceAll("[^\\d]", "")); if (i == 0) { - Integer multiverseId = Integer.parseInt(cardsImages.get(i).attr("src").replaceAll("[^\\d]", "")); if (multiverseId == firstMultiverseIdLastPage) { break Pages; } @@ -289,23 +279,10 @@ public class WizardCardsImageSource implements CardImageSource { String cardName = normalizeName(cardsImages.get(i).attr("alt")); if (cardName != null && !cardName.isEmpty()) { if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) { - Integer multiverseId = Integer.parseInt(cardsImages.get(i).attr("src").replaceAll("[^\\d]", "")); - String urlLandDocument = "http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=" + multiverseId; - Document landDoc = Jsoup.connect(urlLandDocument).get(); - Elements variations = landDoc.select("a.variationlink"); - if(!variations.isEmpty()) { - int landNumber = 1; - for (Element variation : variations) { - Integer landMultiverseId = Integer.parseInt(variation.attr("onclick").replaceAll("[^\\d]", "")); - // "" - setLinks.put((cardName + landNumber).toLowerCase(), "/Handlers/Image.ashx?multiverseid=" +landMultiverseId + "&type=card"); - landNumber++; - } - } else { - setLinks.put(cardName.toLowerCase(), cardsImages.get(i).attr("src").substring(5)); - } + setLinks.putAll(getLandVariations(multiverseId, cardName)); } else { - setLinks.put(cardName.toLowerCase(), cardsImages.get(i).attr("src").substring(5)); + Integer preferedMultiverseId = getLocalizedMultiverseId(preferedLanguage, multiverseId); + setLinks.put(cardName.toLowerCase(), generateLink(preferedMultiverseId)); } } } @@ -318,6 +295,85 @@ public class WizardCardsImageSource implements CardImageSource { return setLinks; } + private Document getDocument(String urlString) throws NumberFormatException, IOException { + Preferences prefs = MageFrame.getPreferences(); + Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None")); + Document doc; + if (proxyType.equals(ProxyType.NONE)) { + doc = Jsoup.connect(urlString).get(); + } else { + String proxyServer = prefs.get("proxyAddress", ""); + int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0")); + URL url = new URL(urlString); + Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort)); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy); + + uc.connect(); + + String line; + StringBuffer tmp = new StringBuffer(); + BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); + while ((line = in.readLine()) != null) { + tmp.append(line); + } + doc = Jsoup.parse(String.valueOf(tmp)); + } + return doc; + } + + private Map getLandVariations(Integer multiverseId, String cardName) throws IOException, NumberFormatException { + String urlLandDocument = "http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=" + multiverseId; + Document landDoc = getDocument(urlLandDocument); + Elements variations = landDoc.select("a.variationlink"); + Map links = new HashMap<>(); + if(!variations.isEmpty()) { + int landNumber = 1; + for (Element variation : variations) { + Integer landMultiverseId = Integer.parseInt(variation.attr("onclick").replaceAll("[^\\d]", "")); + links.put((cardName + landNumber).toLowerCase(), generateLink(landMultiverseId)); + landNumber++; + } + } else { + links.put(cardName.toLowerCase(), generateLink(multiverseId)); + } + + return links; + } + + private static String generateLink(Integer landMultiverseId) { + return "/Handlers/Image.ashx?multiverseid=" +landMultiverseId + "&type=card"; + } + + private Integer getLocalizedMultiverseId(String preferedLanguage, Integer multiverseId) throws IOException { + if (preferedLanguage.equals("en")) { + return multiverseId; + } + + String languageName = languageAliases.get(preferedLanguage); + HashMap localizedLanguageIds = getlocalizedMultiverseIds(multiverseId); + if (localizedLanguageIds.containsKey(languageName)) { + return localizedLanguageIds.get(languageName); + } else { + return multiverseId; + } + } + + private HashMap getlocalizedMultiverseIds(Integer englishMultiverseId) throws IOException { + String cardLanguagesUrl = "http://gatherer.wizards.com/Pages/Card/Languages.aspx?multiverseid=" + englishMultiverseId; + Document cardLanguagesDoc = getDocument(cardLanguagesUrl); + Elements languageTableRows = cardLanguagesDoc.select("tr.cardItem"); + HashMap localizedIds = new HashMap<>(); + if(!languageTableRows.isEmpty()) { + for (Element languageTableRow : languageTableRows) { + Elements languageTableColumns = languageTableRow.select("td"); + Integer localizedId = Integer.parseInt(languageTableColumns.get(0).select("a").first().attr("href").replaceAll("[^\\d]", "")); + String languageName = languageTableColumns.get(1).text().trim(); + localizedIds.put(languageName, localizedId); + } + } + return localizedIds; + } + private String normalizeName(String name) { //Split card if(name.contains("//")) { From 61cad91f9b20bfa3fd8e58ba7d779f5f1a4dc8c3 Mon Sep 17 00:00:00 2001 From: Quercitron Date: Wed, 24 Feb 2016 02:17:02 +0300 Subject: [PATCH 04/17] Fix images download from magiccards.info --- .../java/org/mage/plugins/card/images/DownloadPictures.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index c4ffa94f69b..0c61f379f4f 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.imageio.IIOImage; @@ -572,7 +573,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab // Logger.getLogger(this.getClass()).info(url.toString()); URLConnection httpConn = url.openConnection(p); // images download from magiccards.info may not work with default 'User-Agent: Java/1.x.x' request header - httpConn.setRequestProperty("User-Agent", ""); + httpConn.setRequestProperty("User-Agent", UUID.randomUUID().toString()); httpConn.connect(); int responseCode = ((HttpURLConnection) httpConn).getResponseCode(); if (responseCode == 200) { From 188db6eedc3a04b3f0a8348aae64c2fcd8aa860c Mon Sep 17 00:00:00 2001 From: markedagain Date: Tue, 23 Feb 2016 23:54:57 -0500 Subject: [PATCH 05/17] Refactored Blocked Creature effect --- .../sets/guildpact/BeastmastersMagemark.java | 9 +- .../src/mage/sets/iceage/JohtullWurm.java | 192 +++++++----------- .../src/mage/sets/invasion/SparringGolem.java | 185 +++++++---------- .../mage/sets/legions/BerserkMurlodont.java | 143 +++++++------ .../src/mage/sets/mirage/JungleWurm.java | 190 +++++++---------- .../sets/ninthedition/ElvishBerserker.java | 191 +++++++---------- .../src/mage/sets/odyssey/RabidElephant.java | 189 +++++++---------- .../sets/portalsecondage/RazorclawBear.java | 2 +- .../mage/sets/stronghold/SpinedSliver.java | 8 +- .../src/mage/sets/urzaslegacy/GangOfElk.java | 56 +---- .../common/BlockedCreatureCount.java | 81 ++++++++ 11 files changed, 537 insertions(+), 709 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java diff --git a/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java b/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java index 1771bdb8532..ca3bb751497 100644 --- a/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java +++ b/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java @@ -29,9 +29,11 @@ package mage.sets.guildpact; import java.util.UUID; import mage.abilities.Ability; +import mage.abilities.common.BecomesBlockedAllTriggeredAbility; import mage.abilities.common.BecomesBlockedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.continuous.BoostAllEffect; @@ -79,7 +81,10 @@ public class BeastmastersMagemark extends CardImpl { ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1,1, Duration.WhileOnBattlefield, filter, false)); this.addAbility(ability); // Whenever a creature you control that's enchanted becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. - this.addAbility(new BeastmastersMagemarkAbility()); + BlockedCreatureCount value = new BlockedCreatureCount(); + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets +1/+1 until end of turn for each creature blocking it"); + this.addAbility(new BecomesBlockedAllTriggeredAbility(effect, false,filter,false)); } public BeastmastersMagemark(final BeastmastersMagemark card) { @@ -137,4 +142,4 @@ class BeastmastersMagemarkValue implements DynamicValue { public String getMessage() { return "+1/+1 until end of turn for each creature blocking it"; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java b/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java index 524fbde5197..d8e1577e167 100644 --- a/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java +++ b/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java @@ -1,119 +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.iceage; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.BecomesBlockedTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.MultipliedValue; -import mage.abilities.effects.Effect; -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.game.Game; -import mage.game.combat.CombatGroup; - -/** - * - * @author fireshoes - */ -public class JohtullWurm extends CardImpl { - - public JohtullWurm(UUID ownerId) { - super(ownerId, 138, "Johtull Wurm", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{5}{G}"); - this.expansionSetCode = "ICE"; - this.subtype.add("Wurm"); - this.power = new MageInt(6); - this.toughness = new MageInt(6); - - // Whenever Johtull Wurm becomes blocked, it gets -2/-1 until end of turn for each creature blocking it beyond the first. - this.addAbility(new JohtullWurmAbility()); - } - - public JohtullWurm(final JohtullWurm card) { - super(card); - } - - @Override - public JohtullWurm copy() { - return new JohtullWurm(this); - } -} - -class JohtullWurmAbility extends BecomesBlockedTriggeredAbility { - - public JohtullWurmAbility() { - super(null, false); - JohtullWurmValue toughnessValue = new JohtullWurmValue(); - DynamicValue powerValue = new MultipliedValue(toughnessValue, 2); - this.addEffect(new BoostSourceEffect(powerValue, toughnessValue, Duration.EndOfTurn)); - } - - public JohtullWurmAbility(final JohtullWurmAbility ability) { - super(ability); - } - - @Override - public JohtullWurmAbility copy() { - return new JohtullWurmAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} becomes blocked, it gets -2/-1 until end of turn for each creature blocking it beyond the first."; - } -} - -class JohtullWurmValue implements DynamicValue { - - @Override - public JohtullWurmValue copy() { - return new JohtullWurmValue(); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? -(blockers - 1) : 0; - } - } - return 0; - } - - @Override - public String getMessage() { - return "-2/-1 until end of turn for each creature blocking it beyond the first"; - } -} - +/* + * 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.iceage; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; +import mage.abilities.dynamicvalue.MultipliedValue; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author fireshoes + */ +public class JohtullWurm extends CardImpl { + + public JohtullWurm(UUID ownerId) { + super(ownerId, 138, "Johtull Wurm", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{5}{G}"); + this.expansionSetCode = "ICE"; + this.subtype.add("Wurm"); + this.power = new MageInt(6); + this.toughness = new MageInt(6); + + // Whenever Johtull Wurm becomes blocked, it gets -2/-1 until end of turn for each creature blocking it beyond the first. + DynamicValue toughnessValue = new MultipliedValue(new BlockedCreatureCount(),2); + int value = Math.negateExact(Integer.parseInt(toughnessValue.toString()) - 1); + + Effect effect = new BoostSourceEffect(powerValue, value, Duration.EndOfTurn); + effect.setText("it gets -2/-1 until end of turn for each creature blocking it beyond the first"); + this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); + } + + public JohtullWurm(final JohtullWurm card) { + super(card); + } + + @Override + public JohtullWurm copy() { + return new JohtullWurm(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/invasion/SparringGolem.java b/Mage.Sets/src/mage/sets/invasion/SparringGolem.java index 9f9a2844949..98304b10f88 100644 --- a/Mage.Sets/src/mage/sets/invasion/SparringGolem.java +++ b/Mage.Sets/src/mage/sets/invasion/SparringGolem.java @@ -1,116 +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 mage.sets.invasion; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.BecomesBlockedTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; -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.game.Game; -import mage.game.combat.CombatGroup; - -/** - * - * @author fireshoes - */ -public class SparringGolem extends CardImpl { - - public SparringGolem(UUID ownerId) { - super(ownerId, 312, "Sparring Golem", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); - this.expansionSetCode = "INV"; - this.subtype.add("Golem"); - this.power = new MageInt(2); - this.toughness = new MageInt(2); - - // Whenever Sparring Golem becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. - this.addAbility(new SparringGolemAbility()); - } - - public SparringGolem(final SparringGolem card) { - super(card); - } - - @Override - public SparringGolem copy() { - return new SparringGolem(this); - } -} - -class SparringGolemAbility extends BecomesBlockedTriggeredAbility { - - public SparringGolemAbility() { - super(null, false); - SparringGolemValue value = new SparringGolemValue(); - this.addEffect(new BoostSourceEffect(value, value, Duration.EndOfTurn)); - } - - public SparringGolemAbility(final SparringGolemAbility ability) { - super(ability); - } - - @Override - public SparringGolemAbility copy() { - return new SparringGolemAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} becomes blocked, it gets +1/+1 until end of turn for each creature blocking it."; - } -} - -class SparringGolemValue implements DynamicValue { - - @Override - public SparringGolemValue copy() { - return new SparringGolemValue(); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? (blockers) : 0; - } - } - return 0; - } - - @Override - public String getMessage() { - return "+1/+1 until end of turn for each creature blocking it"; - } -} +/* + * 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.BecomesBlockedTriggeredAbility; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author fireshoes + */ +public class SparringGolem extends CardImpl { + + public SparringGolem(UUID ownerId) { + super(ownerId, 312, "Sparring Golem", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}"); + this.expansionSetCode = "INV"; + this.subtype.add("Golem"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Sparring Golem becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. + BlockedCreatureCount value = new BlockedCreatureCount(); + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets +1/+1 until end of turn for each creature blocking it"); + this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); + } + + public SparringGolem(final SparringGolem card) { + super(card); + } + + @Override + public SparringGolem copy() { + return new SparringGolem(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/legions/BerserkMurlodont.java b/Mage.Sets/src/mage/sets/legions/BerserkMurlodont.java index d0c38c0faec..dcddb71fa2d 100644 --- a/Mage.Sets/src/mage/sets/legions/BerserkMurlodont.java +++ b/Mage.Sets/src/mage/sets/legions/BerserkMurlodont.java @@ -1,67 +1,76 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.sets.legions; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility; -import mage.abilities.effects.Effect; -import mage.abilities.effects.common.continuous.BoostSourceEffect; -import mage.cards.CardImpl; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Rarity; - -/** - * - * @author fireshoes - */ -public class BerserkMurlodont extends CardImpl { - - public BerserkMurlodont(UUID ownerId) { - super(ownerId, 117, "Berserk Murlodont", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{G}"); - this.expansionSetCode = "LGN"; - this.subtype.add("Beast"); - this.power = new MageInt(3); - this.toughness = new MageInt(3); - - // Whenever a Beast becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. - Effect effect = new BoostSourceEffect(1, 1, Duration.EndOfTurn); - effect.setText("it gets +1/+1 until end of turn for each creature blocking it"); - this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(effect, false)); - } - - public BerserkMurlodont(final BerserkMurlodont card) { - super(card); - } - - @Override - public BerserkMurlodont copy() { - return new BerserkMurlodont(this); - } -} +/* + * 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.legions; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesBlockedAllTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; + +/** + * + * @author Markedagain + */ +public class BerserkMurlodont extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a Beast"); + static { + filter.add(new SubtypePredicate("Beast")); + } + + public BerserkMurlodont(UUID ownerId) { + super(ownerId, 117, "Berserk Murlodont", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{G}"); + this.expansionSetCode = "LGN"; + this.subtype.add("Beast"); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // Whenever a Beast becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. + BlockedCreatureCount value = new BlockedCreatureCount(); + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets +1/+1 until end of turn for each creature blocking it"); + this.addAbility(new BecomesBlockedAllTriggeredAbility(effect, false,filter,false)); + } + + public BerserkMurlodont(final BerserkMurlodont card) { + super(card); + } + + @Override + public BerserkMurlodont copy() { + return new BerserkMurlodont(this); + } +} diff --git a/Mage.Sets/src/mage/sets/mirage/JungleWurm.java b/Mage.Sets/src/mage/sets/mirage/JungleWurm.java index 0ad27034812..947fc82784c 100644 --- a/Mage.Sets/src/mage/sets/mirage/JungleWurm.java +++ b/Mage.Sets/src/mage/sets/mirage/JungleWurm.java @@ -1,119 +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.mirage; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.BecomesBlockedTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; -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.game.Game; -import mage.game.combat.CombatGroup; -import mage.game.events.GameEvent; - -/** - * - * @author LoneFox - */ -public class JungleWurm extends CardImpl { - - public JungleWurm(UUID ownerId) { - super(ownerId, 122, "Jungle Wurm", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); - this.expansionSetCode = "MIR"; - this.subtype.add("Wurm"); - this.power = new MageInt(5); - this.toughness = new MageInt(5); - - // Whenever Jungle Wurm becomes blocked, it gets -1/-1 until end of turn for each creature blocking it beyond the first. - this.addAbility(new JungleWurmAbility()); - } - - public JungleWurm(final JungleWurm card) { - super(card); - } - - @Override - public JungleWurm copy() { - return new JungleWurm(this); - } -} - -class JungleWurmAbility extends BecomesBlockedTriggeredAbility { - - public JungleWurmAbility() { - super(null, false); - JungleWurmValue value = new JungleWurmValue(); - this.addEffect(new BoostSourceEffect(value, value, Duration.EndOfTurn)); - } - - public JungleWurmAbility(final JungleWurmAbility ability) { - super(ability); - } - - @Override - public JungleWurmAbility copy() { - return new JungleWurmAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} becomes blocked, it gets -1/-1 until end of turn for each creature blocking it beyond the first."; - } -} - -class JungleWurmValue implements DynamicValue { - - @Override - public JungleWurmValue copy() { - return new JungleWurmValue(); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - int count = 0; - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? -(blockers - 1) : 0; - } - } - return 0; - } - - @Override - public String getMessage() { - return "-1/-1 until end of turn for each creature blocking it beyond the first"; - } -} - +/* + * 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.mirage; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author LoneFox + */ +public class JungleWurm extends CardImpl { + + public JungleWurm(UUID ownerId) { + super(ownerId, 122, "Jungle Wurm", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Wurm"); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Whenever Jungle Wurm becomes blocked, it gets -1/-1 until end of turn for each creature blocking it beyond the first. + BlockedCreatureCount blockedCreatureCount = new BlockedCreatureCount(); + int value = Math.negateExact(Integer.parseInt(blockedCreatureCount.toString()) - 1); + + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets -1/-1 until end of turn for each creature blocking it beyond the first"); + this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); + } + + public JungleWurm(final JungleWurm card) { + super(card); + } + + @Override + public JungleWurm copy() { + return new JungleWurm(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java b/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java index b53ffa4298b..6f3a35091e8 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java +++ b/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java @@ -1,117 +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.ninthedition; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.BecomesBlockedTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; -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.game.Game; -import mage.game.combat.CombatGroup; - -/** - * - * @author ilcartographer - */ -public class ElvishBerserker extends CardImpl { - - public ElvishBerserker(UUID ownerId) { - super(ownerId, 237, "Elvish Berserker", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{G}"); - this.expansionSetCode = "9ED"; - this.subtype.add("Elf"); - this.subtype.add("Berserker"); - this.power = new MageInt(1); - this.toughness = new MageInt(1); - - // Whenever Elvish Berserker becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. - this.addAbility(new ElvishBerserkerAbility()); - } - - public ElvishBerserker(final ElvishBerserker card) { - super(card); - } - - @Override - public ElvishBerserker copy() { - return new ElvishBerserker(this); - } -} - -class ElvishBerserkerAbility extends BecomesBlockedTriggeredAbility { - - public ElvishBerserkerAbility() { - super(null, false); - ElvishBerserkerValue value = new ElvishBerserkerValue(); - this.addEffect(new BoostSourceEffect(value, value, Duration.EndOfTurn)); - } - - public ElvishBerserkerAbility(final ElvishBerserkerAbility ability) { - super(ability); - } - - @Override - public ElvishBerserkerAbility copy() { - return new ElvishBerserkerAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} becomes blocked, it gets +1/+1 until end of turn for each creature blocking it."; - } -} - -class ElvishBerserkerValue implements DynamicValue { - - @Override - public ElvishBerserkerValue copy() { - return new ElvishBerserkerValue(); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? (blockers) : 0; - } - } - return 0; - } - - @Override - public String getMessage() { - return "+1/+1 until end of turn for each creature blocking it"; - } -} +/* + * 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.ninthedition; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; +import mage.abilities.effects.Effect; +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.game.Game; +import mage.game.combat.CombatGroup; + +/** + * + * @author ilcartographer + */ +public class ElvishBerserker extends CardImpl { + + public ElvishBerserker(UUID ownerId) { + super(ownerId, 237, "Elvish Berserker", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{G}"); + this.expansionSetCode = "9ED"; + this.subtype.add("Elf"); + this.subtype.add("Berserker"); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Whenever Elvish Berserker becomes blocked, it gets +1/+1 until end of turn for each creature blocking it. + BlockedCreatureCount value = new BlockedCreatureCount(); + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets +1/+1 until end of turn for each creature blocking it"); + this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); + } + + public ElvishBerserker(final ElvishBerserker card) { + super(card); + } + + @Override + public ElvishBerserker copy() { + return new ElvishBerserker(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/odyssey/RabidElephant.java b/Mage.Sets/src/mage/sets/odyssey/RabidElephant.java index 4c496f27b80..7d4dac87c25 100644 --- a/Mage.Sets/src/mage/sets/odyssey/RabidElephant.java +++ b/Mage.Sets/src/mage/sets/odyssey/RabidElephant.java @@ -1,117 +1,72 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.sets.odyssey; - -import java.util.UUID; -import mage.MageInt; -import mage.abilities.Ability; -import mage.abilities.common.BecomesBlockedTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.effects.Effect; -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.game.Game; -import mage.game.combat.CombatGroup; - -/** - * - * @author LevelX2 - */ -public class RabidElephant extends CardImpl { - - public RabidElephant(UUID ownerId) { - super(ownerId, 263, "Rabid Elephant", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{G}"); - this.expansionSetCode = "ODY"; - this.subtype.add("Elephant"); - - this.power = new MageInt(3); - this.toughness = new MageInt(4); - - // Whenever Rabid Elephant becomes blocked, it gets +2/+2 until end of turn for each creature blocking it. - this.addAbility(new RabidElephantAbility()); - } - - public RabidElephant(final RabidElephant card) { - super(card); - } - - @Override - public RabidElephant copy() { - return new RabidElephant(this); - } -} - -class RabidElephantAbility extends BecomesBlockedTriggeredAbility { - - public RabidElephantAbility() { - super(null, false); - RabidElephantValue value = new RabidElephantValue(); - this.addEffect(new BoostSourceEffect(value, value, Duration.EndOfTurn)); - } - - public RabidElephantAbility(final RabidElephantAbility ability) { - super(ability); - } - - @Override - public RabidElephantAbility copy() { - return new RabidElephantAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} becomes blocked, it gets +2/+2 until end of turn for each creature blocking it."; - } -} - -class RabidElephantValue implements DynamicValue { - - @Override - public RabidElephantValue copy() { - return new RabidElephantValue(); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? (blockers) * 2 : 0; - } - } - return 0; - } - - @Override - public String getMessage() { - return "+2/+2 until end of turn for each creature blocking it"; - } -} +/* + * 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.odyssey; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.MultipliedValue; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class RabidElephant extends CardImpl { + + public RabidElephant(UUID ownerId) { + super(ownerId, 263, "Rabid Elephant", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{G}"); + this.expansionSetCode = "ODY"; + this.subtype.add("Elephant"); + + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Whenever Rabid Elephant becomes blocked, it gets +2/+2 until end of turn for each creature blocking it. + DynamicValue value = new MultipliedValue(new BlockedCreatureCount(),2); + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets +2/+2 until end of turn for each creature blocking it"); + this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); + } + + public RabidElephant(final RabidElephant card) { + super(card); + } + + @Override + public RabidElephant copy() { + return new RabidElephant(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/portalsecondage/RazorclawBear.java b/Mage.Sets/src/mage/sets/portalsecondage/RazorclawBear.java index f8746c1fa22..3fda93ee35a 100644 --- a/Mage.Sets/src/mage/sets/portalsecondage/RazorclawBear.java +++ b/Mage.Sets/src/mage/sets/portalsecondage/RazorclawBear.java @@ -52,7 +52,7 @@ public class RazorclawBear extends CardImpl { // Whenever Razorclaw Bear becomes blocked, it gets +2/+2 until end of turn. Effect effect = new BoostSourceEffect(2, 2, Duration.EndOfTurn); - effect.setText("it gets +2/+2 until end of turn for each creature blocking it"); + effect.setText("it gets +2/+2 until end of turn"); this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); } diff --git a/Mage.Sets/src/mage/sets/stronghold/SpinedSliver.java b/Mage.Sets/src/mage/sets/stronghold/SpinedSliver.java index da10b8dc8f6..cf3f572246f 100644 --- a/Mage.Sets/src/mage/sets/stronghold/SpinedSliver.java +++ b/Mage.Sets/src/mage/sets/stronghold/SpinedSliver.java @@ -32,6 +32,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; +import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.abilities.effects.common.continuous.GainAbilityAllEffect; import mage.cards.CardImpl; @@ -54,7 +56,6 @@ public class SpinedSliver extends CardImpl { filter.add(new SubtypePredicate("Sliver")); } - public SpinedSliver(UUID ownerId) { super(ownerId, 142, "Spined Sliver", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{R}{G}"); this.expansionSetCode = "STH"; @@ -64,7 +65,10 @@ public class SpinedSliver extends CardImpl { this.toughness = new MageInt(2); // Whenever a Sliver becomes blocked, that Sliver gets +1/+1 until end of turn for each creature blocking it. - Ability ability = new BecomesBlockedByCreatureTriggeredAbility(new BoostSourceEffect(1, 1, Duration.EndOfTurn), false); + BlockedCreatureCount value = new BlockedCreatureCount(); + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets +1/+1 until end of turn for each creature blocking it"); + Ability ability = new BecomesBlockedByCreatureTriggeredAbility(effect, false); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, filter, diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java b/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java index ec2120547f7..ddd5f72d933 100644 --- a/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java +++ b/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java @@ -32,6 +32,8 @@ import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesBlockedTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.MultipliedValue; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; @@ -57,7 +59,10 @@ public class GangOfElk extends CardImpl { this.toughness = new MageInt(4); // Whenever Gang of Elk becomes blocked, it gets +2/+2 until end of turn for each creature blocking it. - this.addAbility(new GangOfElkAbility()); + DynamicValue value = new MultipliedValue(new BlockedCreatureCount(),2); + Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); + effect.setText("it gets +2/+2 until end of turn for each creature blocking it"); + this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); } public GangOfElk(final GangOfElk card) { @@ -68,51 +73,4 @@ public class GangOfElk extends CardImpl { public GangOfElk copy() { return new GangOfElk(this); } -} - -class GangOfElkAbility extends BecomesBlockedTriggeredAbility { - - public GangOfElkAbility() { - super(null, false); - GangOfElkValue value = new GangOfElkValue(); - this.addEffect(new BoostSourceEffect(value, value, Duration.EndOfTurn)); - } - - public GangOfElkAbility(final GangOfElkAbility ability) { - super(ability); - } - - @Override - public GangOfElkAbility copy() { - return new GangOfElkAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} becomes blocked, it gets +2/+2 until end of turn for each creature blocking it."; - } -} - -class GangOfElkValue implements DynamicValue { - - @Override - public GangOfElkValue copy() { - return new GangOfElkValue(); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? (blockers) * 2 : 0; - } - } - return 0; - } - - @Override - public String getMessage() { - return "+2/+2 until end of turn for each creature blocking it"; - } -} +} \ No newline at end of file diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java new file mode 100644 index 00000000000..ff7a3fd15bd --- /dev/null +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java @@ -0,0 +1,81 @@ +/* + * 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.dynamicvalue.common; + +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.Effect; +import mage.game.Game; +import mage.game.combat.CombatGroup; + +/** + * + * @author Markedagain + */ +public class BlockedCreatureCount implements DynamicValue { + private String message; + + public BlockedCreatureCount() { + this("each creature blocking it"); + } + + public BlockedCreatureCount(String message) { + this.message = message; + } + + public BlockedCreatureCount(final BlockedCreatureCount dynamicValue) { + super(); + this.message = dynamicValue.message; + } + + @Override + public int calculate(Game game, Ability sourceAbility, Effect effect) { + for(CombatGroup combatGroup : game.getCombat().getGroups()) { + if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { + int blockers = combatGroup.getBlockers().size(); + return blockers > 1 ? (blockers) : 0; + } + } + return 0; + } + + @Override + public BlockedCreatureCount copy() { + return new BlockedCreatureCount(this); + } + + @Override + public String getMessage() { + return message; + } + + @Override + public String toString() { + return "X"; + } +} From 502ecd88582eb3bc3f88a213361241d8d0610eba Mon Sep 17 00:00:00 2001 From: markedagain Date: Wed, 24 Feb 2016 00:32:39 -0500 Subject: [PATCH 06/17] Fixed getPlayerList references --- .../mage/sets/alarareborn/TaintedSigil.java | 2 +- .../sets/conspiracy/ExtractFromDarkness.java | 2 +- .../sets/darkascension/CurseOfEchoes.java | 2 +- Mage.Sets/src/mage/sets/exodus/Cataclysm.java | 2 +- .../src/mage/sets/invasion/GlobalRuin.java | 3 +- .../mage/sets/lorwyn/ArbiterOfKnollridge.java | 6 ++-- .../src/mage/sets/magic2013/Worldfire.java | 2 +- .../src/mage/sets/onslaught/WordsOfWind.java | 2 +- .../src/mage/sets/planechase/SyphonSoul.java | 2 +- .../riseoftheeldrazi/PestilenceDemon.java | 2 +- .../sets/scourge/DecreeOfAnnihilation.java | 2 +- .../src/mage/sets/urzassaga/Whetstone.java | 2 +- .../src/mage/sets/zendikar/WorldQueller.java | 31 +++++-------------- 13 files changed, 22 insertions(+), 38 deletions(-) diff --git a/Mage.Sets/src/mage/sets/alarareborn/TaintedSigil.java b/Mage.Sets/src/mage/sets/alarareborn/TaintedSigil.java index 905f22ddacd..47da23ea1ad 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/TaintedSigil.java +++ b/Mage.Sets/src/mage/sets/alarareborn/TaintedSigil.java @@ -87,7 +87,7 @@ class AllPlayersLostLifeCount implements DynamicValue { PlayerLostLifeWatcher watcher = (PlayerLostLifeWatcher) game.getState().getWatchers().get("PlayerLostLifeWatcher"); if (watcher != null) { int amountLifeLost = 0; - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(controllerId, game)) { amountLifeLost += watcher.getLiveLost(playerId); } return amountLifeLost; diff --git a/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java b/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java index 4fe08b08edc..ec1c37fda95 100644 --- a/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java +++ b/Mage.Sets/src/mage/sets/conspiracy/ExtractFromDarkness.java @@ -80,7 +80,7 @@ class ExtractFromDarknessMillEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.LIBRARY, Zone.GRAVEYARD, source, game); diff --git a/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java b/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java index ad3f964a8b2..dfee5dd7f9c 100644 --- a/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java +++ b/Mage.Sets/src/mage/sets/darkascension/CurseOfEchoes.java @@ -147,7 +147,7 @@ class CurseOfEchoesEffect extends OneShotEffect { Spell spell = game.getStack().getSpell(targetPointer.getFirst(game, source)); if (spell != null) { String chooseMessage = "Copy target spell? You may choose new targets for the copy."; - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { if (!playerId.equals(spell.getControllerId())) { Player player = game.getPlayer(playerId); if (player.chooseUse(Outcome.Copy, chooseMessage, source, game)) { diff --git a/Mage.Sets/src/mage/sets/exodus/Cataclysm.java b/Mage.Sets/src/mage/sets/exodus/Cataclysm.java index ac1df0bf079..5c7953f2a0b 100644 --- a/Mage.Sets/src/mage/sets/exodus/Cataclysm.java +++ b/Mage.Sets/src/mage/sets/exodus/Cataclysm.java @@ -86,7 +86,7 @@ class CataclysmEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { List chosen = new ArrayList<>(); - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); Target target1 = new TargetControlledPermanent(1, 1, new FilterControlledArtifactPermanent(), true); diff --git a/Mage.Sets/src/mage/sets/invasion/GlobalRuin.java b/Mage.Sets/src/mage/sets/invasion/GlobalRuin.java index 691ca31ce50..635764fc927 100644 --- a/Mage.Sets/src/mage/sets/invasion/GlobalRuin.java +++ b/Mage.Sets/src/mage/sets/invasion/GlobalRuin.java @@ -44,7 +44,6 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetControlledPermanent; -import mage.target.common.TargetLandPermanent; /** * @@ -90,7 +89,7 @@ class GlobalRuinDestroyLandEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Set lands = new HashSet<>(); - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); for (String landName : new String[]{"Forest", "Island", "Mountain", "Plains", "Swamp"}) { FilterControlledLandPermanent filter = new FilterControlledLandPermanent(landName + " you control"); diff --git a/Mage.Sets/src/mage/sets/lorwyn/ArbiterOfKnollridge.java b/Mage.Sets/src/mage/sets/lorwyn/ArbiterOfKnollridge.java index 146d923b0ee..95c7c0d61fd 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/ArbiterOfKnollridge.java +++ b/Mage.Sets/src/mage/sets/lorwyn/ArbiterOfKnollridge.java @@ -40,6 +40,7 @@ import mage.cards.CardImpl; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; +import mage.players.PlayerList; /** * @@ -85,7 +86,8 @@ class ArbiterOfKnollridgeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int maxLife = 0; - for (UUID pid : game.getPlayerList()) { + PlayerList playerList = game.getState().getPlayersInRange(source.getControllerId(), game); + for (UUID pid : playerList) { Player p = game.getPlayer(pid); if (p != null) { if (maxLife < p.getLife()) { @@ -93,7 +95,7 @@ class ArbiterOfKnollridgeEffect extends OneShotEffect { } } } - for (UUID pid : game.getPlayerList()) { + for (UUID pid : playerList) { Player p = game.getPlayer(pid); if (p != null) { p.setLife(maxLife, game); diff --git a/Mage.Sets/src/mage/sets/magic2013/Worldfire.java b/Mage.Sets/src/mage/sets/magic2013/Worldfire.java index 4ef69e58ec6..7a4fe173a8d 100644 --- a/Mage.Sets/src/mage/sets/magic2013/Worldfire.java +++ b/Mage.Sets/src/mage/sets/magic2013/Worldfire.java @@ -89,7 +89,7 @@ class WorldfireEffect extends OneShotEffect { for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { permanent.moveToExile(id, "all permanents", id, game); } - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { for (UUID cid : player.getHand().copy()) { diff --git a/Mage.Sets/src/mage/sets/onslaught/WordsOfWind.java b/Mage.Sets/src/mage/sets/onslaught/WordsOfWind.java index 756f729d359..fae884fb83a 100644 --- a/Mage.Sets/src/mage/sets/onslaught/WordsOfWind.java +++ b/Mage.Sets/src/mage/sets/onslaught/WordsOfWind.java @@ -92,7 +92,7 @@ class WordsOfWindEffect extends ReplacementEffectImpl { @Override public boolean replaceEvent(GameEvent event, Ability source, Game game) { game.informPlayers("Each player returns a permanent he or she controls to its owner's hand instead"); - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { TargetControlledPermanent target = new TargetControlledPermanent(); diff --git a/Mage.Sets/src/mage/sets/planechase/SyphonSoul.java b/Mage.Sets/src/mage/sets/planechase/SyphonSoul.java index e8906dabdaa..6b643e265cc 100644 --- a/Mage.Sets/src/mage/sets/planechase/SyphonSoul.java +++ b/Mage.Sets/src/mage/sets/planechase/SyphonSoul.java @@ -74,7 +74,7 @@ class SyphonSoulEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int damageDealt = 0; - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { if (!playerId.equals(source.getControllerId())) { damageDealt += game.getPlayer(playerId).damage(2, source.getSourceId(), game, false, true); } diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/PestilenceDemon.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/PestilenceDemon.java index 0256675d651..c34ee564b2a 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/PestilenceDemon.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/PestilenceDemon.java @@ -90,7 +90,7 @@ class PestilenceDemonEffect extends OneShotEffect { p.damage(1, source.getSourceId(), game, false, true); } } - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player p = game.getPlayer(playerId); if (p != null) { p.damage(1, source.getSourceId(), game, false, true); diff --git a/Mage.Sets/src/mage/sets/scourge/DecreeOfAnnihilation.java b/Mage.Sets/src/mage/sets/scourge/DecreeOfAnnihilation.java index 8f1efa909a3..6c92e5b9ee9 100644 --- a/Mage.Sets/src/mage/sets/scourge/DecreeOfAnnihilation.java +++ b/Mage.Sets/src/mage/sets/scourge/DecreeOfAnnihilation.java @@ -108,7 +108,7 @@ class DecreeOfAnnihilationEffect extends OneShotEffect { for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { permanent.moveToExile(id, "all artifacts, creatures, and land", id, game); } - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { for (UUID cid : player.getHand().copy()) { diff --git a/Mage.Sets/src/mage/sets/urzassaga/Whetstone.java b/Mage.Sets/src/mage/sets/urzassaga/Whetstone.java index 0dc9de8d86b..b513741ee9f 100644 --- a/Mage.Sets/src/mage/sets/urzassaga/Whetstone.java +++ b/Mage.Sets/src/mage/sets/urzassaga/Whetstone.java @@ -80,7 +80,7 @@ class WhetstoneEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - for (UUID playerId : game.getPlayerList()) { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { player.moveCards(player.getLibrary().getTopCards(game, 2), Zone.LIBRARY, Zone.GRAVEYARD, source, game); diff --git a/Mage.Sets/src/mage/sets/zendikar/WorldQueller.java b/Mage.Sets/src/mage/sets/zendikar/WorldQueller.java index d85879e1ff7..53cdea0dacc 100644 --- a/Mage.Sets/src/mage/sets/zendikar/WorldQueller.java +++ b/Mage.Sets/src/mage/sets/zendikar/WorldQueller.java @@ -45,7 +45,6 @@ import mage.cards.Card; import mage.cards.CardImpl; import mage.choices.Choice; import mage.choices.ChoiceImpl; -import mage.filter.FilterPermanent; import mage.filter.common.FilterControlledPermanent; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; @@ -115,12 +114,12 @@ class WorldQuellerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { List chosen = new ArrayList<>(); - Player you = game.getPlayer(source.getControllerId()); + Player player = game.getPlayer(source.getControllerId()); Permanent sourceCreature = game.getPermanent(source.getSourceId()); - if (you != null && sourceCreature != null) { + if (player != null && sourceCreature != null) { Choice choiceImpl = new ChoiceImpl(); choiceImpl.setChoices(choice); - while (you.canRespond() && !you.choose(Outcome.Neutral, choiceImpl, game)) {} + while (player.canRespond() && !player.choose(Outcome.Neutral, choiceImpl, game)) {} CardType type = null; String choosenType = choiceImpl.getChoice(); @@ -148,26 +147,11 @@ class WorldQuellerEffect extends OneShotEffect { TargetPermanent target = new TargetControlledPermanent(1, 1, filter, false); target.setNotTarget(true); - // you always go first - if (target.canChoose(you.getId(), game)) { - while (you.canRespond() && !target.isChosen() && target.canChoose(you.getId(), game)) { - you.choose(Outcome.Sacrifice, target, source.getSourceId(), game); - } - Permanent permanent = game.getPermanent(target.getFirstTarget()); - if (permanent != null) { - chosen.add(permanent); - } - } - - target.clearChosen(); - - // opponents follow - for (UUID playerId : game.getPlayerList()) { - if (playerId != you.getId()) { - Player player = game.getPlayer(playerId); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player2 = game.getPlayer(playerId); if (target.canChoose(playerId, game)) { - while (!target.isChosen() && target.canChoose(playerId, game)) { - player.chooseTarget(Outcome.Sacrifice, target, source, game); + while (player2.canRespond() && !target.isChosen() && target.canChoose(playerId, game)) { + player2.chooseTarget(Outcome.Sacrifice, target, source, game); } Permanent permanent = game.getPermanent(target.getFirstTarget()); if (permanent != null) { @@ -175,7 +159,6 @@ class WorldQuellerEffect extends OneShotEffect { } target.clearChosen(); } - } } // all chosen permanents are sacrificed together From 58ea586ca58718d8316b0ba357337df6adf0d1df Mon Sep 17 00:00:00 2001 From: markedagain Date: Wed, 24 Feb 2016 01:04:42 -0500 Subject: [PATCH 07/17] Removed unused class --- .../sets/guildpact/BeastmastersMagemark.java | 53 +------------------ 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java b/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java index ca3bb751497..51659bd9544 100644 --- a/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java +++ b/Mage.Sets/src/mage/sets/guildpact/BeastmastersMagemark.java @@ -30,9 +30,7 @@ package mage.sets.guildpact; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.common.BecomesBlockedAllTriggeredAbility; -import mage.abilities.common.BecomesBlockedTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.BlockedCreatureCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.AttachEffect; @@ -49,8 +47,6 @@ import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.filter.predicate.permanent.EnchantedPredicate; -import mage.game.Game; -import mage.game.combat.CombatGroup; import mage.target.TargetPermanent; import mage.target.common.TargetCreaturePermanent; @@ -95,51 +91,4 @@ public class BeastmastersMagemark extends CardImpl { public BeastmastersMagemark copy() { return new BeastmastersMagemark(this); } -} - -class BeastmastersMagemarkAbility extends BecomesBlockedTriggeredAbility { - - public BeastmastersMagemarkAbility() { - super(null, false); - BeastmastersMagemarkValue value = new BeastmastersMagemarkValue(); - this.addEffect(new BoostSourceEffect(value, value, Duration.EndOfTurn)); - } - - public BeastmastersMagemarkAbility(final BeastmastersMagemarkAbility ability) { - super(ability); - } - - @Override - public BeastmastersMagemarkAbility copy() { - return new BeastmastersMagemarkAbility(this); - } - - @Override - public String getRule() { - return "Whenever {this} becomes blocked, it gets +1/+1 until end of turn for each creature blocking it."; - } -} - -class BeastmastersMagemarkValue implements DynamicValue { - - @Override - public BeastmastersMagemarkValue copy() { - return new BeastmastersMagemarkValue(); - } - - @Override - public int calculate(Game game, Ability sourceAbility, Effect effect) { - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? (blockers) : 0; - } - } - return 0; - } - - @Override - public String getMessage() { - return "+1/+1 until end of turn for each creature blocking it"; - } -} +} \ No newline at end of file From 708474822665c78a60613acca1073784b54807c6 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 24 Feb 2016 10:55:30 +0100 Subject: [PATCH 08/17] * Fixed a bug that token permanents were not bounced to hand (related to Reduce to Dreams, Whelming Wave, Part the Veil, Retract, Inundate, AEtherize, Dromar the Banisher, Thousand Winds, Crush of Tentacles, Upheaval, Waterspout Elemental, Kederekt Leviathan, Denizen of the Deep, Llawan Cephalid Empress). --- .../mage/test/cards/abilities/keywords/SurgeTest.java | 9 +++++++++ .../common/ReturnToHandFromBattlefieldAllEffect.java | 11 ++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SurgeTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SurgeTest.java index 171781717c0..a636fe4d5bc 100644 --- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SurgeTest.java +++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/SurgeTest.java @@ -70,17 +70,26 @@ public class SurgeTest extends CardTestPlayerBase { addCard(Zone.HAND, playerA, "Crush of Tentacles"); // {4}{U}{U} addCard(Zone.HAND, playerA, "Lightning Bolt"); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion"); + + // Put a token onto the battlefield that's a copy of target creature you control. + // Flashback {5}{U}{U}(You may cast this card from your graveyard for its flashback cost. Then exile it.) + addCard(Zone.HAND, playerB, "Cackling Counterpart"); + addCard(Zone.BATTLEFIELD, playerB, "Island", 3); addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion"); castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cackling Counterpart", "Silvercoat Lion"); + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Crush of Tentacles with surge"); setStopAt(1, PhaseStep.BEGIN_COMBAT); execute(); assertGraveyardCount(playerA, "Lightning Bolt", 1); + assertGraveyardCount(playerB, "Cackling Counterpart", 1); assertGraveyardCount(playerA, "Crush of Tentacles", 1); assertPermanentCount(playerA, "Octopus", 1); + assertPermanentCount(playerB, "Silvercoat Lion", 0); assertHandCount(playerA, "Silvercoat Lion", 1); assertHandCount(playerB, "Silvercoat Lion", 1); assertPermanentCount(playerA, 7); diff --git a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java index 67977bfa6d2..403295e818d 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/ReturnToHandFromBattlefieldAllEffect.java @@ -27,10 +27,11 @@ */ package mage.abilities.effects.common; +import java.util.HashSet; +import java.util.Set; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Cards; -import mage.cards.CardsImpl; +import mage.cards.Card; import mage.constants.Outcome; import mage.constants.Zone; import mage.filter.FilterPermanent; @@ -61,11 +62,11 @@ public class ReturnToHandFromBattlefieldAllEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null) { - Cards cardsToHand = new CardsImpl(); + Set permanentsToHand = new HashSet<>(); for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - cardsToHand.add(permanent); + permanentsToHand.add(permanent); } - controller.moveCards(cardsToHand, Zone.HAND, source, game); + controller.moveCards(permanentsToHand, Zone.HAND, source, game); return true; } return false; From b8512476224b7a3b261872a77e4e49ecb5061057 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 24 Feb 2016 11:04:56 +0100 Subject: [PATCH 09/17] * Stonecloaker - Fixed that the return to hand ability was not mandatory. --- Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java b/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java index 92b4f50836f..d867cf82338 100644 --- a/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java +++ b/Mage.Sets/src/mage/sets/commander2013/Stonecloaker.java @@ -60,7 +60,7 @@ public class Stonecloaker extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // When Stonecloaker enters the battlefield, return a creature you control to its owner's hand. - Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(new FilterControlledCreaturePermanent()), true); + Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandChosenControlledPermanentEffect(new FilterControlledCreaturePermanent()), false); this.addAbility(ability); // When Stonecloaker enters the battlefield, exile target card from a graveyard. From e87727dd763cf3ca4c5df4e47970908a14df6ca6 Mon Sep 17 00:00:00 2001 From: markedagain Date: Wed, 24 Feb 2016 12:25:39 -0500 Subject: [PATCH 10/17] fixed wrong calculation for wurm --- Mage.Sets/src/mage/sets/iceage/JohtullWurm.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java b/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java index d8e1577e167..345a9a1ac7a 100644 --- a/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java +++ b/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java @@ -54,9 +54,10 @@ public class JohtullWurm extends CardImpl { this.toughness = new MageInt(6); // Whenever Johtull Wurm becomes blocked, it gets -2/-1 until end of turn for each creature blocking it beyond the first. - DynamicValue toughnessValue = new MultipliedValue(new BlockedCreatureCount(),2); - int value = Math.negateExact(Integer.parseInt(toughnessValue.toString()) - 1); - + DynamicValue blockedCreatureCount = new BlockedCreatureCount(); + int value = Math.negateExact(Integer.parseInt(blockedCreatureCount.toString()) - 1); + int powerValue = value * 2; + Effect effect = new BoostSourceEffect(powerValue, value, Duration.EndOfTurn); effect.setText("it gets -2/-1 until end of turn for each creature blocking it beyond the first"); this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); @@ -70,4 +71,4 @@ public class JohtullWurm extends CardImpl { public JohtullWurm copy() { return new JohtullWurm(this); } -} \ No newline at end of file +} From b41c4822e989f847b7aa0b46fca477b29842c180 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Wed, 24 Feb 2016 22:31:19 +0100 Subject: [PATCH 11/17] Fixed BlockedCreatureCount handling. --- Mage.Sets/src/mage/sets/coldsnap/RuneSnag.java | 4 ++-- .../src/mage/sets/iceage/JohtullWurm.java | 9 +++------ Mage.Sets/src/mage/sets/mirage/JungleWurm.java | 9 +++++---- .../sets/ninthedition/ElvishBerserker.java | 6 +----- .../src/mage/sets/urzaslegacy/GangOfElk.java | 7 ++----- .../common/BlockedCreatureCount.java | 18 ++++++++++++++---- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Mage.Sets/src/mage/sets/coldsnap/RuneSnag.java b/Mage.Sets/src/mage/sets/coldsnap/RuneSnag.java index 70bcf87ea59..31b4c09315a 100644 --- a/Mage.Sets/src/mage/sets/coldsnap/RuneSnag.java +++ b/Mage.Sets/src/mage/sets/coldsnap/RuneSnag.java @@ -45,8 +45,9 @@ import mage.target.TargetSpell; * @author emerald000 */ public class RuneSnag extends CardImpl { - + private static final FilterCard filter = new FilterCard(); + static { filter.add(new NamePredicate("Rune Snag")); } @@ -55,7 +56,6 @@ public class RuneSnag extends CardImpl { super(ownerId, 46, "Rune Snag", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}"); this.expansionSetCode = "CSP"; - // Counter target spell unless its controller pays {2} plus an additional {2} for each card named Rune Snag in each graveyard. Effect effect = new CounterUnlessPaysEffect(new IntPlusDynamicValue(2, new MultipliedValue(new CardsInAllGraveyardsCount(filter), 2))); effect.setText("Counter target spell unless its controller pays {2} plus an additional {2} for each card named Rune Snag in each graveyard"); diff --git a/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java b/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java index 345a9a1ac7a..d1fd3b5b7af 100644 --- a/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java +++ b/Mage.Sets/src/mage/sets/iceage/JohtullWurm.java @@ -31,8 +31,8 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesBlockedTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.BlockedCreatureCount; import mage.abilities.dynamicvalue.MultipliedValue; +import mage.abilities.dynamicvalue.common.BlockedCreatureCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostSourceEffect; import mage.cards.CardImpl; @@ -54,11 +54,8 @@ public class JohtullWurm extends CardImpl { this.toughness = new MageInt(6); // Whenever Johtull Wurm becomes blocked, it gets -2/-1 until end of turn for each creature blocking it beyond the first. - DynamicValue blockedCreatureCount = new BlockedCreatureCount(); - int value = Math.negateExact(Integer.parseInt(blockedCreatureCount.toString()) - 1); - int powerValue = value * 2; - - Effect effect = new BoostSourceEffect(powerValue, value, Duration.EndOfTurn); + DynamicValue blockedCreatureCount = new BlockedCreatureCount("each creature blocking it beyond the first", true); + Effect effect = new BoostSourceEffect(new MultipliedValue(blockedCreatureCount, -2), new MultipliedValue(blockedCreatureCount, -1), Duration.EndOfTurn); effect.setText("it gets -2/-1 until end of turn for each creature blocking it beyond the first"); this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); } diff --git a/Mage.Sets/src/mage/sets/mirage/JungleWurm.java b/Mage.Sets/src/mage/sets/mirage/JungleWurm.java index 947fc82784c..7a66ccdecad 100644 --- a/Mage.Sets/src/mage/sets/mirage/JungleWurm.java +++ b/Mage.Sets/src/mage/sets/mirage/JungleWurm.java @@ -30,6 +30,8 @@ package mage.sets.mirage; import java.util.UUID; import mage.MageInt; import mage.abilities.common.BecomesBlockedTriggeredAbility; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.MultipliedValue; import mage.abilities.dynamicvalue.common.BlockedCreatureCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostSourceEffect; @@ -52,9 +54,8 @@ public class JungleWurm extends CardImpl { this.toughness = new MageInt(5); // Whenever Jungle Wurm becomes blocked, it gets -1/-1 until end of turn for each creature blocking it beyond the first. - BlockedCreatureCount blockedCreatureCount = new BlockedCreatureCount(); - int value = Math.negateExact(Integer.parseInt(blockedCreatureCount.toString()) - 1); - + BlockedCreatureCount blockedCreatureCount = new BlockedCreatureCount("each creature blocking it beyond the first", true); + DynamicValue value = new MultipliedValue(blockedCreatureCount, -1); Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); effect.setText("it gets -1/-1 until end of turn for each creature blocking it beyond the first"); this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); @@ -68,4 +69,4 @@ public class JungleWurm extends CardImpl { public JungleWurm copy() { return new JungleWurm(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java b/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java index 6f3a35091e8..924d718d4cd 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java +++ b/Mage.Sets/src/mage/sets/ninthedition/ElvishBerserker.java @@ -29,9 +29,7 @@ package mage.sets.ninthedition; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.BecomesBlockedTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.BlockedCreatureCount; import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.BoostSourceEffect; @@ -39,8 +37,6 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.game.Game; -import mage.game.combat.CombatGroup; /** * @@ -71,4 +67,4 @@ public class ElvishBerserker extends CardImpl { public ElvishBerserker copy() { return new ElvishBerserker(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java b/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java index ddd5f72d933..c3ccea99283 100644 --- a/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java +++ b/Mage.Sets/src/mage/sets/urzaslegacy/GangOfElk.java @@ -29,7 +29,6 @@ package mage.sets.urzaslegacy; import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.BecomesBlockedTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.MultipliedValue; @@ -40,8 +39,6 @@ import mage.cards.CardImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Rarity; -import mage.game.Game; -import mage.game.combat.CombatGroup; /** * @@ -59,7 +56,7 @@ public class GangOfElk extends CardImpl { this.toughness = new MageInt(4); // Whenever Gang of Elk becomes blocked, it gets +2/+2 until end of turn for each creature blocking it. - DynamicValue value = new MultipliedValue(new BlockedCreatureCount(),2); + DynamicValue value = new MultipliedValue(new BlockedCreatureCount(), 2); Effect effect = new BoostSourceEffect(value, value, Duration.EndOfTurn); effect.setText("it gets +2/+2 until end of turn for each creature blocking it"); this.addAbility(new BecomesBlockedTriggeredAbility(effect, false)); @@ -73,4 +70,4 @@ public class GangOfElk extends CardImpl { public GangOfElk copy() { return new GangOfElk(this); } -} \ No newline at end of file +} diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java index ff7a3fd15bd..78ac659e793 100644 --- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java +++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/BlockedCreatureCount.java @@ -38,27 +38,37 @@ import mage.game.combat.CombatGroup; * @author Markedagain */ public class BlockedCreatureCount implements DynamicValue { + private String message; + boolean beyondTheFirst; public BlockedCreatureCount() { this("each creature blocking it"); } public BlockedCreatureCount(String message) { + this(message, false); + } + + public BlockedCreatureCount(String message, boolean beyondTheFist) { this.message = message; } public BlockedCreatureCount(final BlockedCreatureCount dynamicValue) { super(); this.message = dynamicValue.message; + this.beyondTheFirst = dynamicValue.beyondTheFirst; } @Override public int calculate(Game game, Ability sourceAbility, Effect effect) { - for(CombatGroup combatGroup : game.getCombat().getGroups()) { - if(combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { - int blockers = combatGroup.getBlockers().size(); - return blockers > 1 ? (blockers) : 0; + for (CombatGroup combatGroup : game.getCombat().getGroups()) { + if (combatGroup.getAttackers().contains(sourceAbility.getSourceId())) { + int blockers = combatGroup.getBlockers().size(); + if (beyondTheFirst) { + blockers = blockers > 0 ? blockers - 1 : 0; + } + return blockers; } } return 0; From 8e671fecaa18ada601c4bae7ab403dece993cdde Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 25 Feb 2016 00:25:33 +0100 Subject: [PATCH 12/17] Added a test. --- .../mage/sets/magic2011/SerraAscendant.java | 42 +++++----- .../sets/timespiral/KaervekTheMerciless.java | 6 +- .../sets/timespiral/TemporalIsolation.java | 5 +- .../prevention/PreventAttachedEffectTest.java | 80 +++++++++++++++++++ .../java/org/mage/test/player/TestPlayer.java | 45 ++++++----- .../PreventAllDamageByAttachedEffect.java | 4 +- 6 files changed, 134 insertions(+), 48 deletions(-) create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAttachedEffectTest.java diff --git a/Mage.Sets/src/mage/sets/magic2011/SerraAscendant.java b/Mage.Sets/src/mage/sets/magic2011/SerraAscendant.java index 6249ea6ee65..8acd2927c35 100644 --- a/Mage.Sets/src/mage/sets/magic2011/SerraAscendant.java +++ b/Mage.Sets/src/mage/sets/magic2011/SerraAscendant.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,22 +20,14 @@ * 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.magic2011; import java.util.UUID; -import mage.constants.CardType; -import mage.constants.Duration; -import mage.constants.Layer; -import mage.constants.Outcome; -import mage.constants.Rarity; -import mage.constants.SubLayer; -import mage.constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; @@ -43,6 +35,13 @@ import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.LifelinkAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Layer; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.SubLayer; +import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; @@ -64,7 +63,7 @@ public class SerraAscendant extends CardImpl { // Lifelink (Damage dealt by this creature also causes you to gain that much life.) this.addAbility(LifelinkAbility.getInstance()); - + // As long as you have 30 or more life, Serra Ascendant gets +5/+5 and has flying. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SerraAscendantEffect())); } @@ -99,9 +98,9 @@ class SerraAscendantEffect extends ContinuousEffectImpl { @Override public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { Permanent creature = game.getPermanent(source.getSourceId()); - if (creature != null) { - Player player = game.getPlayer(creature.getControllerId()); - if (player != null && player.getLife() >= 30) { + Player controller = game.getPlayer(source.getControllerId()); + if (creature != null && controller != null) { + if (controller.getLife() >= 30) { switch (layer) { case PTChangingEffects_7: if (sublayer == SubLayer.ModifyPT_7c) { @@ -111,12 +110,13 @@ class SerraAscendantEffect extends ContinuousEffectImpl { break; case AbilityAddingRemovingEffects_6: if (sublayer == SubLayer.NA) { - creature.addAbility(FlyingAbility.getInstance(), game); + creature.addAbility(FlyingAbility.getInstance(), source.getSourceId(), game); } break; } - return true; + } + return true; } return false; } @@ -128,7 +128,7 @@ class SerraAscendantEffect extends ContinuousEffectImpl { @Override public boolean hasLayer(Layer layer) { - return layer == Layer.AbilityAddingRemovingEffects_6 || layer == layer.PTChangingEffects_7; + return Layer.AbilityAddingRemovingEffects_6.equals(layer) || Layer.PTChangingEffects_7.equals(layer); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/sets/timespiral/KaervekTheMerciless.java b/Mage.Sets/src/mage/sets/timespiral/KaervekTheMerciless.java index 3264e6a9e19..fd737f8ec50 100644 --- a/Mage.Sets/src/mage/sets/timespiral/KaervekTheMerciless.java +++ b/Mage.Sets/src/mage/sets/timespiral/KaervekTheMerciless.java @@ -98,9 +98,9 @@ class KaervekTheMercilessEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - MageObject spellCast = game.getObject(targetPointer.getFirst(game, source)); + MageObject spellCast = game.getObject(getTargetPointer().getFirst(game, source)); if (spellCast instanceof Spell) { - int cost = ((Spell)spellCast).getConvertedManaCost(); + int cost = ((Spell) spellCast).getConvertedManaCost(); Player target = game.getPlayer(source.getFirstTarget()); if (target != null) { target.damage(cost, source.getSourceId(), game, false, true); @@ -108,7 +108,7 @@ class KaervekTheMercilessEffect extends OneShotEffect { } Permanent targetCreature = game.getPermanent(source.getFirstTarget()); if (targetCreature != null) { - targetCreature.damage(cost, source.getSourceId(), game, true, false); + targetCreature.damage(cost, source.getSourceId(), game, false, true); return true; } } diff --git a/Mage.Sets/src/mage/sets/timespiral/TemporalIsolation.java b/Mage.Sets/src/mage/sets/timespiral/TemporalIsolation.java index 804e68e1a8b..4f13fd224c1 100644 --- a/Mage.Sets/src/mage/sets/timespiral/TemporalIsolation.java +++ b/Mage.Sets/src/mage/sets/timespiral/TemporalIsolation.java @@ -57,7 +57,6 @@ public class TemporalIsolation extends CardImpl { this.expansionSetCode = "TSP"; this.subtype.add("Aura"); - // Flash this.addAbility(FlashAbility.getInstance()); // Enchant creature @@ -65,11 +64,11 @@ public class TemporalIsolation extends CardImpl { this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); Ability ability = new EnchantAbility(auraTarget.getTargetName()); - this.addAbility(ability); + this.addAbility(ability); // Enchanted creature has shadow. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ShadowAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield))); // Prevent all damage that would be dealt by enchanted creature. - this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageByAttachedEffect(Duration.WhileOnBattlefield, "enchanted creature", false))); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PreventAllDamageByAttachedEffect(Duration.WhileOnBattlefield, "enchanted creature", false))); } public TemporalIsolation(final TemporalIsolation card) { diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAttachedEffectTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAttachedEffectTest.java new file mode 100644 index 00000000000..3cc1fec3c2f --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/prevention/PreventAttachedEffectTest.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 org.mage.test.cards.prevention; + +import mage.constants.PhaseStep; +import mage.constants.Zone; +import org.junit.Test; +import org.mage.test.serverside.base.CardTestPlayerBase; + +/** + * + * @author LevelX2 + */ +public class PreventAttachedEffectTest extends CardTestPlayerBase { + + /** + * Kaervek the Merciless still deals damage with the triggered ability when + * enchanted with Temporal Isolation. + */ + @Test + public void testDamageToPlayerPrevented() { + // Whenever an opponent casts a spell, Kaervek the Merciless deals damage to target creature or player equal to that spell's converted mana cost. + addCard(Zone.BATTLEFIELD, playerA, "Kaervek the Merciless"); + // Flash + // Enchant creature + // Enchanted creature has shadow. + // Prevent all damage that would be dealt by enchanted creature. + addCard(Zone.HAND, playerA, "Temporal Isolation", 1); // {1}{W} + addCard(Zone.BATTLEFIELD, playerA, "Plains", 2); + + addCard(Zone.HAND, playerB, "Silvercoat Lion", 1); // {1}{W} + addCard(Zone.HAND, playerB, "Pillarfield Ox", 1); // {3}{W} + addCard(Zone.BATTLEFIELD, playerB, "Plains", 6); + + castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Temporal Isolation", "Kaervek the Merciless"); + + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Silvercoat Lion"); + addTarget(playerA, playerB); + castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Pillarfield Ox"); + addTarget(playerA, "Silvercoat Lion"); + + setStopAt(2, PhaseStep.BEGIN_COMBAT); + execute(); + + assertPermanentCount(playerA, "Kaervek the Merciless", 1); + assertPermanentCount(playerA, "Temporal Isolation", 1); + + assertPermanentCount(playerB, "Silvercoat Lion", 1); + assertPermanentCount(playerB, "Pillarfield Ox", 1); + + assertLife(playerA, 20); + assertLife(playerB, 20); + } + +} diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 8618a73267d..588dd63444a 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -63,10 +63,12 @@ import mage.constants.SpellAbilityType; import mage.constants.Zone; import mage.counters.Counter; import mage.counters.Counters; +import mage.filter.Filter; import mage.filter.FilterPermanent; import mage.filter.common.FilterAttackingCreature; import mage.filter.common.FilterCreatureForCombat; import mage.filter.common.FilterCreatureForCombatBlock; +import mage.filter.common.FilterCreatureOrPlayer; import mage.filter.common.FilterPlaneswalkerPermanent; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.NamePredicate; @@ -99,6 +101,7 @@ import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInOpponentsGraveyard; import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetCreatureOrPlayer; import mage.target.common.TargetCreaturePermanentAmount; import mage.target.common.TargetPermanentOrPlayer; import mage.util.MessageToClient; @@ -742,7 +745,23 @@ public class TestPlayer implements Player { if (target.getTargetController() != null && target.getAbilityController() != null) { abilityControllerId = target.getAbilityController(); } - if ((target instanceof TargetPermanent) || (target instanceof TargetPermanentOrPlayer)) { + if (target instanceof TargetPlayer || target instanceof TargetCreatureOrPlayer) { + for (String targetDefinition : targets) { + if (targetDefinition.startsWith("targetPlayer=")) { + String playerName = targetDefinition.substring(targetDefinition.indexOf("targetPlayer=") + 13); + for (Player player : game.getPlayers().values()) { + if (player.getName().equals(playerName) + && target.canTarget(computerPlayer.getId(), player.getId(), source, game)) { + target.add(player.getId(), game); + targets.remove(targetDefinition); + return true; + } + } + } + } + + } + if ((target instanceof TargetPermanent) || (target instanceof TargetPermanentOrPlayer) || (target instanceof TargetCreatureOrPlayer)) { for (String targetDefinition : targets) { String[] targetList = targetDefinition.split("\\^"); boolean targetFound = false; @@ -759,9 +778,13 @@ public class TestPlayer implements Player { targetName = targetName.substring(0, targetName.length() - 11); } } - for (Permanent permanent : game.getBattlefield().getAllActivePermanents((FilterPermanent) target.getFilter(), game)) { + Filter filter = target.getFilter(); + if (filter instanceof FilterCreatureOrPlayer) { + filter = ((FilterCreatureOrPlayer) filter).getCreatureFilter(); + } + for (Permanent permanent : game.getBattlefield().getAllActivePermanents((FilterPermanent) filter, game)) { if (permanent.getName().equals(targetName) || (permanent.getName() + "-" + permanent.getExpansionSetCode()).equals(targetName)) { - if (((TargetPermanent) target).canTarget(abilityControllerId, permanent.getId(), source, game) && !target.getTargets().contains(permanent.getId())) { + if (target.canTarget(abilityControllerId, permanent.getId(), source, game) && !target.getTargets().contains(permanent.getId())) { if ((permanent.isCopy() && !originOnly) || (!permanent.isCopy() && !copyOnly)) { target.add(permanent.getId(), game); targetFound = true; @@ -770,6 +793,7 @@ public class TestPlayer implements Player { } } } + } if (targetFound) { targets.remove(targetDefinition); @@ -777,22 +801,7 @@ public class TestPlayer implements Player { } } } - if (target instanceof TargetPlayer) { - for (String targetDefinition : targets) { - if (targetDefinition.startsWith("targetPlayer=")) { - String playerName = targetDefinition.substring(targetDefinition.indexOf("targetPlayer=") + 13); - for (Player player : game.getPlayers().values()) { - if (player.getName().equals(playerName) - && ((TargetPlayer) target).canTarget(computerPlayer.getId(), player.getId(), source, game)) { - target.add(player.getId(), game); - targets.remove(targetDefinition); - return true; - } - } - } - } - } if (target instanceof TargetCardInHand) { for (String targetDefinition : targets) { String[] targetList = targetDefinition.split("\\^"); diff --git a/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.java index 9c39034d8b3..9911a2bc789 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/PreventAllDamageByAttachedEffect.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 mage.abilities.effects.common; import mage.abilities.Ability; @@ -39,13 +38,12 @@ import mage.game.permanent.Permanent; * * @author LevelX2 */ - public class PreventAllDamageByAttachedEffect extends PreventionEffectImpl { private final String attachedDescription; public PreventAllDamageByAttachedEffect(Duration duration, String attachedDescription, boolean onlyCombat) { - super(duration, Integer.MAX_VALUE, onlyCombat); + super(duration, Integer.MAX_VALUE, onlyCombat, false); this.attachedDescription = attachedDescription; staticText = setText(); } From d2fec6c61df5fbf76a76a6617503dbaee72bb61c Mon Sep 17 00:00:00 2001 From: benjamin Date: Wed, 24 Feb 2016 21:33:10 -0500 Subject: [PATCH 13/17] Added Eternal format (Legacy without reserve list cards). Fixed Issues 1133 and 1521 (Pauper Deck legality check). --- .../src/mage/deck/Eternal.java | 662 ++++++++++++++++++ Mage.Server/config/config.xml | 1 + Mage.Server/release/config/config.xml | 1 + .../java/mage/cards/decks/Constructed.java | 65 +- 4 files changed, 703 insertions(+), 26 deletions(-) create mode 100644 Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Eternal.java diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Eternal.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Eternal.java new file mode 100644 index 00000000000..85094dceb64 --- /dev/null +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Eternal.java @@ -0,0 +1,662 @@ +/* +* Copyright 2011 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.deck; + +import mage.cards.decks.Constructed; + +/** + * This class implements the new casual format "Eternal", which is legacy with no reserved list cards legal. + * Banlist taken from + * + * @author marthinwurer@gmail.com + */ +public class Eternal extends Constructed { + + public Eternal() { + super("Constructed - Eternal"); + + banned.add("Abeyance"); + banned.add("Aboroth"); + banned.add("Academy Rector"); + banned.add("Acid Rain"); + banned.add("Acidic Dagger"); + banned.add("Adun Oakenshield"); + banned.add("Advantageous Proclamation"); + banned.add("Aegis of the Meek"); + banned.add("Aeolipile"); + banned.add("Afiya Grove"); + banned.add("Aku Djinn"); + banned.add("Al-abara's Carpet"); + banned.add("Alchor's Tomb"); + banned.add("Ali from Cairo"); + banned.add("All Hallow's Eve"); + banned.add("Altar of Bone"); + banned.add("Aluren"); + banned.add("Amulet of Quoz"); + banned.add("Amulet of Unmaking"); + banned.add("An-Zerrin Ruins"); + banned.add("Anaba Ancestor"); + banned.add("Anaba Spirit Crafter"); + banned.add("Ancestral Knowledge"); + banned.add("Ancestral Recall"); + banned.add("Angus Mackenzie"); + banned.add("Anvil of Bogardan"); + banned.add("Apocalypse Chime"); + banned.add("Apocalypse"); + banned.add("Argivian Archaeologist"); + banned.add("Argothian Wurm"); + banned.add("Ashnod's Cylix"); + banned.add("Asmira, Holy Avenger"); + banned.add("Auspicious Ancestor"); + banned.add("Autumn Willow"); + banned.add("Avenging Angel"); + banned.add("Avizoa"); + banned.add("Aysen Crusader"); + banned.add("Aysen Highway"); + banned.add("Backup Plan"); + banned.add("Badlands"); + banned.add("Baki's Curse"); + banned.add("Balance"); + banned.add("Balduvian Hydra"); + banned.add("Balduvian Trading Post"); + banned.add("Balm of Restoration"); + banned.add("Baron Sengir"); + banned.add("Barreling Attack"); + banned.add("Barrin, Master Wizard"); + banned.add("Bartel Runeaxe"); + banned.add("Bayou"); + banned.add("Bazaar of Baghdad"); + banned.add("Bazaar of Wonders"); + banned.add("Beast Walkers"); + banned.add("Benthic Djinn"); + banned.add("Black Carriage"); + banned.add("Black Lotus"); + banned.add("Blaze of Glory"); + banned.add("Blizzard"); + banned.add("Bogardan Phoenix"); + banned.add("Bone Dancer"); + banned.add("Bone Mask"); + banned.add("Boris Devilboon"); + banned.add("Bosium Strip"); + banned.add("Brago's Favor"); + banned.add("Braingeyser"); + banned.add("Brand of Ill Omen"); + banned.add("Breathstealer's Crypt"); + banned.add("Bronze Tablet"); + banned.add("Brushwagg"); + banned.add("Bubble Matrix"); + banned.add("Cadaverous Bloom"); + banned.add("Call to Arms"); + banned.add("Candelabra of Tawnos"); + banned.add("Canopy Dragon"); + banned.add("Carnival of Souls"); + banned.add("Carrion"); + banned.add("Catacomb Dragon"); + banned.add("Caverns of Despair"); + banned.add("Chain Stasis"); + banned.add("Chains of Mephistopheles"); + banned.add("Channel"); + banned.add("Chaos Harlequin"); + banned.add("Chaos Orb"); + banned.add("Chaosphere"); + banned.add("Chromatic Armor"); + banned.add("Chronatog"); + banned.add("Circle of Despair"); + banned.add("Citanul Centaurs"); + banned.add("Citanul Druid"); + banned.add("City in a Bottle"); + banned.add("City of Shadows"); + banned.add("City of Solitude"); + banned.add("City of Traitors"); + banned.add("Cleanse"); + banned.add("Cleansing"); + banned.add("Commander Greven il-Vec"); + banned.add("Conch Horn"); + banned.add("Contract from Below"); + banned.add("Copy Artifact"); + banned.add("Corpse Dance"); + banned.add("Corrosion"); + banned.add("Covetous Dragon"); + banned.add("Crovax the Cursed"); + banned.add("Cursed Scroll"); + banned.add("Cycle of Life"); + banned.add("Cyclopean Tomb"); + banned.add("Damping Field"); + banned.add("Darkpact"); + banned.add("Daughter of Autumn"); + banned.add("Debt of Loyalty"); + banned.add("Delif's Cube"); + banned.add("Demonic Attorney"); + banned.add("Demonic Consultation"); + banned.add("Demonic Hordes"); + banned.add("Demonic Tutor"); + banned.add("Deranged Hermit"); + banned.add("Diamond Kaleidoscope"); + banned.add("Diamond Valley"); + banned.add("Didgeridoo"); + banned.add("Dig Through Time"); + banned.add("Discordant Spirit"); + banned.add("Disharmony"); + banned.add("Divine Intervention"); + banned.add("Divine Retribution"); + banned.add("Dominating Licid"); + banned.add("Donate"); + banned.add("Double Stroke"); + banned.add("Draconian Cylix"); + banned.add("Dream Halls"); + banned.add("Drop of Honey"); + banned.add("Dwarven Armorer"); + banned.add("Dwarven Pony"); + banned.add("Dwarven Sea Clan"); + banned.add("Dwarven Thaumaturgist"); + banned.add("Dystopia"); + banned.add("Earthcraft"); + banned.add("Earthlink"); + banned.add("Ebon Praetor"); + banned.add("Eladamri, Lord of Leaves"); + banned.add("Elder Spawn"); + banned.add("Elephant Graveyard"); + banned.add("Elkin Lair"); + banned.add("Elven Lyre"); + banned.add("Elvish Farmer"); + banned.add("Emberwilde Caliph"); + banned.add("Emberwilde Djinn"); + banned.add("Energy Bolt"); + banned.add("Energy Storm"); + banned.add("Energy Vortex"); + banned.add("Equipoise"); + banned.add("Ertai's Familiar"); + banned.add("Ertai, Wizard Adept"); + banned.add("Escaped Shapeshifter"); + banned.add("Eternal Flame"); + banned.add("Eureka"); + banned.add("Exalted Dragon"); + banned.add("Exorcist"); + banned.add("Eye of Singularity"); + banned.add("Faerie Noble"); + banned.add("Falling Star"); + banned.add("Farmstead"); + banned.add("Fastbond"); + banned.add("Fatal Lore"); + banned.add("Femeref Enchantress"); + banned.add("Field of Dreams"); + banned.add("Firestorm Hellkite"); + banned.add("Firestorm Phoenix"); + banned.add("Firestorm"); + banned.add("Flash"); + banned.add("Flooded Shoreline"); + banned.add("Floodwater Dam"); + banned.add("Flow of Maggots"); + banned.add("Forbidden Ritual"); + banned.add("Forcefield"); + banned.add("Forethought Amulet"); + banned.add("Fork"); + banned.add("Formation"); + banned.add("Forsaken Wastes"); + banned.add("Frankenstein's Monster"); + banned.add("Frantic Search"); + banned.add("Frenetic Efreet"); + banned.add("Fungal Bloom"); + banned.add("Fungus Elemental"); + banned.add("Fyndhorn Pollen"); + banned.add("Gaea's Avenger"); + banned.add("Gaea's Cradle"); + banned.add("Gallowbraid"); + banned.add("Gargantuan Gorilla"); + banned.add("Gate to Phyrexia"); + banned.add("Gauntlet of Might"); + banned.add("General Jarkeld"); + banned.add("Gilded Drake"); + banned.add("Glacial Crevasses"); + banned.add("Goblin Bomb"); + banned.add("Goblin Flotilla"); + banned.add("Goblin Recruiter"); + banned.add("Goblin Wizard"); + banned.add("Golgothian Sylex"); + banned.add("Gosta Dirk"); + banned.add("Grandmother Sengir"); + banned.add("Granite Gargoyle"); + banned.add("Grave Robbers"); + banned.add("Gravebind"); + banned.add("Gravity Sphere"); + banned.add("Great Whale"); + banned.add("Griffin Canyon"); + banned.add("Grim Feast"); + banned.add("Grim Monolith"); + banned.add("Guardian Beast"); + banned.add("Guiding Spirit"); + banned.add("Gush"); + banned.add("Gustha's Scepter"); + banned.add("Gwendlyn Di Corci"); + banned.add("Hakim, Loreweaver"); + banned.add("Halfdane"); + banned.add("Hall of Gemstone"); + banned.add("Halls of Mist"); + banned.add("Hand of Justice"); + banned.add("Harbinger of Night"); + banned.add("Hatred"); + banned.add("Haunting Wind"); + banned.add("Hazduhr the Abbot"); + banned.add("Hazezon Tamar"); + banned.add("Heart Wolf"); + banned.add("Heart of Bogardan"); + banned.add("Heart of Yavimaya"); + banned.add("Heat Stroke"); + banned.add("Hellfire"); + banned.add("Helm of Obedience"); + banned.add("Herald of Serra"); + banned.add("Hermit Druid"); + banned.add("Hidden Path"); + banned.add("Hivis of the Scale"); + banned.add("Homarid Shaman"); + banned.add("Hot Springs"); + banned.add("Humility"); + banned.add("Icatian Lieutenant"); + banned.add("Icatian Skirmishers"); + banned.add("Ice Cauldron"); + banned.add("Ifh-Biff Efreet"); + banned.add("Illusionary Mask"); + banned.add("Illusionary Presence"); + banned.add("Illusions of Grandeur"); + banned.add("Immediate Action"); + banned.add("Imperial Seal"); + banned.add("Implements of Sacrifice"); + banned.add("Imprison"); + banned.add("In the Eye of Chaos"); + banned.add("Infernal Denizen"); + banned.add("Infernal Tribute"); + banned.add("Infinite Authority"); + banned.add("Inner Sanctum"); + banned.add("Intuition"); + banned.add("Invoke Prejudice"); + banned.add("Island of Wak-Wak"); + banned.add("Iterative Analysis"); + banned.add("Ivory Gargoyle"); + banned.add("Jabari's Influence"); + banned.add("Jacques le Vert"); + banned.add("Jester's Mask"); + banned.add("Jeweled Bird"); + banned.add("Jihad"); + banned.add("Jovial Evil"); + banned.add("Jungle Patrol"); + banned.add("Juzam Djinn"); + banned.add("Kaervek's Spite"); + banned.add("Karn, Silver Golem"); + banned.add("Katabatic Winds"); + banned.add("Kaysa"); + banned.add("Keeper of Tresserhorn"); + banned.add("Khabal Ghoul"); + banned.add("King Suleiman"); + banned.add("Kjeldoran Knight"); + banned.add("Kjeldoran Outpost"); + banned.add("Kjeldoran Phalanx"); + banned.add("Knights of Thorn"); + banned.add("Knowledge Vault"); + banned.add("Kobold Overlord"); + banned.add("Kookus"); + banned.add("Koskun Falls"); + banned.add("Krovikan Horror"); + banned.add("Kudzu"); + banned.add("Kukemssa Pirates"); + banned.add("Lady Caleria"); + banned.add("Lady Evangela"); + banned.add("Lake of the Dead"); + banned.add("Land Cap"); + banned.add("Land Equilibrium"); + banned.add("Lava Tubes"); + banned.add("Leeches"); + banned.add("Leering Gargoyle"); + banned.add("Library of Alexandria"); + banned.add("Lich"); + banned.add("Lichenthrope"); + banned.add("Liege of the Hollows"); + banned.add("Life Matrix"); + banned.add("Lifeblood"); + banned.add("Lifeline"); + banned.add("Lightning Blow"); + banned.add("Lightning Cloud"); + banned.add("Lightning Dragon"); + banned.add("Lion's Eye Diamond"); + banned.add("Living Plane"); + banned.add("Livonya Silone"); + banned.add("Lodestone Bauble"); + banned.add("Lord of Tresserhorn"); + banned.add("Lotus Vale"); + banned.add("Lure of Prey"); + banned.add("Lurker"); + banned.add("Malignant Growth"); + banned.add("Mammoth Harness"); + banned.add("Mana Crypt"); + banned.add("Mana Drain"); + banned.add("Mana Matrix"); + banned.add("Mana Vault"); + banned.add("Mana Vortex"); + banned.add("Mana Web"); + banned.add("Mangara's Tome"); + banned.add("Maraxus of Keld"); + banned.add("Marjhan"); + banned.add("Marton Stromgald"); + banned.add("Martyr's Cry"); + banned.add("Martyrs of Korlis"); + banned.add("Master of the Hunt"); + banned.add("Masticore"); + banned.add("Meditate"); + banned.add("Memory Jar"); + banned.add("Mental Misstep"); + banned.add("Mercenaries"); + banned.add("Merchant Ship"); + banned.add("Mesmeric Trance"); + banned.add("Metalworker"); + banned.add("Mightstone"); + banned.add("Mind Over Matter"); + banned.add("Mind Twist"); + banned.add("Mind's Desire"); + banned.add("Mindbender Spores"); + banned.add("Minion of Tevesh Szat"); + banned.add("Mirror Universe"); + banned.add("Misers' Cage"); + banned.add("Misfortune"); + banned.add("Mishra's Workshop"); + banned.add("Mist Dragon"); + banned.add("Moat"); + banned.add("Mold Demon"); + banned.add("Morinfen"); + banned.add("Morphling"); + banned.add("Mountain Titan"); + banned.add("Mox Diamond"); + banned.add("Mox Emerald"); + banned.add("Mox Jet"); + banned.add("Mox Pearl"); + banned.add("Mox Ruby"); + banned.add("Mox Sapphire"); + banned.add("Mudslide"); + banned.add("Multani, Maro-Sorcerer"); + banned.add("Musician"); + banned.add("Muzzio's Preparations"); + banned.add("Mwonvuli Ooze"); + banned.add("Mystic Decree"); + banned.add("Mystic Might"); + banned.add("Mystical Tutor"); + banned.add("Nameless Race"); + banned.add("Narwhal"); + banned.add("Natural Balance"); + banned.add("Natural Selection"); + banned.add("Nature's Wrath"); + banned.add("Necropotence"); + banned.add("Nether Void"); + banned.add("Niall Silvain"); + banned.add("North Star"); + banned.add("Nova Pentacle"); + banned.add("Null Chamber"); + banned.add("Null Rod"); + banned.add("Oath of Druids"); + banned.add("Oath of Ghouls"); + banned.add("Ogre Enforcer"); + banned.add("Old Man of the Sea"); + banned.add("Omen of Fire"); + banned.add("Opal Archangel"); + banned.add("Opalescence"); + banned.add("Orim, Samite Healer"); + banned.add("Palinchron"); + banned.add("Paradigm Shift"); + banned.add("Paupers' Cage"); + banned.add("Peacekeeper"); + banned.add("Pendrell Mists"); + banned.add("Phantasmal Sphere"); + banned.add("Phelddagrif"); + banned.add("Phyrexian Devourer"); + banned.add("Phyrexian Dreadnought"); + banned.add("Phyrexian Marauder"); + banned.add("Phyrexian Negator"); + banned.add("Phyrexian Portal"); + banned.add("Phyrexian Purge"); + banned.add("Phyrexian Tribute"); + banned.add("Pillar Tombs of Aku"); + banned.add("Pixie Queen"); + banned.add("Planar Gate"); + banned.add("Plateau (Brudi)"); + banned.add("Plateau (Tucker)"); + banned.add("Polar Kraken"); + banned.add("Political Trickery"); + banned.add("Powder Keg"); + banned.add("Power Artifact"); + banned.add("Power Play"); + banned.add("Powerleech"); + banned.add("Preacher"); + banned.add("Preferred Selection"); + banned.add("Prismatic Lace"); + banned.add("Psychic Allergy"); + banned.add("Psychic Vortex"); + banned.add("Purgatory"); + banned.add("Purraj of Urborg"); + banned.add("Pygmy Hippo"); + banned.add("Pyramids"); + banned.add("Quarum Trench Gnomes"); + banned.add("Quirion Druid"); + banned.add("Radiant, Archangel"); + banned.add("Raging River"); + banned.add("Ragnar"); + banned.add("Rainbow Efreet"); + banned.add("Rainbow Vale"); + banned.add("Ramses Overdark"); + banned.add("Rapid Fire"); + banned.add("Rashida Scalebane"); + banned.add("Rasputin Dreamweaver"); + banned.add("Razor Pendulum"); + banned.add("Reality Twist"); + banned.add("Rebirth"); + banned.add("Recurring Nightmare"); + banned.add("Recycle"); + banned.add("Reflect Damage"); + banned.add("Reparations"); + banned.add("Replenish"); + banned.add("Retribution of the Meek"); + banned.add("Reveka, Wizard Savant"); + banned.add("Reverberation"); + banned.add("Righteous War"); + banned.add("Ring of Gix"); + banned.add("Ring of Immortals"); + banned.add("Ring of Ma'ruf"); + banned.add("Ring of Renewal"); + banned.add("Ritual of Subdual"); + banned.add("Ritual of the Machine"); + banned.add("River Delta"); + banned.add("River Merfolk"); + banned.add("Roc of Kher Ridges"); + banned.add("Rock Basilisk"); + banned.add("Rock Hydra"); + banned.add("Rofellos, Llanowar Emissary"); + banned.add("Rogue Skycaptain"); + banned.add("Rohgahh of Kher Keep"); + banned.add("Royal Decree"); + banned.add("Rysorian Badger"); + banned.add("Sandals of Abdallah"); + banned.add("Sands of Time"); + banned.add("Sarcomancy"); + banned.add("Savannah"); + banned.add("Sawback Manticore"); + banned.add("Scarwood Bandits"); + banned.add("Scorched Ruins"); + banned.add("Scrubland"); + banned.add("Season of the Witch"); + banned.add("Second Chance"); + banned.add("Secret Summoning"); + banned.add("Secrets of Paradise"); + banned.add("Sedge Troll"); + banned.add("Seeds of Innocence"); + banned.add("Selenia, Dark Angel"); + banned.add("Sentinel Dispatch"); + banned.add("Serendib Djinn"); + banned.add("Serra Aviary"); + banned.add("Serra's Sanctum"); + banned.add("Shahrazad"); + banned.add("Shallow Grave"); + banned.add("Shauku, Endbringer"); + banned.add("Sheltered Valley"); + banned.add("Shimmer"); + banned.add("Sidar Jabari"); + banned.add("Silver Wyvern"); + banned.add("Singing Tree"); + banned.add("Skeleton Ship"); + banned.add("Skullclamp"); + banned.add("Sliver Queen"); + banned.add("Snowblind"); + banned.add("Sol Ring"); + banned.add("Soldevi Digger"); + banned.add("Soldevi Excavations"); + banned.add("Soldevi Golem"); + banned.add("Soraya the Falconer"); + banned.add("Sorrow's Path"); + banned.add("Soul Echo"); + banned.add("Spectral Guardian"); + banned.add("Spinal Villain"); + banned.add("Spirit Shield"); + banned.add("Spirit of the Night"); + banned.add("Spiritual Sanctuary"); + banned.add("Splintering Wind"); + banned.add("Spoils of Evil"); + banned.add("Spoils of War"); + banned.add("Squandered Resources"); + banned.add("Stone Calendar"); + banned.add("Storm Spirit"); + banned.add("Storm World"); + banned.add("Strip Mine"); + banned.add("Su-Chi"); + banned.add("Subterranean Spirit"); + banned.add("Suleiman's Legacy"); + banned.add("Survival of the Fittest"); + banned.add("Sustaining Spirit"); + banned.add("Sword of the Ages"); + banned.add("Sworn Defender"); + banned.add("Taiga"); + banned.add("Tainted Specter"); + banned.add("Taniwha"); + banned.add("Tawnos's Coffin"); + banned.add("Teeka's Dragon"); + banned.add("Teferi's Imp"); + banned.add("Teferi's Isle"); + banned.add("Teferi's Realm"); + banned.add("Telekinesis"); + banned.add("Telim'Tor"); + banned.add("Telim'Tor's Edict"); + banned.add("Tempest Efreet"); + banned.add("Temporal Aperture"); + banned.add("Tetsuo Umezawa"); + banned.add("Thawing Glaciers"); + banned.add("The Abyss"); + banned.add("The Tabernacle at Pendrell Vale"); + banned.add("Thelon's Curse"); + banned.add("Thelonite Monk"); + banned.add("Thought Lash"); + banned.add("Thran Tome"); + banned.add("Three Wishes"); + banned.add("Thrull Champion"); + banned.add("Thunder Spirit"); + banned.add("Tidal Control"); + banned.add("Timberline Ridge"); + banned.add("Time Spiral"); + banned.add("Time Vault"); + banned.add("Time Walk"); + banned.add("Timetwister"); + banned.add("Timetwister"); + banned.add("Timmerian Fiends"); + banned.add("Tinker"); + banned.add("Tithe"); + banned.add("Tolarian Academy"); + banned.add("Tolarian Entrancer"); + banned.add("Tolarian Serpent"); + banned.add("Tombstone Stairwell"); + banned.add("Tornado"); + banned.add("Torrent of Lava"); + banned.add("Tourach's Gate"); + banned.add("Tracker"); + banned.add("Trailblazer"); + banned.add("Transmute Artifact"); + banned.add("Treachery"); + banned.add("Treasure Cruise"); + banned.add("Triangle of War"); + banned.add("Tropical Island"); + banned.add("Tuknir Deathlock"); + banned.add("Tundra"); + banned.add("Two-Headed Giant of Foriys"); + banned.add("Typhoon"); + banned.add("Underground Sea"); + banned.add("Undiscovered Paradise"); + banned.add("Unexpected Potential"); + banned.add("Unfulfilled Desires"); + banned.add("Ur-Drago"); + banned.add("Urborg Justice"); + banned.add("Urborg Stalker"); + banned.add("Urza's Miter"); + banned.add("Vampiric Tutor"); + banned.add("Varchild's War-Riders"); + banned.add("Veldrane of Sengir"); + banned.add("Veldt"); + banned.add("Ventifact Bottle"); + banned.add("Vesuvan Doppelganger"); + banned.add("Veteran Bodyguard"); + banned.add("Viashivan Dragon"); + banned.add("Vodalian Knights"); + banned.add("Vodalian War Machine"); + banned.add("Volcanic Island"); + banned.add("Volrath's Shapeshifter"); + banned.add("Volrath's Stronghold"); + banned.add("Wall of Kelp"); + banned.add("Wandering Mage"); + banned.add("Warping Wurm"); + banned.add("Wave of Terror"); + banned.add("Weakstone"); + banned.add("Weatherseed Treefolk"); + banned.add("Well of Knowledge"); + banned.add("Wellspring"); + banned.add("Wheel of Fortune"); + banned.add("Willow Priestess"); + banned.add("Willow Satyr"); + banned.add("Windfall"); + banned.add("Winding Canyons"); + banned.add("Winter Sky"); + banned.add("Winter's Chill"); + banned.add("Winter's Night"); + banned.add("Wood Elemental"); + banned.add("Word of Command"); + banned.add("Worldknit"); + banned.add("Worms of the Earth"); + banned.add("Wormwood Treefolk"); + banned.add("Xanthic Statue"); + banned.add("Yare"); + banned.add("Yavimaya Hollow"); + banned.add("Yawgmoth's Bargain"); + banned.add("Yawgmoth's Will"); + banned.add("Zelyon Sword"); + banned.add("Zephid"); + banned.add("Zhalfirin Crusader"); + banned.add("Zirilan of the Claw"); + banned.add("Zuberi, Golden Feather"); + } +} diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 21e2db8e3fe..6aadb3d2ad9 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -110,6 +110,7 @@ + diff --git a/Mage.Server/release/config/config.xml b/Mage.Server/release/config/config.xml index 123ba8599f0..9b9598c07b4 100644 --- a/Mage.Server/release/config/config.xml +++ b/Mage.Server/release/config/config.xml @@ -107,6 +107,7 @@ + diff --git a/Mage/src/main/java/mage/cards/decks/Constructed.java b/Mage/src/main/java/mage/cards/decks/Constructed.java index c8c385e76d7..1c68d651c25 100644 --- a/Mage/src/main/java/mage/cards/decks/Constructed.java +++ b/Mage/src/main/java/mage/cards/decks/Constructed.java @@ -108,14 +108,16 @@ public class Constructed extends DeckValidator { if (!rarities.isEmpty()) { for (Card card : deck.getCards()) { if (!rarities.contains(card.getRarity())) { - invalid.put(card.getName(), "Invalid rarity: " + card.getRarity()); - valid = false; + if( !legalRarity(card) ){ + valid = false; + } } } for (Card card : deck.getSideboard()) { if (!rarities.contains(card.getRarity())) { - invalid.put(card.getName(), "Invalid rarity: " + card.getRarity()); - valid = false; + if( !legalRarity(card) ){ + valid = false; + } } } } @@ -123,34 +125,14 @@ public class Constructed extends DeckValidator { if (!setCodes.isEmpty()) { for (Card card : deck.getCards()) { if (!setCodes.contains(card.getExpansionSetCode())) { - // check if card is legal if taken from other set - boolean legal = false; - List cardInfos = CardRepository.instance.findCards(card.getName()); - for (CardInfo cardInfo : cardInfos) { - if (setCodes.contains(cardInfo.getSetCode())) { - legal = true; - break; - } - } - if (!legal && !invalid.containsKey(card.getName())) { - invalid.put(card.getName(), "Invalid set: " + card.getExpansionSetCode()); + if( !legalSets(card) ){ valid = false; } } } for (Card card : deck.getSideboard()) { if (!setCodes.contains(card.getExpansionSetCode())) { - // check if card is legal if taken from other set - boolean legal = false; - List cardInfos = CardRepository.instance.findCards(card.getName()); - for (CardInfo cardInfo : cardInfos) { - if (setCodes.contains(cardInfo.getSetCode())) { - legal = true; - break; - } - } - if (!legal && !invalid.containsKey(card.getName())) { - invalid.put(card.getName(), "Invalid set: " + card.getExpansionSetCode()); + if( !legalSets(card) ){ valid = false; } } @@ -159,5 +141,36 @@ public class Constructed extends DeckValidator { logger.debug("DECK validate end: " + name + " deckname: " + deck.getName() + " invalids:" + invalid.size()); return valid; } + + protected boolean legalRarity(Card card){ + // check if card is legal if taken from other set + boolean legal = false; + List cardInfos = CardRepository.instance.findCards(card.getName()); + for (CardInfo cardInfo : cardInfos) { + if (rarities.contains(cardInfo.getRarity())) { + legal = true; + break; + } + } + if (!legal && !invalid.containsKey(card.getName())) { + invalid.put(card.getName(), "Invalid rarity: " + card.getRarity()); + } + return legal; + } + protected boolean legalSets(Card card) { + // check if card is legal if taken from other set + boolean legal = false; + List cardInfos = CardRepository.instance.findCards(card.getName()); + for (CardInfo cardInfo : cardInfos) { + if (setCodes.contains(cardInfo.getSetCode())) { + legal = true; + break; + } + } + if (!legal && !invalid.containsKey(card.getName())) { + invalid.put(card.getName(), "Invalid set: " + card.getExpansionSetCode()); + } + return legal; + } } From f607f140b72de1b5baad22d6232cb4784f4db0fb Mon Sep 17 00:00:00 2001 From: DjB Date: Wed, 24 Feb 2016 21:13:24 -0600 Subject: [PATCH 14/17] Create DreadSpecter.java --- .../src/mage/sets/mirage/DreadSpecter.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/mirage/DreadSpecter.java diff --git a/Mage.Sets/src/mage/sets/mirage/DreadSpecter.java b/Mage.Sets/src/mage/sets/mirage/DreadSpecter.java new file mode 100644 index 00000000000..b9220585be3 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mirage/DreadSpecter.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.mirage; + +import java.util.UUID; +import mage.MageInt; +import mage.ObjectColor; +import mage.abilities.common.BlocksOrBecomesBlockedByCreatureTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +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; + +/** + * + * @author djbrez + */ +public class DreadSpecter extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature"); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK))); + } + + public DreadSpecter(UUID ownerId) { + super(ownerId, 17, "Dread Specter", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}"); + this.expansionSetCode = "MIR"; + this.subtype.add("Specter"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Dread Specter blocks or becomes blocked by a nonblack creature, destroy that creature at end of combat. + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()), true); + effect.setText("destroy that creature at end of combat"); + this.addAbility(new BlocksOrBecomesBlockedByCreatureTriggeredAbility(effect, filter, false)); + } + + public DreadSpecter(final DreadSpecter card) { + super(card); + } + + @Override + public DreadSpecter copy() { + return new DreadSpecter(this); + } +} From 59933f0842803a4c2f1764b8a27c91d8f850e848 Mon Sep 17 00:00:00 2001 From: benjamin Date: Wed, 24 Feb 2016 22:24:51 -0500 Subject: [PATCH 15/17] Added documentation to two new functions in Constructed.java --- Mage/src/main/java/mage/cards/decks/Constructed.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Mage/src/main/java/mage/cards/decks/Constructed.java b/Mage/src/main/java/mage/cards/decks/Constructed.java index 1c68d651c25..85cb94b9afa 100644 --- a/Mage/src/main/java/mage/cards/decks/Constructed.java +++ b/Mage/src/main/java/mage/cards/decks/Constructed.java @@ -142,6 +142,11 @@ public class Constructed extends DeckValidator { return valid; } + /** + * Checks if the given card is legal in any of the given rarities + * @param card - the card to check + * @return Whether the card was printed at any of the given rarities. + */ protected boolean legalRarity(Card card){ // check if card is legal if taken from other set boolean legal = false; @@ -158,6 +163,11 @@ public class Constructed extends DeckValidator { return legal; } + /** + * Checks if the given card is legal in any of the given sets + * @param card - the card to check + * @return Whether the card was printed in any of this format's sets. + */ protected boolean legalSets(Card card) { // check if card is legal if taken from other set boolean legal = false; From 830b86543d866097e94373f197f6c3ded19ab70a Mon Sep 17 00:00:00 2001 From: DjB Date: Wed, 24 Feb 2016 23:13:07 -0600 Subject: [PATCH 16/17] Create BlockadeRunner.java --- .../sets/mercadianmasques/BlockadeRunner.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Mage.Sets/src/mage/sets/mercadianmasques/BlockadeRunner.java diff --git a/Mage.Sets/src/mage/sets/mercadianmasques/BlockadeRunner.java b/Mage.Sets/src/mage/sets/mercadianmasques/BlockadeRunner.java new file mode 100644 index 00000000000..404dcdcea85 --- /dev/null +++ b/Mage.Sets/src/mage/sets/mercadianmasques/BlockadeRunner.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.mercadianmasques; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Rarity; +import mage.constants.Zone; + +/** + * + * @author djbrez + */ +public class BlockadeRunner extends CardImpl { + + public BlockadeRunner(UUID ownerId) { + super(ownerId, 60, "Blockade Runner", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{U}"); + this.expansionSetCode = "MMQ"; + this.subtype.add("Merfolk"); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {U}: Blockade Runner is unblockable this turn. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, + new CantBeBlockedSourceEffect(Duration.EndOfTurn), + new ManaCostsImpl("{U}"))); + } + + public BlockadeRunner(final BlockadeRunner card) { + super(card); + } + + @Override + public BlockadeRunner copy() { + return new BlockadeRunner(this); + } +} From 140672b8b3988d2e1379ff00cac143834ac16416 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Thu, 25 Feb 2016 11:35:59 +0100 Subject: [PATCH 17/17] * Curse of the Forsaken - Changed outcome (fixes #1557). --- .../src/mage/sets/commander2013/CurseOfTheForsaken.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Mage.Sets/src/mage/sets/commander2013/CurseOfTheForsaken.java b/Mage.Sets/src/mage/sets/commander2013/CurseOfTheForsaken.java index 8011fafb75c..4d1b0660872 100644 --- a/Mage.Sets/src/mage/sets/commander2013/CurseOfTheForsaken.java +++ b/Mage.Sets/src/mage/sets/commander2013/CurseOfTheForsaken.java @@ -58,11 +58,10 @@ public class CurseOfTheForsaken extends CardImpl { this.subtype.add("Aura"); this.subtype.add("Curse"); - // Enchant player TargetPlayer auraTarget = new TargetPlayer(); this.getSpellAbility().addTarget(auraTarget); - this.getSpellAbility().addEffect(new AttachEffect(Outcome.GainLife)); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); this.addAbility(new EnchantAbility(auraTarget.getTargetName())); // Whenever a creature attacks enchanted player, its controller gains 1 life. @@ -112,7 +111,7 @@ class CurseOfTheForsakenTriggeredAbility extends TriggeredAbilityImpl { if (enchantment != null && enchantment.getAttachedTo() != null && enchantment.getAttachedTo().equals(defender.getId())) { - for (Effect effect: this.getEffects()) { + for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(event.getPlayerId())); } return true;