diff --git a/.gitignore b/.gitignore index 6c4a3781368..d084fe143d0 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,4 @@ Mage.Client/serverlist.txt client_secrets.json dependency-reduced-pom.xml +mage-bundle diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties index 9ea86aa6e9b..8603daf3264 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target/maven-archiver/pom.properties @@ -1,5 +1,5 @@ #Generated by Maven -#Fri Sep 15 22:14:29 CEST 2017 +#Sun Oct 22 00:34:49 EDT 2017 version=1.4.26 groupId=org.mage artifactId=mage-game-pennydreadfulcommanderfreeforall diff --git a/Mage.Sets/src/mage/cards/d/DeadIronSledge.java b/Mage.Sets/src/mage/cards/d/DeadIronSledge.java new file mode 100644 index 00000000000..11b27920136 --- /dev/null +++ b/Mage.Sets/src/mage/cards/d/DeadIronSledge.java @@ -0,0 +1,202 @@ +/* + * 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.cards.d; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbility; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.BlocksAttachedTriggeredAbility; +import mage.abilities.common.BlocksOrBecomesBlockedTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.effects.common.DestroySourceEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; +import mage.abilities.keyword.EquipAbility; +import mage.abilities.keyword.FirstStrikeAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.permanent.BlockedByIdPredicate; +import mage.filter.predicate.permanent.BlockingAttackerIdPredicate; +import mage.filter.predicate.permanent.PermanentIdPredicate; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FirstTargetPointer; +import mage.target.targetpointer.FixedTarget; +import mage.target.targetpointer.FixedTargets; +import mage.util.CardUtil; + +/** + * + * @author jerekwilson + */ +public class DeadIronSledge extends CardImpl { + + public DeadIronSledge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + this.subtype.add(SubType.EQUIPMENT); + + // Whenever equipped creature blocks or becomes blocked by a creature, destroy both creatures. + this.addAbility(new DeadIronSledgeTriggeredAbility()); + + + // Equip {2} + this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); + } + + public DeadIronSledge(final DeadIronSledge card) { + super(card); + } + + @Override + public DeadIronSledge copy() { + return new DeadIronSledge(this); + } + +} +class DeadIronSledgeTriggeredAbility extends TriggeredAbilityImpl { + + private Set possibleTargets = new HashSet<>(); + + DeadIronSledgeTriggeredAbility() { + super(Zone.BATTLEFIELD, new DeadIronSledgeDestroyEffect(), false); + } + + DeadIronSledgeTriggeredAbility(final DeadIronSledgeTriggeredAbility ability) { + super(ability); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DECLARED_BLOCKERS; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + List targetPermanents = new ArrayList<>(); + Permanent equipment = game.getPermanentOrLKIBattlefield((this.getSourceId())); + if (equipment != null && equipment.getAttachedTo() != null) { + Permanent equippedPermanent = game.getPermanentOrLKIBattlefield((equipment.getAttachedTo())); + if (equippedPermanent != null) { + possibleTargets.clear(); + if(equippedPermanent.isBlocked(game)){ + possibleTargets.add(equippedPermanent.getId()); //add equipped creature to target list + } + String targetName = ""; + if (equippedPermanent.isAttacking()) { + for (CombatGroup group : game.getCombat().getGroups()) { + if (group.getAttackers().contains(equippedPermanent.getId())) { + possibleTargets.addAll(group.getBlockers()); + } + } + targetName = "a creature blocking attacker "; + } else if (equippedPermanent.getBlocking() > 0) { + for (CombatGroup group : game.getCombat().getGroups()) { + if (group.getBlockers().contains(equippedPermanent.getId())) { + possibleTargets.addAll(group.getAttackers()); + } + } + targetName = "a creature blocked by creature "; + } + if (!possibleTargets.isEmpty()) { + this.getTargets().clear(); + + for (UUID creatureId : possibleTargets) { + Permanent target = game.getPermanentOrLKIBattlefield(creatureId); + targetPermanents.add(target); + } + + this.getEffects().get(0).setTargetPointer(new FixedTargets(targetPermanents,game)); + + return true; + } + } + } + return false; + } + + @Override + public TriggeredAbility copy() { + return new DeadIronSledgeTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever equipped creature blocks or becomes blocked by a creature, destroy both creatures."; + } +} + +class DeadIronSledgeDestroyEffect extends OneShotEffect { + + public DeadIronSledgeDestroyEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "destroy both creatures"; + } + + public DeadIronSledgeDestroyEffect(final DeadIronSledgeDestroyEffect effect) { + super(effect); + } + + @Override + public DeadIronSledgeDestroyEffect copy() { + return new DeadIronSledgeDestroyEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + + List targets = this.getTargetPointer().getTargets(game, source); + for(UUID target: targets){ + Permanent permanent = game.getPermanentOrLKIBattlefield(target); + permanent.destroy(target, game, false); + } + return true; + } +} diff --git a/Mage.Sets/src/mage/cards/i/IceFloe.java b/Mage.Sets/src/mage/cards/i/IceFloe.java index 974b442ac5a..5daccfa4d85 100644 --- a/Mage.Sets/src/mage/cards/i/IceFloe.java +++ b/Mage.Sets/src/mage/cards/i/IceFloe.java @@ -47,6 +47,7 @@ import mage.target.common.TargetCreaturePermanent; /** * + * @author TheElk801 */ public class IceFloe extends CardImpl { diff --git a/Mage.Sets/src/mage/cards/j/JaggedPoppet.java b/Mage.Sets/src/mage/cards/j/JaggedPoppet.java new file mode 100644 index 00000000000..e8627cd335f --- /dev/null +++ b/Mage.Sets/src/mage/cards/j/JaggedPoppet.java @@ -0,0 +1,162 @@ +/* + * 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.cards.j; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.common.DealtDamageToSourceTriggeredAbility; +import mage.abilities.condition.common.HellbentCondition; +import mage.abilities.decorator.ConditionalTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardControllerEffect; +import mage.constants.SubType; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.AbilityWord; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; + +/** + * + * @author jerekwilson + */ +public class JaggedPoppet extends CardImpl { + + public JaggedPoppet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}"); + + this.subtype.add(SubType.OGRE); + this.subtype.add(SubType.WARRIOR); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Whenever Jagged Poppet is dealt damage, discard that many cards. + Ability dealtDamageAbility = new DealtDamageToSourceTriggeredAbility(Zone.BATTLEFIELD, new JaggedPoppetDealtDamageEffect(), false, false, true); + this.addAbility(dealtDamageAbility); + + // Hellbent - Whenever Jagged Poppet deals combat damage to a player, if you have no cards in hand, that player discards cards equal to the damage. + Ability hellbentAbility = new ConditionalTriggeredAbility( + new DealsCombatDamageToAPlayerTriggeredAbility(new JaggedPoppetDealsDamageEffect(), false,true), + HellbentCondition.instance, + "Hellbent - Whenever {this} deals combat damage to a player, if you have no cards in hand, that player discards cards equal to the damage."); + + hellbentAbility.setAbilityWord(AbilityWord.HELLBENT); + this.addAbility(hellbentAbility); + + + + + } + + public JaggedPoppet(final JaggedPoppet card) { + super(card); + } + + @Override + public JaggedPoppet copy() { + return new JaggedPoppet(this); + } +} + + +class JaggedPoppetDealsDamageEffect extends OneShotEffect { + + public JaggedPoppetDealsDamageEffect() { + super(Outcome.Discard); + //staticText = "it deals that much damage to each creature that player controls"; + } + + public JaggedPoppetDealsDamageEffect(final JaggedPoppetDealsDamageEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + //According to the Balefire Dragon code, This statement gets the player that was dealt the combat damage + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + if (player != null) { + //Call the getValue method of the Effect class to retrieve the amount of damage + int amount = (Integer) getValue("damage"); + + if(amount > 0){ + //Call the player discard function discarding cards equal to damage + player.discard(amount, false, source, game); + } + return true; + } + return false; + } + + @Override + public JaggedPoppetDealsDamageEffect copy() { + return new JaggedPoppetDealsDamageEffect(this); + } +} + + +class JaggedPoppetDealtDamageEffect extends OneShotEffect { + + public JaggedPoppetDealtDamageEffect() { + super(Outcome.Discard); + staticText = "discard that many cards"; + } + + public JaggedPoppetDealtDamageEffect(final JaggedPoppetDealtDamageEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + + //According to the Firedrinker Satyr code, This statement gets the player that controls Jagged Poppet + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + //Call the getValue method of the Effect class to retrieve the amount of damage + int amount = (Integer) getValue("damage"); + + if(amount > 0){ + //Call the player discard function discarding cards equal to damage + player.discard(amount, false, source, game); + } + return true; + } + return false; + + } + + @Override + public JaggedPoppetDealtDamageEffect copy() { + return new JaggedPoppetDealtDamageEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/r/RhysticCave.java b/Mage.Sets/src/mage/cards/r/RhysticCave.java new file mode 100644 index 00000000000..88362d5905c --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/RhysticCave.java @@ -0,0 +1,149 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.r; + +import java.util.UUID; +import mage.MageObject; +import mage.Mana; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.ChooseColorEffect; +import mage.abilities.effects.common.DoUnlessAnyPlayerPaysEffect; +import mage.abilities.effects.common.ManaEffect; +import mage.abilities.effects.common.continuous.BoostSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.choices.ChoiceColor; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +/** + * + * @author jerekwilson + */ +public class RhysticCave extends CardImpl { + + public RhysticCave(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + // {tap}: Choose a color. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, + new ChooseColorEffect(Outcome.PutManaInPool), + new TapSourceCost()); + + // Add one mana of that color to your mana pool unless any player pays {1}. Activate this ability only any time you could cast an instant. + ability.addEffect(new DoUnlessAnyPlayerPaysEffect(new RhysticCaveManaEffect(),new GenericManaCost(1))); + + this.addAbility(ability); + + } + + public RhysticCave(final RhysticCave card) { + super(card); + } + + @Override + public RhysticCave copy() { + return new RhysticCave(this); + } + + + class RhysticCaveManaEffect extends ManaEffect { + + private final Mana chosenMana; + + public RhysticCaveManaEffect() { + super(); + chosenMana = new Mana(); + this.staticText = "Add one mana of that color to your mana pool "; + } + + public RhysticCaveManaEffect(final RhysticCaveManaEffect effect) { + super(effect); + this.chosenMana = effect.chosenMana.copy(); + } + + @Override + public Mana getMana(Game game, Ability source) { + return null; + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getPermanentOrLKIBattlefield(source.getSourceId()); //get obj reference to Rhystic Cave + if (controller != null) { + if (mageObject != null) { + ObjectColor choice = (ObjectColor) game.getState().getValue(mageObject.getId()+"_color"); + if (choice!= null) { + String color = choice.toString(); + switch (color) { + case "R": + chosenMana.setRed(1); + break; + case "U": + chosenMana.setBlue(1); + break; + case "W": + chosenMana.setWhite(1); + break; + case "B": + chosenMana.setBlack(1); + break; + case "G": + chosenMana.setGreen(1); + break; + } + } + checkToFirePossibleEvents(chosenMana, game, source); + controller.getManaPool().addMana(chosenMana, game, source); + return true; + } + + } + + return false; + } + + @Override + public Effect copy() { + return new RhysticCaveManaEffect(this); + } + } + +} diff --git a/Mage.Sets/src/mage/cards/t/TalonOfPain.java b/Mage.Sets/src/mage/cards/t/TalonOfPain.java new file mode 100644 index 00000000000..6cdcfb3dc63 --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TalonOfPain.java @@ -0,0 +1,133 @@ +/* + * 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.cards.t; + +import java.util.Objects; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveVariableCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreatureOrPlayer; + +/** + * + * @author jerekwilson + */ +public class TalonOfPain extends CardImpl { + + public TalonOfPain(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); + + + /* + * Whenever a source you control other than Talon of Pain deals damage to an opponent, + * put a charge counter on Talon of Pain. + */ + this.addAbility(new TalonOfPainTriggeredAbility()); + + + // {X}, {tap}, Remove X charge counters from Talon of Pain: Talon of Pain deals X damage to target creature or player. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()) , new ManaCostsImpl("{X}")); + ability.addCost(new TapSourceCost()); + ability.addCost(new RemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance())); + ability.addTarget(new TargetCreatureOrPlayer()); + this.addAbility(ability); + + + } + + public TalonOfPain(final TalonOfPain card) { + super(card); + } + + @Override + public TalonOfPain copy() { + return new TalonOfPain(this); + } + + private class TalonOfPainTriggeredAbility extends TriggeredAbilityImpl { + + public TalonOfPainTriggeredAbility() { + super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance())); + } + + public TalonOfPainTriggeredAbility(final TalonOfPainTriggeredAbility ability) { + super(ability); + } + + @Override + public TalonOfPainTriggeredAbility copy() { + return new TalonOfPainTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_PLAYER; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + // to another player + Player controller = game.getPlayer(this.getControllerId()); + if(controller==null){return false;} + if(controller.hasOpponent(event.getTargetId(),game)){ + // a source you control other than Talon of Pain + UUID sourceControllerId = game.getControllerId(event.getSourceId()); + if (sourceControllerId != null + && sourceControllerId.equals(this.getControllerId()) + && this.getSourceId() != event.getSourceId() ) { + // return true so the effect will fire and a charge counter will be added + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a source you control other than {this} deals damage to an opponent, " + super.getRule(); + } + } +} diff --git a/Mage.Sets/src/mage/sets/Darksteel.java b/Mage.Sets/src/mage/sets/Darksteel.java index eae36ce1cd2..923073de62e 100644 --- a/Mage.Sets/src/mage/sets/Darksteel.java +++ b/Mage.Sets/src/mage/sets/Darksteel.java @@ -157,6 +157,7 @@ public class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Sword of Fire and Ice", 148, Rarity.RARE, mage.cards.s.SwordOfFireAndIce.class)); cards.add(new SetCardInfo("Sword of Light and Shadow", 149, Rarity.RARE, mage.cards.s.SwordOfLightAndShadow.class)); cards.add(new SetCardInfo("Synod Artificer", 34, Rarity.RARE, mage.cards.s.SynodArtificer.class)); + cards.add(new SetCardInfo("Talon of Pain", 150, Rarity.UNCOMMON, mage.cards.t.TalonOfPain.class)); cards.add(new SetCardInfo("Tangle Golem", 151, Rarity.COMMON, mage.cards.t.TangleGolem.class)); cards.add(new SetCardInfo("Tangle Spider", 85, Rarity.COMMON, mage.cards.t.TangleSpider.class)); cards.add(new SetCardInfo("Tanglewalker", 86, Rarity.UNCOMMON, mage.cards.t.Tanglewalker.class)); diff --git a/Mage.Sets/src/mage/sets/Dissension.java b/Mage.Sets/src/mage/sets/Dissension.java index 3bc0aaaf640..58724c4ca45 100644 --- a/Mage.Sets/src/mage/sets/Dissension.java +++ b/Mage.Sets/src/mage/sets/Dissension.java @@ -71,7 +71,7 @@ public class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Blood Crypt", 171, Rarity.RARE, mage.cards.b.BloodCrypt.class)); cards.add(new SetCardInfo("Bond of Agony", 38, Rarity.UNCOMMON, mage.cards.b.BondOfAgony.class)); cards.add(new SetCardInfo("Bound // Determined", 149, Rarity.RARE, mage.cards.b.BoundDetermined.class)); - cards.add(new SetCardInfo("Brace for Impact", 5, Rarity.UNCOMMON, mage.cards.b.BraceForImpact.class)); + cards.add(new SetCardInfo("Brace for Impact", 5, Rarity.UNCOMMON, mage.cards.b.BraceForImpact.class)); cards.add(new SetCardInfo("Brain Pry", 39, Rarity.UNCOMMON, mage.cards.b.BrainPry.class)); cards.add(new SetCardInfo("Breeding Pool", 172, Rarity.RARE, mage.cards.b.BreedingPool.class)); cards.add(new SetCardInfo("Bronze Bombshell", 160, Rarity.RARE, mage.cards.b.BronzeBombshell.class)); @@ -118,6 +118,7 @@ public class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Indrik Stomphowler", 86, Rarity.UNCOMMON, mage.cards.i.IndrikStomphowler.class)); cards.add(new SetCardInfo("Infernal Tutor", 46, Rarity.RARE, mage.cards.i.InfernalTutor.class)); cards.add(new SetCardInfo("Isperia the Inscrutable", 114, Rarity.RARE, mage.cards.i.IsperiaTheInscrutable.class)); + cards.add(new SetCardInfo("Jagged Poppet", 115, Rarity.UNCOMMON, mage.cards.j.JaggedPoppet.class)); cards.add(new SetCardInfo("Kill-Suit Cultist", 65, Rarity.COMMON, mage.cards.k.KillSuitCultist.class)); cards.add(new SetCardInfo("Kindle the Carnage", 66, Rarity.UNCOMMON, mage.cards.k.KindleTheCarnage.class)); cards.add(new SetCardInfo("Leafdrake Roost", 116, Rarity.UNCOMMON, mage.cards.l.LeafdrakeRoost.class)); @@ -199,7 +200,7 @@ public class Dissension extends ExpansionSet { cards.add(new SetCardInfo("Trial // Error", 158, Rarity.UNCOMMON, mage.cards.t.TrialError.class)); cards.add(new SetCardInfo("Trygon Predator", 133, Rarity.UNCOMMON, mage.cards.t.TrygonPredator.class)); cards.add(new SetCardInfo("Twinstrike", 134, Rarity.UNCOMMON, mage.cards.t.Twinstrike.class)); - cards.add(new SetCardInfo("Unliving Psychopath", 56, Rarity.RARE, mage.cards.u.UnlivingPsychopath.class)); + cards.add(new SetCardInfo("Unliving Psychopath", 56, Rarity.RARE, mage.cards.u.UnlivingPsychopath.class)); cards.add(new SetCardInfo("Utopia Sprawl", 99, Rarity.COMMON, mage.cards.u.UtopiaSprawl.class)); cards.add(new SetCardInfo("Utvara Scalper", 76, Rarity.COMMON, mage.cards.u.UtvaraScalper.class)); cards.add(new SetCardInfo("Valor Made Real", 20, Rarity.COMMON, mage.cards.v.ValorMadeReal.class)); diff --git a/Mage.Sets/src/mage/sets/Mirrodin.java b/Mage.Sets/src/mage/sets/Mirrodin.java index 7222f68d8a5..a8f3fc7340b 100644 --- a/Mage.Sets/src/mage/sets/Mirrodin.java +++ b/Mage.Sets/src/mage/sets/Mirrodin.java @@ -68,6 +68,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Crystal Shard", 159, Rarity.UNCOMMON, mage.cards.c.CrystalShard.class)); cards.add(new SetCardInfo("Culling Scales", 160, Rarity.RARE, mage.cards.c.CullingScales.class)); cards.add(new SetCardInfo("Damping Matrix", 161, Rarity.RARE, mage.cards.d.DampingMatrix.class)); + cards.add(new SetCardInfo("Dead-Iron Sledge", 162, Rarity.UNCOMMON, mage.cards.d.DeadIronSledge.class)); cards.add(new SetCardInfo("Deconstruct", 118, Rarity.COMMON, mage.cards.d.Deconstruct.class)); cards.add(new SetCardInfo("Detonate", 88, Rarity.UNCOMMON, mage.cards.d.Detonate.class)); cards.add(new SetCardInfo("Disarm", 32, Rarity.COMMON, mage.cards.d.Disarm.class)); diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 10b7c6d885f..6d3da98bb32 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -128,6 +128,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Rebel Informer", 75, Rarity.RARE, mage.cards.r.RebelInformer.class)); cards.add(new SetCardInfo("Rethink", 42, Rarity.COMMON, mage.cards.r.Rethink.class)); cards.add(new SetCardInfo("Reveille Squad", 18, Rarity.UNCOMMON, mage.cards.r.ReveilleSquad.class)); + cards.add(new SetCardInfo("Rhystic Cave", 142, Rarity.UNCOMMON, mage.cards.r.RhysticCave.class)); cards.add(new SetCardInfo("Rhystic Circle", 19, Rarity.COMMON, mage.cards.r.RhysticCircle.class)); cards.add(new SetCardInfo("Rhystic Study", 45, Rarity.COMMON, mage.cards.r.RhysticStudy.class)); cards.add(new SetCardInfo("Rhystic Tutor", 77, Rarity.RARE, mage.cards.r.RhysticTutor.class));