From 2dc674b75c5decff3d400be302722e9aa2db67b7 Mon Sep 17 00:00:00 2001 From: "Saga\\Robert" Date: Thu, 17 Aug 2017 00:22:14 +0200 Subject: [PATCH] - added Kindred Boon, Charge, Discovery and Summons - updated c17 set class --- Mage.Sets/src/mage/cards/k/KindredBoon.java | 90 +++++++++++++ Mage.Sets/src/mage/cards/k/KindredCharge.java | 117 ++++++++++++++++ .../src/mage/cards/k/KindredDiscovery.java | 68 ++++++++++ .../src/mage/cards/k/KindredSummons.java | 126 ++++++++++++++++++ Mage.Sets/src/mage/sets/Commander2017.java | 4 + 5 files changed, 405 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/k/KindredBoon.java create mode 100644 Mage.Sets/src/mage/cards/k/KindredCharge.java create mode 100644 Mage.Sets/src/mage/cards/k/KindredDiscovery.java create mode 100644 Mage.Sets/src/mage/cards/k/KindredSummons.java diff --git a/Mage.Sets/src/mage/cards/k/KindredBoon.java b/Mage.Sets/src/mage/cards/k/KindredBoon.java new file mode 100644 index 00000000000..c0be740e70d --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KindredBoon.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.cards.k; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.abilities.effects.common.continuous.GainAbilityControlledEffect; +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.ChosenSubtypePredicate; +import mage.filter.predicate.permanent.CounterPredicate; +import mage.target.TargetPermanent; +/** + * + * @author Saga + */ +public class KindredBoon extends CardImpl { + + private static final FilterControlledCreaturePermanent filterDivinity = new FilterControlledCreaturePermanent("Each creature you control with a divinity counter on it"); + static { + filterDivinity.add(new CounterPredicate(CounterType.DIVINITY)); + } + + public KindredBoon(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{W}{W}"); + + // As Kindred Boon enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.AddAbility))); + + // {1}{W}: Put a divinity counter on target creature you control of the chosen type. + FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature you control of the chosen type"); + filter.add(new ChosenSubtypePredicate(this.getId())); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.DIVINITY.createInstance()), new ManaCostsImpl("{1}{W}")); + ability.addTarget(new TargetPermanent(filter)); + this.addAbility(ability); + + // Each creature you control with a divinity counter on it has indestructible. + Effect effect = new GainAbilityControlledEffect(IndestructibleAbility.getInstance(), Duration.WhileOnBattlefield, filterDivinity); + effect.setText("Each creature you control with a divinity counter on it has indestructible"); + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); + } + + public KindredBoon(final KindredBoon card) { + super(card); + } + + @Override + public KindredBoon copy() { + return new KindredBoon(this); + } +} diff --git a/Mage.Sets/src/mage/cards/k/KindredCharge.java b/Mage.Sets/src/mage/cards/k/KindredCharge.java new file mode 100644 index 00000000000..bc93536051a --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KindredCharge.java @@ -0,0 +1,117 @@ +/* + * 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.k; + +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.effects.common.PutTokenOntoBattlefieldCopyTargetEffect; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author Saga + */ +public class KindredCharge extends CardImpl { + + public KindredCharge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{R}{R}"); + + // Choose a creature type. For each creature you control of the chosen type, create a token that's a copy of that creature. + // Those tokens gain haste. Exile them at the beginning of the next end step. + this.getSpellAbility().addEffect(new ChooseCreatureTypeEffect(Outcome.Copy)); + this.getSpellAbility().addEffect(new KindredChargeEffect()); + } + + public KindredCharge(final KindredCharge card) { + super(card); + } + + @Override + public KindredCharge copy() { + return new KindredCharge(this); + } +} + +class KindredChargeEffect extends OneShotEffect { + + public KindredChargeEffect() { + super(Outcome.Copy); + this.staticText = "For each creature you control of the chosen type, create a token that's a copy of that creature. " + + "Those tokens gain haste. Exile them at the beginning of the next end step"; + } + + public KindredChargeEffect(final KindredChargeEffect effect) { + super(effect); + } + + @Override + public KindredChargeEffect copy() { + return new KindredChargeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = game.getObject(source.getSourceId()); + if (controller != null && sourceObject != null) { + String creatureType = game.getState().getValue(sourceObject.getId() + "_type").toString(); + FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature you control of the chosen type"); + filter.add(new SubtypePredicate(SubType.byDescription(creatureType))); + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { + if (permanent != null) { + PutTokenOntoBattlefieldCopyTargetEffect effect = new PutTokenOntoBattlefieldCopyTargetEffect(source.getControllerId(), null, true); + effect.setTargetPointer(new FixedTarget(permanent, game)); + effect.apply(game, source); + for (Permanent addedToken : effect.getAddedPermanent()) { + Effect exileEffect = new ExileTargetEffect(); + exileEffect.setTargetPointer(new FixedTarget(addedToken, game)); + game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect), source); + } + } + } + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/k/KindredDiscovery.java b/Mage.Sets/src/mage/cards/k/KindredDiscovery.java new file mode 100644 index 00000000000..79069afc07a --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KindredDiscovery.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.cards.k; + +import java.util.UUID; +import mage.abilities.common.AsEntersBattlefieldAbility; +import mage.abilities.common.EntersBattlefieldOrAttacksAllTriggeredAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.mageobject.ChosenSubtypePredicate; +/** + * + * @author Saga + */ +public class KindredDiscovery extends CardImpl { + + public KindredDiscovery(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}{U}"); + + // As Kindred Discovery enters the battlefield, choose a creature type. + this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.DrawCard))); + + // Whenever a creature you control of the chosen type enters the battlefield or attacks, draw a card. + FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a creature you control of the chosen type"); + filter.add(new ChosenSubtypePredicate(this.getId())); + this.addAbility(new EntersBattlefieldOrAttacksAllTriggeredAbility(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(1), filter, false)); + } + + public KindredDiscovery(final KindredDiscovery card) { + super(card); + } + + @Override + public KindredDiscovery copy() { + return new KindredDiscovery(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/k/KindredSummons.java b/Mage.Sets/src/mage/cards/k/KindredSummons.java new file mode 100644 index 00000000000..a34f76dc977 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KindredSummons.java @@ -0,0 +1,126 @@ +/* + * 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.k; + +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ChooseCreatureTypeEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.game.Game; +import mage.players.Player; +/** + * + * @author Saga + */ +public class KindredSummons extends CardImpl { + + public KindredSummons(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{5}{G}{G}"); + + // Choose a creature type. Reveal cards from the top of your library until you reveal X creature cards of the chosen type, + // where X is the number of creatures you control of that type. Put those cards onto the battlefield, + // then shuffle the rest of the revealed cards into your library. + this.getSpellAbility().addEffect(new ChooseCreatureTypeEffect(Outcome.PutCreatureInPlay)); + this.getSpellAbility().addEffect(new KindredSummonsEffect()); + } + + public KindredSummons(final KindredSummons card) { + super(card); + } + + @Override + public KindredSummons copy() { + return new KindredSummons(this); + } +} + +class KindredSummonsEffect extends OneShotEffect { + + public KindredSummonsEffect() { + super(Outcome.PutCreatureInPlay); + this.staticText = "Reveal cards from the top of your library until you reveal X creature cards of the chosen type, " + + "where X is the number of creatures you control of that type. Put those cards onto the battlefield, " + + "then shuffle the rest of the revealed cards into your library"; + } + + public KindredSummonsEffect(final KindredSummonsEffect effect) { + super(effect); + } + + @Override + public KindredSummonsEffect copy() { + return new KindredSummonsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + MageObject sourceObject = source.getSourceObject(game); + if (controller != null && sourceObject != null) { + String creatureType = game.getState().getValue(sourceObject.getId() + "_type").toString(); + FilterControlledCreaturePermanent filterPermanent = new FilterControlledCreaturePermanent("creature you control of the chosen type"); + filterPermanent.add(new SubtypePredicate(SubType.byDescription(creatureType))); + int numberOfCards = game.getBattlefield().countAll(filterPermanent, source.getControllerId(), game); + Cards revealed = new CardsImpl(); + Set chosenSubtypeCreatureCards = new LinkedHashSet<>(); + Cards otherCards = new CardsImpl(); + FilterCreatureCard filterCard = new FilterCreatureCard("creature card of the chosen type"); + filterCard.add(new SubtypePredicate(SubType.byDescription(creatureType))); + while (chosenSubtypeCreatureCards.size() < numberOfCards && controller.getLibrary().hasCards()) { + Card card = controller.getLibrary().removeFromTop(game); + revealed.add(card); + if (card != null && filterCard.match(card, game)) { + chosenSubtypeCreatureCards.add(card); + } else { + otherCards.add(card); + } + } + controller.revealCards(sourceObject.getIdName(), revealed, game); + controller.moveCards(chosenSubtypeCreatureCards, Zone.BATTLEFIELD, source, game, false, false, false, null); + controller.putCardsOnTopOfLibrary(otherCards, game, source, false); + controller.shuffleLibrary(source, game); + return true; + } + return false; + } +} diff --git a/Mage.Sets/src/mage/sets/Commander2017.java b/Mage.Sets/src/mage/sets/Commander2017.java index 821b6fdc714..91655e5700b 100644 --- a/Mage.Sets/src/mage/sets/Commander2017.java +++ b/Mage.Sets/src/mage/sets/Commander2017.java @@ -62,7 +62,11 @@ public class Commander2017 extends ExpansionSet { cards.add(new SetCardInfo("Hungry Lynx", 31, Rarity.RARE, mage.cards.h.HungryLynx.class)); cards.add(new SetCardInfo("Fractured Identity", 37, Rarity.RARE, mage.cards.f.FracturedIdentity.class)); cards.add(new SetCardInfo("Inalla, Archmage Ritualist", 38, Rarity.MYTHIC, mage.cards.i.InallaArchmageRitualist.class)); + cards.add(new SetCardInfo("Kindred Boon", 5, Rarity.RARE, mage.cards.k.KindredBoon.class)); + cards.add(new SetCardInfo("Kindred Charge", 27, Rarity.RARE, mage.cards.k.KindredCharge.class)); + cards.add(new SetCardInfo("Kindred Discovery", 11, Rarity.RARE, mage.cards.k.KindredDiscovery.class)); cards.add(new SetCardInfo("Kindred Dominance", 18, Rarity.RARE, mage.cards.k.KindredDominance.class)); + cards.add(new SetCardInfo("Kindred Summons", 32, Rarity.RARE, mage.cards.k.KindredSummons.class)); cards.add(new SetCardInfo("Mirror of the Forebears", 54, Rarity.UNCOMMON, mage.cards.m.MirrorOfTheForebears.class)); cards.add(new SetCardInfo("Nazahn, Revered Bladesmith", 44, Rarity.MYTHIC, mage.cards.n.NazahnReveredBladesmith.class)); cards.add(new SetCardInfo("O-Kagachi, Vengeful Kami", 45, Rarity.MYTHIC, mage.cards.o.OKagachiVengefulKami.class));