From 6bf8699208db171bdd680ceb7d9a14f961b1ccb1 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 12 Sep 2014 01:33:09 +0200 Subject: [PATCH] [KTK] Added 10 cards. --- .../bornofthegods/BrimazKingOfOreskos.java | 1 + .../sets/khansoftarkir/AltarOfTheBrood.java | 70 +++++++ .../mage/sets/khansoftarkir/BribersPurse.java | 113 ++++++++++ .../sets/khansoftarkir/CranialArchive.java | 106 ++++++++++ .../khansoftarkir/EfreetWeaponmaster.java | 6 +- .../mage/sets/khansoftarkir/Goblinslide.java | 11 +- .../sets/khansoftarkir/HeartPiercerBow.java | 115 +++++++++++ .../sets/khansoftarkir/KinTreeInvocation.java | 112 ++++++++++ .../sets/khansoftarkir/LensOfClarity.java | 195 ++++++++++++++++++ .../sets/khansoftarkir/PonybackBrigade.java | 115 +++++++++++ .../src/mage/sets/khansoftarkir/RideDown.java | 124 +++++++++++ .../sets/khansoftarkir/SnowhornRider.java | 72 +++++++ .../sets/khansoftarkir/VillainousWealth.java | 136 ++++++++++++ .../combat/CantAttackBlockTargetEffect.java | 73 +++++++ .../mage/abilities/keyword/MorphAbility.java | 4 +- Mage/src/mage/players/PlayerImpl.java | 2 +- 16 files changed, 1245 insertions(+), 10 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/AltarOfTheBrood.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/BribersPurse.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/CranialArchive.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/HeartPiercerBow.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/KinTreeInvocation.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/RideDown.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/SnowhornRider.java create mode 100644 Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java create mode 100644 Mage/src/mage/abilities/effects/common/combat/CantAttackBlockTargetEffect.java diff --git a/Mage.Sets/src/mage/sets/bornofthegods/BrimazKingOfOreskos.java b/Mage.Sets/src/mage/sets/bornofthegods/BrimazKingOfOreskos.java index 1cb99728cc7..4b9700cad4d 100644 --- a/Mage.Sets/src/mage/sets/bornofthegods/BrimazKingOfOreskos.java +++ b/Mage.Sets/src/mage/sets/bornofthegods/BrimazKingOfOreskos.java @@ -65,6 +65,7 @@ public class BrimazKingOfOreskos extends CardImpl { // Vigilance this.addAbility(VigilanceAbility.getInstance()); + // Whenever Brimaz, King of Oreskos attacks, put a 1/1 white Cat Soldier creature token with vigilance onto the battlefield attacking. this.addAbility(new AttacksTriggeredAbility(new CreateTokenEffect(new CatSoldierCreatureToken(), 1, false, true), false)); diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/AltarOfTheBrood.java b/Mage.Sets/src/mage/sets/khansoftarkir/AltarOfTheBrood.java new file mode 100644 index 00000000000..c1f5a97ff80 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/AltarOfTheBrood.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.khansoftarkir; + +import java.util.UUID; +import mage.abilities.common.EntersBattlefieldAllTriggeredAbility; +import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveEachPlayerEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterControlledPermanent; +import mage.filter.predicate.permanent.AnotherPredicate; + +/** + * + * @author LevelX2 + */ +public class AltarOfTheBrood extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("another permanent"); + + static { + filter.add(new AnotherPredicate()); + } + + public AltarOfTheBrood(UUID ownerId) { + super(ownerId, 216, "Altar of the Brood", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "KTK"; + + // Whenever another permanent enters the battlefield under your control, each opponent puts the top card of his or her library into his or her graveyard. + this.addAbility(new EntersBattlefieldAllTriggeredAbility(Zone.BATTLEFIELD, + new PutTopCardOfLibraryIntoGraveEachPlayerEffect(1, TargetController.OPPONENT), filter, false)); + } + + public AltarOfTheBrood(final AltarOfTheBrood card) { + super(card); + } + + @Override + public AltarOfTheBrood copy() { + return new AltarOfTheBrood(this); + } +} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/BribersPurse.java b/Mage.Sets/src/mage/sets/khansoftarkir/BribersPurse.java new file mode 100644 index 00000000000..29f984a7408 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/BribersPurse.java @@ -0,0 +1,113 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.khansoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.combat.CantAttackBlockTargetEffect; +import mage.abilities.effects.common.combat.CantAttackTargetEffect; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.counters.Counter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class BribersPurse extends CardImpl { + + public BribersPurse(UUID ownerId) { + super(ownerId, 217, "Briber's Purse", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{X}"); + this.expansionSetCode = "KTK"; + + // Briber's Purse enters the battlefield with X gem counters on it. + this.addAbility(new EntersBattlefieldAbility(new BribersPurseEffect(), "{this} enters the battlefield with X gem counters on it")); + + // {1}, {T}, Remove a gem counter from Briber's Purse: Target creature can't attack or block this turn. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CantAttackBlockTargetEffect(Duration.EndOfTurn), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + ability.addCost(new RemoveCountersSourceCost(new Counter("gem"))); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public BribersPurse(final BribersPurse card) { + super(card); + } + + @Override + public BribersPurse copy() { + return new BribersPurse(this); + } +} + +class BribersPurseEffect extends OneShotEffect { + public BribersPurseEffect() { + super(Outcome.Benefit); + } + + public BribersPurseEffect(final BribersPurseEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + Object obj = getValue(EntersBattlefieldEffect.SOURCE_CAST_SPELL_ABILITY); + if (obj != null && obj instanceof SpellAbility) { + int amount = ((SpellAbility) obj).getManaCostsToPay().getX(); + if (amount > 0) { + permanent.addCounters(new Counter("gem", amount), game); + } + } + } + return true; + } + + @Override + public BribersPurseEffect copy() { + return new BribersPurseEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/CranialArchive.java b/Mage.Sets/src/mage/sets/khansoftarkir/CranialArchive.java new file mode 100644 index 00000000000..2b39b1e0372 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/CranialArchive.java @@ -0,0 +1,106 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.khansoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author LevelX2 + */ +public class CranialArchive extends CardImpl { + + public CranialArchive(UUID ownerId) { + super(ownerId, 218, "Cranial Archive", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "KTK"; + + // {2}, Exile Cranial Archive: Target player shuffles his or her gravyeard into his or her library. Draw a card. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CranialArchiveEffect(), new GenericManaCost(2)); + ability.addCost(new SacrificeSourceCost()); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + + } + + public CranialArchive(final CranialArchive card) { + super(card); + } + + @Override + public CranialArchive copy() { + return new CranialArchive(this); + } +} + +class CranialArchiveEffect extends OneShotEffect { + + public CranialArchiveEffect() { + super(Outcome.Benefit); + this.staticText = "Target player shuffles his or her gravyeard into his or her library. Draw a card"; + } + + public CranialArchiveEffect(final CranialArchiveEffect effect) { + super(effect); + } + + @Override + public CranialArchiveEffect copy() { + return new CranialArchiveEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetPlayer != null) { + for (Card card: targetPlayer.getGraveyard().getCards(game)){ + targetPlayer.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.GRAVEYARD, true, true); + } + targetPlayer.shuffleLibrary(game); + } + controller.drawCards(1, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java b/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java index 91a7a55d462..fb14f5a1327 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/EfreetWeaponmaster.java @@ -44,6 +44,7 @@ import mage.filter.predicate.permanent.AnotherPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; import mage.target.common.TargetControlledCreaturePermanent; /** @@ -113,7 +114,10 @@ class EfreetWeaponmasterAbility extends TriggeredAbilityImpl { return true; } if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { - return true; + Permanent sourcePermanent = game.getPermanent(getSourceId()); + if (sourcePermanent != null && !sourcePermanent.isFaceDown()) { + return true; + } } return false; } diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/Goblinslide.java b/Mage.Sets/src/mage/sets/khansoftarkir/Goblinslide.java index 787dadf65a4..71f60987189 100644 --- a/Mage.Sets/src/mage/sets/khansoftarkir/Goblinslide.java +++ b/Mage.Sets/src/mage/sets/khansoftarkir/Goblinslide.java @@ -47,8 +47,9 @@ import mage.game.permanent.token.Token; * @author emerald000 */ public class Goblinslide extends CardImpl { - + private static final FilterSpell filter = new FilterSpell("noncreature spell"); + static { filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); } @@ -60,7 +61,7 @@ public class Goblinslide extends CardImpl { this.color.setRed(true); // Whenever you cast a noncreature spell, you may pay {1}. If you do, put a 1/1 red Goblin creature token with haste onto the battlefield. - this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new GoblinToken()), new GenericManaCost(1)), filter, false)); + this.addAbility(new SpellCastControllerTriggeredAbility(new DoIfCostPaid(new CreateTokenEffect(new GoblinslideGoblinToken()), new GenericManaCost(1)), filter, false)); } public Goblinslide(final Goblinslide card) { @@ -73,9 +74,9 @@ public class Goblinslide extends CardImpl { } } -class GoblinToken extends Token { +class GoblinslideGoblinToken extends Token { - GoblinToken() { + GoblinslideGoblinToken() { super("Goblin", "1/1 red Goblin creature token with haste"); this.setOriginalExpansionSetCode("KTK"); cardType.add(CardType.CREATURE); @@ -84,5 +85,5 @@ class GoblinToken extends Token { power = new MageInt(1); toughness = new MageInt(1); addAbility(HasteAbility.getInstance()); - } + } } diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/HeartPiercerBow.java b/Mage.Sets/src/mage/sets/khansoftarkir/HeartPiercerBow.java new file mode 100644 index 00000000000..d251b318ca6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/HeartPiercerBow.java @@ -0,0 +1,115 @@ +/* + * 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.khansoftarkir; + +import java.util.UUID; +import mage.abilities.common.AttacksAttachedTriggeredAbility; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.DamageTargetEffect; +import mage.abilities.keyword.EquipAbility; +import mage.cards.CardImpl; +import mage.constants.AttachmentType; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.ControllerIdPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class HeartPiercerBow extends CardImpl { + + public HeartPiercerBow(UUID ownerId) { + super(ownerId, 221, "Heart-Piercer Bow", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); + this.expansionSetCode = "KTK"; + this.subtype.add("Equipment"); + + // Whenever equipped creature attacks, Heart-Piercer Bow deals 1 damage to target creature defending player controls. + this.addAbility(new HeartPiercerBowAbility()); + + // Equip {1} + this.addAbility(new EquipAbility(Outcome.Benefit, new GenericManaCost(1))); + } + + public HeartPiercerBow(final HeartPiercerBow card) { + super(card); + } + + + + @Override + public HeartPiercerBow copy() { + return new HeartPiercerBow(this); + } +} + +class HeartPiercerBowAbility extends AttacksAttachedTriggeredAbility { + + public HeartPiercerBowAbility() { + super(new DamageTargetEffect(1), AttachmentType.EQUIPMENT, false); + } + + public HeartPiercerBowAbility(final HeartPiercerBowAbility ability) { + super(ability); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (super.checkTrigger(event, game)) { + Permanent equipment = game.getPermanent(getSourceId()); + if (equipment != null && equipment.getAttachedTo() != null) { + FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls"); + UUID defenderId = game.getCombat().getDefendingPlayerId(equipment.getAttachedTo(), game); + if (defenderId != null) { + filter.add(new ControllerIdPredicate(defenderId)); + this.getTargets().clear(); + TargetCreaturePermanent target = new TargetCreaturePermanent(filter); + this.addTarget(target); + return true; + } + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever equipped creature attacks, {this} deals 1 damage to target creature defending player controls."; + } + + @Override + public HeartPiercerBowAbility copy() { + return new HeartPiercerBowAbility(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/KinTreeInvocation.java b/Mage.Sets/src/mage/sets/khansoftarkir/KinTreeInvocation.java new file mode 100644 index 00000000000..ccbd4e0736a --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/KinTreeInvocation.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.khansoftarkir; + +import java.util.ArrayList; +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.AbilitiesImpl; +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.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.Token; + +/** + * + * @author LevelX2 + */ +public class KinTreeInvocation extends CardImpl { + + public KinTreeInvocation(UUID ownerId) { + // TODO: Check rarity + super(ownerId, 183, "Kin-Tree Invocation", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{B}{G}"); + this.expansionSetCode = "KTK"; + + this.color.setGreen(true); + this.color.setBlack(true); + + // Put an X/X black and green Spirit Warrior creature token onto the battlefield, where X is the greatest toughness among creatures you control. + this.getSpellAbility().addEffect(new KinTreeInvocationCreateTokenEffect()); + + } + + public KinTreeInvocation(final KinTreeInvocation card) { + super(card); + } + + @Override + public KinTreeInvocation copy() { + return new KinTreeInvocation(this); + } +} + +class KinTreeInvocationCreateTokenEffect extends OneShotEffect { + + public KinTreeInvocationCreateTokenEffect() { + super(Outcome.PutCreatureInPlay); + staticText = "Put an X/X black and green Spirit Warrior creature token onto the battlefield, where X is the greatest toughness among creatures you control"; + } + + public KinTreeInvocationCreateTokenEffect(final KinTreeInvocationCreateTokenEffect effect) { + super(effect); + } + + @Override + public KinTreeInvocationCreateTokenEffect copy() { + return new KinTreeInvocationCreateTokenEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + int value = Integer.MIN_VALUE; + for (Permanent permanent: game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getControllerId(), game)) { + if (value < permanent.getToughness().getValue()) { + value = permanent.getToughness().getValue(); + } + } + + ArrayList list = new ArrayList<>(); + list.add("Spirit"); + list.add("Warrior"); + ObjectColor objectColor = new ObjectColor(); + objectColor.setBlack(true); + objectColor.setGreen(true); + Token token = new Token("Spirit Warrior", "X/X black and green Spirit Warrior creature token onto the battlefield, where X is the greatest toughness among creatures you control", + objectColor, list, value, value, new AbilitiesImpl()); + token.getAbilities().newId(); // neccessary if token has ability like DevourAbility() + token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); + return true; + } + +} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java b/Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java new file mode 100644 index 00000000000..1c824429758 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/LensOfClarity.java @@ -0,0 +1,195 @@ +/* + * 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.khansoftarkir; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.other.FaceDownPredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX2 + */ +public class LensOfClarity extends CardImpl { + + public LensOfClarity(UUID ownerId) { + super(ownerId, 223, "Lens of Clarity", Rarity.COMMON, new CardType[]{CardType.ARTIFACT}, "{1}"); + this.expansionSetCode = "KTK"; + + // You may look at the top card of your library and at face-down creatures you don't control. + // TODO: this should be a static ability + this.addAbility(new LensOfClarityLookLibraryAbility()); + this.addAbility(new LensOfClarityLookFaceDownAbility()); + } + + public LensOfClarity(final LensOfClarity card) { + super(card); + } + + @Override + public LensOfClarity copy() { + return new LensOfClarity(this); + } +} + +class LensOfClarityLookLibraryAbility extends ActivatedAbilityImpl { + + public LensOfClarityLookLibraryAbility() { + super(Zone.BATTLEFIELD, new LensOfClarityLookLibraryEffect(), new GenericManaCost(0)); + this.usesStack = false; + } + + public LensOfClarityLookLibraryAbility(LensOfClarityLookLibraryAbility ability) { + super(ability); + } + + @Override + public LensOfClarityLookLibraryAbility copy() { + return new LensOfClarityLookLibraryAbility(this); + } + +} + +class LensOfClarityLookLibraryEffect extends OneShotEffect { + + public LensOfClarityLookLibraryEffect() { + super(Outcome.Neutral); + this.staticText = "You may look at the top card of your library"; + } + + public LensOfClarityLookLibraryEffect(final LensOfClarityLookLibraryEffect effect) { + super(effect); + } + + @Override + public LensOfClarityLookLibraryEffect copy() { + return new LensOfClarityLookLibraryEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getObject(source.getSourceId()); + if (player == null || mageObject == null) { + return false; + } + + Card card = player.getLibrary().getFromTop(game); + if (card != null) { + Cards cards = new CardsImpl(); + cards.add(card); + player.lookAtCards("top card of library - " + player.getName(), cards, game); + } else { + return false; + } + + return true; + } +} + +class LensOfClarityLookFaceDownAbility extends ActivatedAbilityImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("face down creature you don't control"); + + static { + filter.add(new FaceDownPredicate()); + filter.add(new ControllerPredicate(TargetController.NOT_YOU)); + } + + public LensOfClarityLookFaceDownAbility() { + super(Zone.BATTLEFIELD, new LensOfClarityLookFaceDownEffect(), new GenericManaCost(0)); + this.usesStack = false; + this.addTarget(new TargetCreaturePermanent(filter)); + } + + public LensOfClarityLookFaceDownAbility(LensOfClarityLookFaceDownAbility ability) { + super(ability); + } + + @Override + public LensOfClarityLookFaceDownAbility copy() { + return new LensOfClarityLookFaceDownAbility(this); + } + +} + +class LensOfClarityLookFaceDownEffect extends OneShotEffect { + + public LensOfClarityLookFaceDownEffect() { + super(Outcome.Benefit); + this.staticText = "You may look at face-down creatures you don't control"; + } + + public LensOfClarityLookFaceDownEffect(final LensOfClarityLookFaceDownEffect effect) { + super(effect); + } + + @Override + public LensOfClarityLookFaceDownEffect copy() { + return new LensOfClarityLookFaceDownEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getObject(source.getSourceId()); + if (player == null || mageObject == null) { + return false; + } + Permanent faceDownCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (faceDownCreature != null) { + Permanent copyFaceDown = faceDownCreature.copy(); + copyFaceDown.setFaceDown(false); + Cards cards = new CardsImpl(); + cards.add(copyFaceDown); + player.lookAtCards("face down card - " + mageObject.getLogName(), cards, game); + } else { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java b/Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java new file mode 100644 index 00000000000..f552719a124 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/PonybackBrigade.java @@ -0,0 +1,115 @@ +/* + * 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.khansoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.keyword.MorphAbility; +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.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.GoblinToken; + +/** + * + * @author LevelX2 + */ +public class PonybackBrigade extends CardImpl { + + public PonybackBrigade(UUID ownerId) { + super(ownerId, 191, "Ponyback Brigade", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{R}{W}{B}"); + this.expansionSetCode = "KTK"; + this.subtype.add("Goblin"); + this.subtype.add("Warrior"); + + this.color.setRed(true); + this.color.setBlack(true); + this.color.setWhite(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Ponyback Brigade enters the battlefield or is turned face up, put three 1/1 red Goblin creature tokens onto the battlefield. + this.addAbility(new PonybackBrigadeAbility()); + + // Morph {2}{R}{W}{B} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{R}{W}{B}"))); + } + + public PonybackBrigade(final PonybackBrigade card) { + super(card); + } + + @Override + public PonybackBrigade copy() { + return new PonybackBrigade(this); + } +} + +class PonybackBrigadeAbility extends TriggeredAbilityImpl { + + public PonybackBrigadeAbility() { + super(Zone.BATTLEFIELD, new CreateTokenEffect(new GoblinToken("KTK"), 3), false); + this.setWorksFaceDown(true); + } + + public PonybackBrigadeAbility(final PonybackBrigadeAbility ability) { + super(ability); + } + + @Override + public PonybackBrigadeAbility copy() { + return new PonybackBrigadeAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == EventType.TURNEDFACEUP && event.getTargetId().equals(this.getSourceId())) { + return true; + } + if (event.getType() == EventType.ENTERS_THE_BATTLEFIELD && event.getTargetId().equals(this.getSourceId()) ) { + Permanent sourcePermanent = game.getPermanent(getSourceId()); + if (sourcePermanent != null && !sourcePermanent.isFaceDown()) { + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "When {this} enters the battlefield or is turned face up, " + super.getRule(); + } +} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/RideDown.java b/Mage.Sets/src/mage/sets/khansoftarkir/RideDown.java new file mode 100644 index 00000000000..cd504fe9222 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/RideDown.java @@ -0,0 +1,124 @@ +/* + * 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.khansoftarkir; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continious.GainAbilityTargetEffect; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.permanent.BlockingPredicate; +import mage.game.Game; +import mage.game.combat.CombatGroup; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX2 + */ +public class RideDown extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("blocking creature"); + + static { + filter.add(new BlockingPredicate()); + } + + public RideDown(UUID ownerId) { + // TODO: Check Rarity + super(ownerId, 194, "Ride Down", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{R}{W}"); + this.expansionSetCode = "KTK"; + + this.color.setRed(true); + this.color.setWhite(true); + + // Destroy target blocking creature. Creatures that were blocked by that creature this combat gain trample until end of turn. + this.getSpellAbility().addEffect(new RideDownEffect()); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter)); + + } + + public RideDown(final RideDown card) { + super(card); + } + + @Override + public RideDown copy() { + return new RideDown(this); + } +} + +class RideDownEffect extends OneShotEffect { + + public RideDownEffect() { + super(Outcome.Benefit); + this.staticText = "Destroy target blocking creature. Creatures that were blocked by that creature this combat gain trample until end of turn"; + } + + public RideDownEffect(final RideDownEffect effect) { + super(effect); + } + + @Override + public RideDownEffect copy() { + return new RideDownEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent blockingCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); + if (blockingCreature != null) { + for (CombatGroup combatGroup : game.getCombat().getGroups()) { + if (combatGroup.getBlockers().contains(blockingCreature.getId())) { + for (UUID attackerId: combatGroup.getAttackers()) { + ContinuousEffect effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); + effect.setTargetPointer(new FixedTarget(attackerId)); + game.addEffect(effect, source); + } + break; + } + } + blockingCreature.destroy(source.getSourceId(), game, false); + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/SnowhornRider.java b/Mage.Sets/src/mage/sets/khansoftarkir/SnowhornRider.java new file mode 100644 index 00000000000..64839b65b60 --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/SnowhornRider.java @@ -0,0 +1,72 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.sets.khansoftarkir; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.keyword.TrampleAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.keyword.MorphAbility; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Rarity; + +/** + * + * @author LevelX2 + */ +public class SnowhornRider extends CardImpl { + + public SnowhornRider(UUID ownerId) { + // TODO: Check Rarity + super(ownerId, 201, "Snowhorn Rider", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{G}{U}{R}"); + this.expansionSetCode = "KTK"; + this.subtype.add("Human"); + this.subtype.add("Warrior"); + + this.color.setRed(true); + this.color.setBlue(true); + this.color.setGreen(true); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Trample + this.addAbility(TrampleAbility.getInstance()); + // Morph {2}{G}{U}{R} + this.addAbility(new MorphAbility(this, new ManaCostsImpl("{2}{G}{U}{R}"))); + } + + public SnowhornRider(final SnowhornRider card) { + super(card); + } + + @Override + public SnowhornRider copy() { + return new SnowhornRider(this); + } +} diff --git a/Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java b/Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java new file mode 100644 index 00000000000..f522d0f1a1f --- /dev/null +++ b/Mage.Sets/src/mage/sets/khansoftarkir/VillainousWealth.java @@ -0,0 +1,136 @@ +/* + * 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.khansoftarkir; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Rarity; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.filter.FilterCard; +import mage.filter.common.FilterNonlandCard; +import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; +import mage.game.ExileZone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInExile; +import mage.target.common.TargetOpponent; +import mage.util.CardUtil; + +/** + * + * @author LevelX2 + */ +public class VillainousWealth extends CardImpl { + + public VillainousWealth(UUID ownerId) { + super(ownerId, 211, "Villainous Wealth", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{B}{G}{U}"); + this.expansionSetCode = "KTK"; + + this.color.setBlue(true); + this.color.setGreen(true); + this.color.setBlack(true); + + // Target opponent exiles the top X cards of his or her library. You may cast any number of nonland cards with converted mana cost X or less from among them without paying their mana cost. + this.getSpellAbility().addTarget(new TargetOpponent()); + this.getSpellAbility().addEffect(new VillainousWealthEffect()); + + } + + public VillainousWealth(final VillainousWealth card) { + super(card); + } + + @Override + public VillainousWealth copy() { + return new VillainousWealth(this); + } +} + +class VillainousWealthEffect extends OneShotEffect { + + public VillainousWealthEffect() { + super(Outcome.PlayForFree); + this.staticText = "Target opponent exiles the top X cards of his or her library. You may cast any number of nonland cards with converted mana cost X or less from among them without paying their mana cost"; + } + + public VillainousWealthEffect(final VillainousWealthEffect effect) { + super(effect); + } + + @Override + public VillainousWealthEffect copy() { + return new VillainousWealthEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject mageObject = game.getObject(source.getSourceId()); + if (controller != null) { + Player player = game.getPlayer(targetPointer.getFirst(game, source)); + FilterCard filter = new FilterNonlandCard(); + filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.LessThan, source.getManaCostsToPay().getX() + 1)); + UUID exileId = CardUtil.getCardExileZoneId(game, source); + if (player != null) { + + // putting cards to exile shouldn't end the game, so getting minimun available + int cardsCount = Math.min(source.getManaCostsToPay().getX(), player.getLibrary().size()); + for (int i = 0; i < cardsCount; i++) { + Card card = player.getLibrary().getFromTop(game); + if (card != null) { + controller.moveCardToExileWithInfo(card, exileId, "Cards exiled by " + mageObject.getLogName(), source.getSourceId(), game, Zone.LIBRARY); + } + } + } + ExileZone exileZone = game.getExile().getExileZone(exileId); + while (exileZone != null && exileZone.count(filter, game) > 0 + && controller.chooseUse(Outcome.PlayForFree, "Cast cards exiled with " + mageObject.getLogName() +" without paying its mana cost?", game)) { + TargetCardInExile target = new TargetCardInExile(0,1, filter, exileId, false); + while (exileZone.count(filter, game) > 0 && controller.choose(Outcome.PlayForFree, exileZone, target, game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + controller.cast(card.getSpellAbility(), game, true); + } else { + break; + } + target.clearChosen(); + } + } + return true; + } + + return false; + } +} diff --git a/Mage/src/mage/abilities/effects/common/combat/CantAttackBlockTargetEffect.java b/Mage/src/mage/abilities/effects/common/combat/CantAttackBlockTargetEffect.java new file mode 100644 index 00000000000..1ab76e4fb9c --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/combat/CantAttackBlockTargetEffect.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ + +package mage.abilities.effects.common.combat; + +import mage.abilities.Ability; +import mage.abilities.effects.RestrictionEffect; +import mage.constants.Duration; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * + * @author LevelX2 + */ + +public class CantAttackBlockTargetEffect extends RestrictionEffect { + + public CantAttackBlockTargetEffect(Duration duration) { + super(duration); + staticText = "Target creature can't attack or block this turn"; + } + + public CantAttackBlockTargetEffect(final CantAttackBlockTargetEffect effect) { + super(effect); + } + + @Override + public boolean applies(Permanent permanent, Ability source, Game game) { + return permanent.getId().equals(targetPointer.getFirst(game, source)); + } + + @Override + public boolean canAttack(Game game) { + return false; + } + + @Override + public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) { + return false; + } + + @Override + public CantAttackBlockTargetEffect copy() { + return new CantAttackBlockTargetEffect(this); + } + +} \ No newline at end of file diff --git a/Mage/src/mage/abilities/keyword/MorphAbility.java b/Mage/src/mage/abilities/keyword/MorphAbility.java index 2c58fb4e3e7..21715a59e83 100644 --- a/Mage/src/mage/abilities/keyword/MorphAbility.java +++ b/Mage/src/mage/abilities/keyword/MorphAbility.java @@ -38,7 +38,6 @@ import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.TurnFaceUpAbility; -import mage.abilities.common.TurnedFaceUpTriggeredAbility; import mage.abilities.costs.AlternativeCost2; import mage.abilities.costs.AlternativeCost2Impl; import mage.abilities.costs.AlternativeSourceCosts; @@ -48,7 +47,6 @@ import mage.abilities.costs.CostsImpl; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.AsTurnedFaceUpEffect; import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.common.continious.SourceEffect; import mage.cards.Card; @@ -187,7 +185,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost this.resetMorph(); for (AlternativeCost2 alternateCastingCost: alternateCosts) { if (alternateCastingCost.canPay(ability, sourceId, controllerId, game) && - player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(alternateCastingCost.getText(true)).append(" ?").toString(), game)) { + player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(alternateCastingCost.getText(true)).append(" ?").toString(), game)) { Spell spell = game.getStack().getSpell(ability.getId()); if (spell != null) { diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 05a50e55e3b..f60babb93e1 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -794,7 +794,7 @@ public abstract class PlayerImpl implements Player, Serializable { //20091005 - 601.2a Card card = game.getCard(ability.getSourceId()); if (card != null) { - if (card.isMorphCard()) { //TODO: move to other place + if (card.isMorphCard() && !noMana) { //TODO: move to other place card.setFaceDown(true); } if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.CAST_SPELL, ability.getId(), ability.getSourceId(), playerId))) {