From e88a2a199f8a4b077835c1f433d1d0e7d8a9bc83 Mon Sep 17 00:00:00 2001 From: LevelX Date: Mon, 2 Jan 2012 22:30:22 +0100 Subject: [PATCH] New cards [CHK] BloodthirstyOgre / HorobiDeathsWail / KumanosPupil / MyojinOfInfiniteRage / MyojinOfLifesWeb / MyojinOfNightsReach / MyojinOfSeeingWinds / OniPossession / PainwrackerOni Framework PutOntoBattlefieldTargetEffect - new effect SetCardSubtypeAttachedEffect - added constuctor with list of types TargetControlledCreaturePermanent - added constructor with "required" and "filter" DrawCardControllerEffect / SacrificeTargetEffect - improved text generation CountersCount - added flag to return the number of counters as negative value --- .../championsofkamigawa/BloodthirstyOgre.java | 129 +++++++++++++++++ .../championsofkamigawa/HorobiDeathsWail.java | 119 ++++++++++++++++ .../championsofkamigawa/KumanosPupil.java | 132 ++++++++++++++++++ .../MyojinOfCleansingFire.java | 8 +- .../MyojinOfInfiniteRage.java | 89 ++++++++++++ .../championsofkamigawa/MyojinOfLifesWeb.java | 98 +++++++++++++ .../MyojinOfNightsReach.java | 119 ++++++++++++++++ .../MyojinOfSeeingWinds.java | 96 +++++++++++++ .../championsofkamigawa/OniPossession.java | 96 +++++++++++++ .../championsofkamigawa/PainwrackerOni.java | 120 ++++++++++++++++ .../dynamicvalue/common/CountersCount.java | 13 +- .../common/DrawCardControllerEffect.java | 6 +- .../PutOntoBattlefieldTargetEffect.java | 104 ++++++++++++++ .../effects/common/SacrificeTargetEffect.java | 18 ++- .../SetCardSubtypeAttachedEffect.java | 24 +++- .../TargetControlledCreaturePermanent.java | 5 + 16 files changed, 1153 insertions(+), 23 deletions(-) create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/HorobiDeathsWail.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/KumanosPupil.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfLifesWeb.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfNightsReach.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfSeeingWinds.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/OniPossession.java create mode 100644 Mage.Sets/src/mage/sets/championsofkamigawa/PainwrackerOni.java create mode 100644 Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java b/Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java new file mode 100644 index 0000000000..07566c0814 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java @@ -0,0 +1,129 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.ControlPermanentCost; +import mage.abilities.costs.common.SacrificeTargetCost; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.CountersCount; +import mage.abilities.effects.common.continious.BoostTargetEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.counters.CounterType; +import mage.counters.common.DevotionCounter; +import mage.filter.Filter; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX + */ +public class BloodthirstyOgre extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("Demon"); + static { + filter.getSubtype().add("Demon"); + filter.setScopeSubtype(Filter.ComparisonScope.Any); + } + + public BloodthirstyOgre(UUID ownerId) { + super(ownerId, 104, "Bloodthirsty Ogre", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Ogre"); + this.subtype.add("Warrior"); + this.subtype.add("Shaman"); + + this.color.setBlack(true); + this.power = new MageInt(3); + this.toughness = new MageInt(1); + + // {T}: Put a devotion counter on Bloodthirsty Ogre + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(new DevotionCounter()),new TapSourceCost())); + // {T}: Target creature gets -X/-X until end of turn, where X is the number of devotion counters on Bloodthirsty Ogre. Activate this ability only if you control a Demon. + CountersCount devotionCounters = new CountersCount(CounterType.DEVOTION, true); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,new BoostTargetEffect(devotionCounters,devotionCounters, Duration.EndOfTurn),new TapSourceCost()); + ability.addCost(new ControlPermanentCost(filter)); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + public BloodthirstyOgre(final BloodthirstyOgre card) { + super(card); + } + + @Override + public BloodthirstyOgre copy() { + return new BloodthirstyOgre(this); + } + +} + +class IchorExplosionDynamicValue implements DynamicValue { + @Override + public int calculate(Game game, Ability sourceAbility) { + Card sourceCard = game.getCard(sourceAbility.getSourceId()); + if (sourceCard != null) { + for (Object cost: sourceAbility.getCosts()) { + if (cost instanceof SacrificeTargetCost) { + Permanent p = (Permanent) game.getLastKnownInformation(((SacrificeTargetCost) cost).getPermanents().get(0).getId(), Constants.Zone.BATTLEFIELD); + return -1 * p.getPower().getValue(); + } + } + } + return 0; + } + + @Override + public DynamicValue clone() { + return this; + } + + @Override + public String getMessage() { + return ", where X is the sacrificed creature's power"; + } + + @Override + public String toString() { + return "-X"; + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/HorobiDeathsWail.java b/Mage.Sets/src/mage/sets/championsofkamigawa/HorobiDeathsWail.java new file mode 100644 index 0000000000..fe0c8bec22 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/HorobiDeathsWail.java @@ -0,0 +1,119 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.filter.Filter; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX + */ +public class HorobiDeathsWail extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent("Demon"); + static { + filter.getSubtype().add("Demon"); + filter.setScopeSubtype(Filter.ComparisonScope.Any); + } + + public HorobiDeathsWail(UUID ownerId) { + super(ownerId, 117, "Horobi Death's Wail", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{B}{B}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Spirit"); + + this.color.setBlack(true); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + // Whenever a creature becomes the target of a spell or ability, destroy that creature. + this.addAbility(new HorobiDeathsWailAbility(new DestroyTargetEffect())); + } + + public HorobiDeathsWail(final HorobiDeathsWail card) { + super(card); + } + + @Override + public HorobiDeathsWail copy() { + return new HorobiDeathsWail(this); + } + +} + +class HorobiDeathsWailAbility extends TriggeredAbilityImpl { + + public HorobiDeathsWailAbility(Effect effect) { + super(Zone.BATTLEFIELD, effect); + } + + public HorobiDeathsWailAbility(final HorobiDeathsWailAbility ability) { + super(ability); + } + + @Override + public HorobiDeathsWailAbility copy() { + return new HorobiDeathsWailAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == EventType.TARGETED) { + Permanent creature = game.getPermanent(event.getTargetId()); + if (creature != null && creature.getCardType().contains(CardType.CREATURE)) { + getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId())); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "When a creature becomes the target of a spell or ability, destroy that creature."; + } +} + diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/KumanosPupil.java b/Mage.Sets/src/mage/sets/championsofkamigawa/KumanosPupil.java new file mode 100644 index 0000000000..971970d90f --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/KumanosPupil.java @@ -0,0 +1,132 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants.CardType; +import mage.Constants.Duration; +import mage.Constants.Outcome; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.cards.CardImpl; +import mage.filter.Filter; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.watchers.common.DamagedByWatcher; + +/** + * @author LevelX + */ +public class KumanosPupil extends CardImpl { + + private final static FilterControlledPermanent filter = new FilterControlledPermanent("a land"); + + static { + filter.getCardType().add(CardType.LAND); + filter.setScopeCardType(Filter.ComparisonScope.Any); + } + + public KumanosPupil(UUID ownerId) { + super(ownerId, 177, "Kumano's Pupil", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{4}{R}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Human"); + this.subtype.add("Shaman"); + this.color.setRed(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + // If a creature dealt damage by Kumano's Pupils this turn would die, exile it instead. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KumanosPupilEffect())); + + this.addWatcher(new DamagedByWatcher()); + } + + public KumanosPupil(final KumanosPupil card) { + super(card); + } + + @Override + public KumanosPupil copy() { + return new KumanosPupil(this); + } + +} + + +class KumanosPupilEffect extends ReplacementEffectImpl { + + public KumanosPupilEffect() { + super(Duration.EndOfTurn, Outcome.Exile); + staticText = "If a creature dealt damage by {this} this turn would die, exile it instead"; + } + + public KumanosPupilEffect(final KumanosPupilEffect effect) { + super(effect); + } + + @Override + public KumanosPupilEffect copy() { + return new KumanosPupilEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent permanent = ((ZoneChangeEvent)event).getTarget(); + if (permanent != null) { + return permanent.moveToExile(null, "", source.getId(), game); + } + return false; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).isDiesEvent()) { + DamagedByWatcher watcher = + (DamagedByWatcher) game.getState().getWatchers().get("DamagedByWatcher", source.getSourceId()); + if (watcher != null) + return watcher.damagedCreatures.contains(event.getTargetId()); + } + return false; + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java index fc6dfbcaaa..cbf054a946 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java @@ -33,7 +33,6 @@ import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; @@ -42,25 +41,20 @@ import mage.abilities.condition.common.HasCounterCondition; import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.decorator.ConditionalContinousEffect; import mage.abilities.decorator.ConditionalOneShotEffect; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.continious.GainAbilitySourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.watchers.Watcher; import mage.watchers.common.CastFromHandWatcher; /** * @author Loki */ public class MyojinOfCleansingFire extends CardImpl { - private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("all other creatures"); + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other creatures"); static { filter.setAnother(true); diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java new file mode 100644 index 0000000000..13f115e0ab --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfInfiniteRage.java @@ -0,0 +1,89 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CastFromHandCondition; +import mage.abilities.condition.common.HasCounterCondition; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.DestroyAllEffect; +import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.counters.CounterType; +import mage.filter.common.FilterLandPermanent; +import mage.watchers.common.CastFromHandWatcher; + +/** + * @author LevelX + */ +public class MyojinOfInfiniteRage extends CardImpl { + + private static final FilterLandPermanent filter = new FilterLandPermanent("lands"); + + public MyojinOfInfiniteRage(UUID ownerId) { + super(ownerId, 181, "Myojin Of Infinite Rage", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{7}{R}{R}{R}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Spirit"); + + this.color.setRed(true); + this.power = new MageInt(7); + this.toughness = new MageInt(7); + + this.addWatcher(new CastFromHandWatcher()); + + // Myojin of Infinite Rage enters the battlefield with a divinity counter on it if you cast it from your hand. + this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.DIVINITY.createInstance()), new CastFromHandCondition(), ""), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand")); + // Myojin of Infinite Rage is indestructible as long as it has a divinity counter on it. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new ConditionalContinousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Constants.Duration.WhileOnBattlefield), + new HasCounterCondition(CounterType.DIVINITY), "{this} is indestructible as long as it has a divinity counter on it"))); + // Remove a divinity counter from Myojin of Infinite Rage: Destroy all lands. + this.addAbility(new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new DestroyAllEffect(filter), new RemoveCountersSourceCost(CounterType.DIVINITY.createInstance()))); + } + + public MyojinOfInfiniteRage(final MyojinOfInfiniteRage card) { + super(card); + } + + @Override + public MyojinOfInfiniteRage copy() { + return new MyojinOfInfiniteRage(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfLifesWeb.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfLifesWeb.java new file mode 100644 index 0000000000..571c2f2b72 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfLifesWeb.java @@ -0,0 +1,98 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.TargetController; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CastFromHandCondition; +import mage.abilities.condition.common.HasCounterCondition; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.PutOntoBattlefieldTargetEffect; +import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.target.common.TargetCardInHand; +import mage.watchers.common.CastFromHandWatcher; + +/** + * @author LevelX + */ +public class MyojinOfLifesWeb extends CardImpl { + + private static final FilterCard filter = new FilterCard("any number of creature cards from your hand"); + static { + filter.getCardType().add(CardType.CREATURE); + filter.setTargetOwner(TargetController.YOU); + } + + public MyojinOfLifesWeb(UUID ownerId) { + super(ownerId, 229, "Myojin of Lifes Web", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{6}{G}{G}{G}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Spirit"); + + this.color.setGreen(true); + this.power = new MageInt(8); + this.toughness = new MageInt(8); + + this.addWatcher(new CastFromHandWatcher()); + + // Myojin of Life's Web enters the battlefield with a divinity counter on it if you cast it from your hand. + this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.DIVINITY.createInstance()), new CastFromHandCondition(), ""), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand")); + // Myojin of Life's Web is indestructible as long as it has a divinity counter on it. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new ConditionalContinousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Constants.Duration.WhileOnBattlefield), + new HasCounterCondition(CounterType.DIVINITY), "{this} is indestructible as long as it has a divinity counter on it"))); + // Remove a divinity counter from Myojin of Life's Web: Put any number of creature cards from your hand onto the battlefield. + Ability ability = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new PutOntoBattlefieldTargetEffect(false), new RemoveCountersSourceCost(CounterType.DIVINITY.createInstance())); + ability.addTarget(new TargetCardInHand(0, Integer.MAX_VALUE, filter)); + this.addAbility(ability); + } + + public MyojinOfLifesWeb(final MyojinOfLifesWeb card) { + super(card); + } + + @Override + public MyojinOfLifesWeb copy() { + return new MyojinOfLifesWeb(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfNightsReach.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfNightsReach.java new file mode 100644 index 0000000000..7373203c50 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfNightsReach.java @@ -0,0 +1,119 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CastFromHandCondition; +import mage.abilities.condition.common.HasCounterCondition; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.counters.CounterType; +import mage.game.Game; +import mage.players.Player; +import mage.watchers.common.CastFromHandWatcher; + +/** + * @author LevelX + */ +public class MyojinOfNightsReach extends CardImpl { + + public MyojinOfNightsReach(UUID ownerId) { + super(ownerId, 126, "Myojin of Nights Reach", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{B}{B}{B}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Spirit"); + + this.color.setBlack(true); + this.power = new MageInt(5); + this.toughness = new MageInt(2); + + this.addWatcher(new CastFromHandWatcher()); + + // Myojin of Night's Reach enters the battlefield with a divinity counter on it if you cast it from your hand. + this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.DIVINITY.createInstance()), new CastFromHandCondition(), ""), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand")); + // Myojin of Night's Reach is indestructible as long as it has a divinity counter on it. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new ConditionalContinousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Constants.Duration.WhileOnBattlefield), + new HasCounterCondition(CounterType.DIVINITY), "{this} is indestructible as long as it has a divinity counter on it"))); + // Remove a divinity counter from Myojin of Night's Reach: Each opponent discards his or her hand. + Ability ability = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new MyojinOfNightsReachEffect(), new RemoveCountersSourceCost(CounterType.DIVINITY.createInstance())); + this.addAbility(ability); + } + + public MyojinOfNightsReach(final MyojinOfNightsReach card) { + super(card); + } + + @Override + public MyojinOfNightsReach copy() { + return new MyojinOfNightsReach(this); + } +} + +class MyojinOfNightsReachEffect extends OneShotEffect { + public MyojinOfNightsReachEffect() { + super(Constants.Outcome.Discard); + staticText = "Each opponent discards his or her hand"; + } + + public MyojinOfNightsReachEffect(final MyojinOfNightsReachEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + for (UUID opponentId : game.getOpponents(source.getControllerId())) { + Player opponent = game.getPlayer(opponentId); + for (Card c : opponent.getHand().getCards(game)) { + opponent.discard(c, source, game); + } + } + return true; + } + + @Override + public MyojinOfNightsReachEffect copy() { + return new MyojinOfNightsReachEffect(this); + } + +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfSeeingWinds.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfSeeingWinds.java new file mode 100644 index 0000000000..823ced55d5 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfSeeingWinds.java @@ -0,0 +1,96 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.TargetController; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.EntersBattlefieldAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CastFromHandCondition; +import mage.abilities.condition.common.HasCounterCondition; +import mage.abilities.costs.common.RemoveCountersSourceCost; +import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.effects.common.DrawCardControllerEffect; +import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.CardImpl; +import mage.counters.CounterType; +import mage.filter.FilterPermanent; +import mage.watchers.common.CastFromHandWatcher; + +/** + * @author LevelX + */ +public class MyojinOfSeeingWinds extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("permanent you control"); + static { + filter.setTargetOwner(TargetController.YOU); + } + + public MyojinOfSeeingWinds(UUID ownerId) { + super(ownerId, 75, "Myojin of Seeing Winds", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{7}{U}{U}{U}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Spirit"); + + this.color.setBlue(true); + this.power = new MageInt(3); + this.toughness = new MageInt(3); + + this.addWatcher(new CastFromHandWatcher()); + + // Myojin of Seeing Winds enters the battlefield with a divinity counter on it if you cast it from your hand. + this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.DIVINITY.createInstance()), new CastFromHandCondition(), ""), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand")); + // Myojin of Seeing Winds is indestructible as long as it has a divinity counter on it. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new ConditionalContinousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Constants.Duration.WhileOnBattlefield), + new HasCounterCondition(CounterType.DIVINITY), "{this} is indestructible as long as it has a divinity counter on it"))); + // Remove a divinity counter from Myojin of Seeing Winds: Draw a card for each permanent you control. + Ability ability = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new DrawCardControllerEffect(new PermanentsOnBattlefieldCount(filter, 1)), new RemoveCountersSourceCost(CounterType.DIVINITY.createInstance())); + this.addAbility(ability); + } + + public MyojinOfSeeingWinds(final MyojinOfSeeingWinds card) { + super(card); + } + + @Override + public MyojinOfSeeingWinds copy() { + return new MyojinOfSeeingWinds(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/OniPossession.java b/Mage.Sets/src/mage/sets/championsofkamigawa/OniPossession.java new file mode 100644 index 0000000000..0e59ecf022 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/OniPossession.java @@ -0,0 +1,96 @@ +/* + * 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.championsofkamigawa; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import mage.Constants; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.effects.common.SacrificeTargetEffect; +import mage.abilities.effects.common.continious.BoostEnchantedEffect; +import mage.abilities.effects.common.continious.GainAbilityAttachedEffect; +import mage.abilities.effects.common.continious.SetCardSubtypeAttachedEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.abilities.keyword.TrampleAbility; +import mage.cards.CardImpl; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.target.TargetPermanent; +import mage.target.common.TargetControlledCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; + +/** + * + * @author LevelX + */ +public class OniPossession extends CardImpl { + + private static final List setSubtypes = new ArrayList(); + static { + setSubtypes.add("Demon"); + setSubtypes.add("Spirit"); + } + + public OniPossession(UUID ownerId) { + super(ownerId, 135, "Oni Possession", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Aura"); + + this.color.setBlack(true); + // Enchant creature + TargetPermanent auraTarget = new TargetCreaturePermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Constants.Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + // At the beginning of your upkeep, sacrifice a creature. + Ability ability2 = new BeginningOfUpkeepTriggeredAbility(new SacrificeTargetEffect("sacrifice a creature"), Constants.TargetController.YOU, false); + ability2.addTarget(new TargetControlledCreaturePermanent(1,1, new FilterControlledCreaturePermanent(),false, true)); + this.addAbility(ability2); + // Enchanted creature gets +3/+3 and has trample. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Constants.Duration.WhileOnBattlefield))); + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new GainAbilityAttachedEffect(TrampleAbility.getInstance(), Constants.AttachmentType.AURA))); + // Enchanted creature is a Demon Spirit. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(setSubtypes, Constants.Duration.WhileOnBattlefield, Constants.AttachmentType.AURA))); + } + + public OniPossession(final OniPossession card) { + super(card); + } + + @Override + public OniPossession copy() { + return new OniPossession(this); + } +} diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/PainwrackerOni.java b/Mage.Sets/src/mage/sets/championsofkamigawa/PainwrackerOni.java new file mode 100644 index 0000000000..7b26a995fb --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/PainwrackerOni.java @@ -0,0 +1,120 @@ +/* + * 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.championsofkamigawa; + +import java.util.UUID; +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.Constants.Zone; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.SacrificeTargetEffect; +import mage.abilities.keyword.FearAbility; +import mage.cards.CardImpl; +import mage.filter.FilterPermanent; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.GameEvent.EventType; +import mage.target.common.TargetControlledCreaturePermanent; + +/** + * + * @author LevelX + */ +public class PainwrackerOni extends CardImpl { + + public PainwrackerOni (UUID ownerId) { + super(ownerId, 136, "Painwracker Oni", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Demon"); + this.subtype.add("Spirit"); + this.color.setBlack(true); + this.power = new MageInt(5); + this.toughness = new MageInt(4); + + // Fear (This creature can't be blocked except by artifact creatures and/or black creatures.) + this.addAbility(FearAbility.getInstance()); + // At the beginning of your upkeep, sacrifice a creature if you don't control an Ogre. + Ability ability = new PainwrackerOniTriggeredAbility1(new SacrificeTargetEffect()); + ability.addTarget(new TargetControlledCreaturePermanent()); + this.addAbility(ability); + } + + public PainwrackerOni (final PainwrackerOni card) { + super(card); + } + + @Override + public PainwrackerOni copy() { + return new PainwrackerOni(this); + } + +} + +class PainwrackerOniTriggeredAbility1 extends TriggeredAbilityImpl { + + private final static FilterPermanent filter = new FilterPermanent(); + + static { + filter.getSubtype().add("Ogre"); + } + + public PainwrackerOniTriggeredAbility1(Effect effect) { + super(Zone.BATTLEFIELD, effect, false); + } + + public PainwrackerOniTriggeredAbility1(final PainwrackerOniTriggeredAbility1 ability) { + super(ability); + } + + @Override + public PainwrackerOniTriggeredAbility1 copy() { + return new PainwrackerOniTriggeredAbility1(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == EventType.UPKEEP_STEP_PRE && event.getPlayerId().equals(this.controllerId)) { + return true; + } + return false; + } + + @Override + public boolean checkInterveningIfClause(Game game) { + return game.getBattlefield().countAll(filter, this.controllerId) < 1; + } + + @Override + public String getRule() { + return "At the beginning of your upkeep, sacrifice a creature if you don't control an Ogre."; + } +} \ No newline at end of file diff --git a/Mage/src/mage/abilities/dynamicvalue/common/CountersCount.java b/Mage/src/mage/abilities/dynamicvalue/common/CountersCount.java index 061ca5bd2b..68f68e9859 100644 --- a/Mage/src/mage/abilities/dynamicvalue/common/CountersCount.java +++ b/Mage/src/mage/abilities/dynamicvalue/common/CountersCount.java @@ -9,13 +9,20 @@ import mage.game.permanent.Permanent; public class CountersCount implements DynamicValue { private CounterType counter; - + private boolean negative = false; + public CountersCount(CounterType counter) { this.counter = counter; } + public CountersCount(CounterType counter, boolean negative) { + this.counter = counter; + this.negative = negative; + } + public CountersCount(final CountersCount countersCount) { this.counter = countersCount.counter; + this.negative = countersCount.negative; } @Override @@ -26,7 +33,7 @@ public class CountersCount implements DynamicValue { p = (Permanent) game.getLastKnownInformation(sourceAbility.getSourceId(), Constants.Zone.BATTLEFIELD); } if (p != null) { - return p.getCounters().getCount(counter); + return (negative ? p.getCounters().getCount(counter)*-1: p.getCounters().getCount(counter)) ; } return 0; } @@ -38,7 +45,7 @@ public class CountersCount implements DynamicValue { @Override public String toString() { - return "1"; + return (negative ?"-1":"1"); } @Override diff --git a/Mage/src/mage/abilities/effects/common/DrawCardControllerEffect.java b/Mage/src/mage/abilities/effects/common/DrawCardControllerEffect.java index e0d5312b36..f4591a22cd 100644 --- a/Mage/src/mage/abilities/effects/common/DrawCardControllerEffect.java +++ b/Mage/src/mage/abilities/effects/common/DrawCardControllerEffect.java @@ -31,6 +31,7 @@ package mage.abilities.effects.common; import mage.Constants.Outcome; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; import mage.game.Game; @@ -75,12 +76,13 @@ public class DrawCardControllerEffect extends OneShotEffect 0) { sb.append(" for each "); } diff --git a/Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java b/Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java new file mode 100644 index 0000000000..b2752ebe96 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/PutOntoBattlefieldTargetEffect.java @@ -0,0 +1,104 @@ +/* + * 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; + +import mage.Constants.Outcome; +import mage.Constants.Zone; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.game.Game; +import mage.players.Player; + +import java.util.UUID; + +/** + * @author LevelX + */ +public class PutOntoBattlefieldTargetEffect extends OneShotEffect { + + boolean tapped; + + public PutOntoBattlefieldTargetEffect(boolean tapped) { + super(Outcome.PutCreatureInPlay); + this.tapped = tapped; + } + + public PutOntoBattlefieldTargetEffect(final PutOntoBattlefieldTargetEffect effect) { + super(effect); + this.tapped = effect.tapped; + } + + @Override + public PutOntoBattlefieldTargetEffect copy() { + return new PutOntoBattlefieldTargetEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + boolean result = false; + for (UUID targetId : targetPointer.getTargets(source)) { + Card card = game.getCard(targetId); + if (card != null) { + + switch (game.getState().getZone(targetId)) { + case GRAVEYARD: + for (Player player : game.getPlayers().values()) { + if (player.getGraveyard().contains(card.getId())) { + player.getGraveyard().remove(card); + result |= card.moveToZone(Zone.BATTLEFIELD, source.getId(), game, tapped); + } + } + case HAND: + for (Player player : game.getPlayers().values()) { + if (player.getHand().contains(card.getId())) { + player.getHand().remove(card); + result |= card.moveToZone(Zone.BATTLEFIELD, source.getId(), game, tapped); + } + } + } + } + } + return result; + } + + @Override + public String getText(Mode mode) { + StringBuilder sb = new StringBuilder(); + sb.append("Put "); + if (mode.getTargets().get(0).getMaxNumberOfTargets() == 0) { + sb.append("any number of "); + } + sb.append(mode.getTargets().get(0).getTargetName()); + sb.append(tapped ? "tapped" : "").append(" onto the battlefield"); + return sb.toString(); + + } +} diff --git a/Mage/src/mage/abilities/effects/common/SacrificeTargetEffect.java b/Mage/src/mage/abilities/effects/common/SacrificeTargetEffect.java index c2562546cf..d074289990 100644 --- a/Mage/src/mage/abilities/effects/common/SacrificeTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/SacrificeTargetEffect.java @@ -47,6 +47,11 @@ public class SacrificeTargetEffect extends OneShotEffect super(Outcome.Sacrifice); } + public SacrificeTargetEffect(String text) { + this(); + staticText = text; + } + public SacrificeTargetEffect(final SacrificeTargetEffect effect) { super(effect); } @@ -71,10 +76,13 @@ public class SacrificeTargetEffect extends OneShotEffect @Override public String getText(Mode mode) { - if (mode.getTargets().get(0).getNumberOfTargets() == 1) - return "The controller of target " + mode.getTargets().get(0).getTargetName() + " sacrifices it"; - else - return "The controller of " + mode.getTargets().get(0).getNumberOfTargets() + " target " + mode.getTargets().get(0).getTargetName() + " sacrifices it"; - } + if (staticText.equals("")) { + if (mode.getTargets().get(0).getNumberOfTargets() == 1) + return "The controller of target " + mode.getTargets().get(0).getTargetName() + " sacrifices it"; + else + return "The controller of " + mode.getTargets().get(0).getNumberOfTargets() + " target " + mode.getTargets().get(0).getTargetName() + " sacrifices it"; + } + return staticText; + } } diff --git a/Mage/src/mage/abilities/effects/common/continious/SetCardSubtypeAttachedEffect.java b/Mage/src/mage/abilities/effects/common/continious/SetCardSubtypeAttachedEffect.java index 28485e37c7..8911b4243e 100644 --- a/Mage/src/mage/abilities/effects/common/continious/SetCardSubtypeAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/SetCardSubtypeAttachedEffect.java @@ -27,6 +27,8 @@ */ package mage.abilities.effects.common.continious; +import java.util.ArrayList; +import java.util.List; import mage.Constants; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; @@ -38,19 +40,26 @@ import mage.game.permanent.Permanent; */ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl { - private String setSubtype; + private List setSubtypes = new ArrayList(); private Constants.AttachmentType attachmentType; public SetCardSubtypeAttachedEffect(String setSubtype, Constants.Duration duration, Constants.AttachmentType attachmentType) { super(duration, Constants.Layer.TypeChangingEffects_4, Constants.SubLayer.NA, Constants.Outcome.Benefit); - this.setSubtype = setSubtype; + this.setSubtypes.add(setSubtype); this.attachmentType = attachmentType; - setText(); + setText(); + } + + public SetCardSubtypeAttachedEffect(List setSubtypes, Constants.Duration duration, Constants.AttachmentType attachmentType) { + super(duration, Constants.Layer.TypeChangingEffects_4, Constants.SubLayer.NA, Constants.Outcome.Benefit); + this.setSubtypes.addAll(setSubtypes); + this.attachmentType = attachmentType; + setText(); } public SetCardSubtypeAttachedEffect(final SetCardSubtypeAttachedEffect effect) { super(effect); - this.setSubtype = effect.setSubtype; + this.setSubtypes = effect.setSubtypes; this.attachmentType = effect.attachmentType; } @@ -61,7 +70,7 @@ public class SetCardSubtypeAttachedEffect extends ContinuousEffectImpl