diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/AkkiLavarunner.java b/Mage.Sets/src/mage/sets/championsofkamigawa/AkkiLavarunner.java index f8bd424494b..d9f2e48ac87 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/AkkiLavarunner.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/AkkiLavarunner.java @@ -1,5 +1,6 @@ package mage.sets.championsofkamigawa; +import java.util.UUID; import mage.Constants; import mage.MageInt; import mage.ObjectColor; @@ -11,7 +12,6 @@ import mage.abilities.decorator.ConditionalContinousEffect; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.CopyTokenEffect; import mage.abilities.effects.common.FlipSourceEffect; -import mage.abilities.effects.common.UntapAllLandsControllerEffect; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.ProtectionAbility; import mage.cards.Card; @@ -23,8 +23,6 @@ import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; import mage.game.permanent.token.Token; -import java.util.UUID; - /** * @author Loki */ diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java b/Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java index 336983b76ec..39adb244d09 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/BloodthirstyOgre.java @@ -76,7 +76,8 @@ public class BloodthirstyOgre extends CardImpl { 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. DynamicValue devotionCounters = new SignInversionDynamicValue(new CountersCount(CounterType.DEVOTION)); - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,new BoostTargetEffect(devotionCounters,devotionCounters, Duration.EndOfTurn),new TapSourceCost()); + Ability ability; + ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(devotionCounters,devotionCounters, Duration.EndOfTurn, true),new TapSourceCost()); ability.addCost(new ControlPermanentCost(filter)); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/KashiTribeReaver.java b/Mage.Sets/src/mage/sets/championsofkamigawa/KashiTribeReaver.java new file mode 100644 index 00000000000..d44dffb56ce --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/KashiTribeReaver.java @@ -0,0 +1,77 @@ +/* + * 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.common.DealsCombatDamageToACreatureTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.RegenerateSourceEffect; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardImpl; + +/** + * + * @author LevelX + */ +public class KashiTribeReaver extends CardImpl { + + public KashiTribeReaver(UUID ownerId) { + super(ownerId, 220, "Kashi-Tribe Reaver", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(3); + this.toughness = new MageInt(2); + + // Whenever Kashi-Tribe Reaver deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step. + Ability ability; + ability = new DealsCombatDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), false, true); + ability.addEffect(new SkipNextUntapTargetEffect("and it")); + this.addAbility(ability); + // {1}{G}: Regenerate Kashi-Tribe Reaver. + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{G}"))); + } + + public KashiTribeReaver(final KashiTribeReaver card) { + super(card); + } + + @Override + public KashiTribeReaver copy() { + return new KashiTribeReaver(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/KashiTribeWarriors.java b/Mage.Sets/src/mage/sets/championsofkamigawa/KashiTribeWarriors.java new file mode 100644 index 00000000000..cfe32a1f6d6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/KashiTribeWarriors.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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToACreatureTriggeredAbility; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardImpl; + +/** + * + * @author LevelX + */ +public class KashiTribeWarriors extends CardImpl { + + public KashiTribeWarriors(UUID ownerId) { + super(ownerId, 221, "Kashi-Tribe Warriors", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(2); + this.toughness = new MageInt(4); + + // Whenever Kashi-Tribe Reaver deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step. + Ability ability; + ability = new DealsCombatDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), false, true); + ability.addEffect(new SkipNextUntapTargetEffect("and it")); + this.addAbility(ability); + } + + public KashiTribeWarriors(final KashiTribeWarriors card) { + super(card); + } + + @Override + public KashiTribeWarriors copy() { + return new KashiTribeWarriors(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java b/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java index d48ff522b8e..c42806d12d3 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/KondasBanner.java @@ -69,10 +69,10 @@ public class KondasBanner extends CardImpl { this.subtype.add("Equipment"); // Creatures that share a color with equipped creature get +1/+1. - this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new KodasBannerColorBoostEffect())); + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new KondasBannerColorBoostEffect())); // Creatures that share a creature type with equipped creature get +1/+1. - this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new KodasBannerTypeBoostEffect())); + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new KondasBannerTypeBoostEffect())); // Konda's Banner can be attached only to a legendary creature. // Equip {2} @@ -93,16 +93,16 @@ public class KondasBanner extends CardImpl { } } -class KodasBannerTypeBoostEffect extends BoostAllEffect { +class KondasBannerTypeBoostEffect extends BoostAllEffect { private static final String effectText = "Creatures that share a creature type with equipped creature get +1/+1"; - KodasBannerTypeBoostEffect() { + KondasBannerTypeBoostEffect() { super(1,1, Constants.Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false); staticText = effectText; } - KodasBannerTypeBoostEffect(KodasBannerTypeBoostEffect effect) { + KondasBannerTypeBoostEffect(KondasBannerTypeBoostEffect effect) { super(effect); } @@ -113,38 +113,40 @@ class KodasBannerTypeBoostEffect extends BoostAllEffect { if (equipment != null && equipment.getAttachedTo() != null) { Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo()); - for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { - if (CardUtil.shareSubtypes(perm, equipedCreature) || perm.getAbilities().contains(ChangelingAbility.getInstance())) { - if (!this.affectedObjectsSet || objects.contains(perm.getId())) { - perm.addPower(power.calculate(game, source)); - perm.addToughness(toughness.calculate(game, source)); - } - - } - } - return true; + if (equipedCreature != null) { + for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { + if (CardUtil.shareSubtypes(perm, equipedCreature) || perm.getAbilities().contains(ChangelingAbility.getInstance())) { + if (!this.affectedObjectsSet || objects.contains(perm.getId())) { + perm.addPower(power.calculate(game, source)); + perm.addToughness(toughness.calculate(game, source)); + } + + } + } + return true; + } } return false; } @Override - public KodasBannerTypeBoostEffect copy() { - return new KodasBannerTypeBoostEffect(this); + public KondasBannerTypeBoostEffect copy() { + return new KondasBannerTypeBoostEffect(this); } } -class KodasBannerColorBoostEffect extends BoostAllEffect { +class KondasBannerColorBoostEffect extends BoostAllEffect { private static final String effectText = "Creatures that share a color with equipped creature get +1/+1."; - KodasBannerColorBoostEffect() { + KondasBannerColorBoostEffect() { super(1,1, Constants.Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false); staticText = effectText; } - KodasBannerColorBoostEffect(KodasBannerColorBoostEffect effect) { + KondasBannerColorBoostEffect(KondasBannerColorBoostEffect effect) { super(effect); } @@ -170,8 +172,8 @@ class KodasBannerColorBoostEffect extends BoostAllEffect { } @Override - public KodasBannerColorBoostEffect copy() { - return new KodasBannerColorBoostEffect(this); + public KondasBannerColorBoostEffect copy() { + return new KondasBannerColorBoostEffect(this); } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MatsuTribeDecoy.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MatsuTribeDecoy.java new file mode 100644 index 00000000000..d3bd058d793 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MatsuTribeDecoy.java @@ -0,0 +1,82 @@ +/* + * 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.common.DealsCombatDamageToACreatureTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.MustBlockSourceTargetEffect; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardImpl; +import mage.filter.common.FilterCreaturePermanent; +import mage.target.common.TargetCreaturePermanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX + */ +public class MatsuTribeDecoy extends CardImpl { + + public MatsuTribeDecoy(UUID ownerId) { + super(ownerId, 227, "Matsu-Tribe Decoy", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(1); + this.toughness = new MageInt(3); + + // {2}{G}: Target creature blocks Matsu-Tribe Decoy this turn if able. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MustBlockSourceTargetEffect(), new ManaCostsImpl("{2}{G}")); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + // Whenever Kashi-Tribe Reaver deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step. + Ability ability2; + ability2 = new DealsCombatDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), false, true); + ability2.addEffect(new SkipNextUntapTargetEffect("and it")); + this.addAbility(ability2); + } + + public MatsuTribeDecoy(final MatsuTribeDecoy card) { + super(card); + } + + @Override + public MatsuTribeDecoy copy() { + return new MatsuTribeDecoy(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/OrochiRanger.java b/Mage.Sets/src/mage/sets/championsofkamigawa/OrochiRanger.java new file mode 100644 index 00000000000..36425bbb5a6 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/OrochiRanger.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.championsofkamigawa; + +import java.util.UUID; + +import mage.Constants.CardType; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.DealsCombatDamageToACreatureTriggeredAbility; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.cards.CardImpl; + +/** + * + * @author LevelX + */ +public class OrochiRanger extends CardImpl { + + public OrochiRanger(UUID ownerId) { + super(ownerId, 235, "Orochi Ranger", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{G}"); + this.expansionSetCode = "CHK"; + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // Whenever Orochi Ranger deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step. + Ability ability; + ability = new DealsCombatDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), false, true); + ability.addEffect(new SkipNextUntapTargetEffect("and it")); + this.addAbility(ability); + } + + public OrochiRanger(final OrochiRanger card) { + super(card); + } + + @Override + public OrochiRanger copy() { + return new OrochiRanger(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/ShisatoWhisperingHunter.java b/Mage.Sets/src/mage/sets/championsofkamigawa/ShisatoWhisperingHunter.java new file mode 100644 index 00000000000..f0afaea6dd9 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/ShisatoWhisperingHunter.java @@ -0,0 +1,84 @@ +/* + * 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.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; +import mage.abilities.effects.common.SacrificeEffect; +import mage.abilities.effects.common.SkipNextPlayerUntapStepEffect; +import mage.cards.CardImpl; +import mage.filter.common.FilterControlledCreaturePermanent; + +/** + * + * @author LevelX + */ +public class ShisatoWhisperingHunter extends CardImpl { + + + private final static FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a Snake"); + + static { + filter.getSubtype().add("Snake"); + filter.setTargetController(TargetController.YOU); + } + + public ShisatoWhisperingHunter(UUID ownerId) { + super(ownerId, 242, "Shisato, Whispering Hunter", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{G}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // At the beginning of your upkeep, sacrifice a Snake. +// this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ShisatoWhisperinSacrificeEffect(filter, 1,""), Constants.TargetController.YOU, false)); + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeEffect(filter, 1,""), Constants.TargetController.YOU, false)); + // Whenever Shisato, Whispering Hunter deals combat damage to a player, that player skips his or her next untap step. + this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new SkipNextPlayerUntapStepEffect("that"),false, true)); +// this.addAbility(new ShisatoWhisperingHunterAbility()); + } + + public ShisatoWhisperingHunter(final ShisatoWhisperingHunter card) { + super(card); + } + + @Override + public ShisatoWhisperingHunter copy() { + return new ShisatoWhisperingHunter(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/SosukeSonOfSeshiro.java b/Mage.Sets/src/mage/sets/championsofkamigawa/SosukeSonOfSeshiro.java new file mode 100644 index 00000000000..248eef79a79 --- /dev/null +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/SosukeSonOfSeshiro.java @@ -0,0 +1,158 @@ +/* + * 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.Outcome; +import mage.Constants.Rarity; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.effects.common.continious.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.filter.Filter; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.game.events.DamagedCreatureEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author LevelX + */ +public class SosukeSonOfSeshiro extends CardImpl { + + private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("Snake creatures"); + + static { + filter.getSubtype().add("Snake"); + filter.setScopeSubtype(Filter.ComparisonScope.Any); + } + + public SosukeSonOfSeshiro(UUID ownerId) { + super(ownerId, 244, "Sosuke, Son of Seshiro", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.expansionSetCode = "CHK"; + this.supertype.add("Legendary"); + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(3); + this.toughness = new MageInt(4); + + // Other Snake creatures you control get +1/+0. + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new BoostControlledEffect(1, 0, Constants.Duration.WhileOnBattlefield, filter, true))); + // Whenever a Warrior you control deals combat damage to a creature, destroy that creature at end of combat. + this.addAbility(new SosukeSonOfSeshiroTriggeredAbility()); + } + + public SosukeSonOfSeshiro(final SosukeSonOfSeshiro card) { + super(card); + } + + @Override + public SosukeSonOfSeshiro copy() { + return new SosukeSonOfSeshiro(this); + } +} + +class SosukeSonOfSeshiroTriggeredAbility extends TriggeredAbilityImpl { + + SosukeSonOfSeshiroTriggeredAbility() { + super(Constants.Zone.BATTLEFIELD, new SosukeSonOfSeshiroEffect()); + } + + SosukeSonOfSeshiroTriggeredAbility(final SosukeSonOfSeshiroTriggeredAbility ability) { + super(ability); + } + + @Override + public SosukeSonOfSeshiroTriggeredAbility copy() { + return new SosukeSonOfSeshiroTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event instanceof DamagedCreatureEvent) { + if (((DamagedCreatureEvent) event).isCombatDamage()) { + Permanent sourceCreature = game.getPermanent(event.getSourceId()); + Permanent targetCreature = game.getPermanent(event.getTargetId()); + if (sourceCreature != null && sourceCreature.getControllerId().equals(this.getControllerId()) + && targetCreature != null && sourceCreature.getSubtype().contains("Warrior")) { + this.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); + return true; + } + } + } + return false; + } + + @Override + public String getRule() { + return "Whenever a Warrior you control deals combat damage to a creature, destroy that creature at end of combat."; + } +} + +class SosukeSonOfSeshiroEffect extends OneShotEffect { + + SosukeSonOfSeshiroEffect() { + super(Outcome.DestroyPermanent); + staticText = "destroy that creature at end of combat"; + } + + SosukeSonOfSeshiroEffect(final SosukeSonOfSeshiroEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent targetCreature = game.getPermanent(this.getTargetPointer().getFirst(source)); + if (targetCreature != null) { + AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect()); + delayedAbility.setSourceId(source.getSourceId()); + delayedAbility.setControllerId(source.getControllerId()); + delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(targetCreature.getId())); + game.addDelayedTriggeredAbility(delayedAbility); + return true; + } + return false; + } + + @Override + public SosukeSonOfSeshiroEffect copy() { + return new SosukeSonOfSeshiroEffect(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/StrengthOfCedars.java b/Mage.Sets/src/mage/sets/championsofkamigawa/StrengthOfCedars.java index 5b3b8c790be..75c35cb831a 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/StrengthOfCedars.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/StrengthOfCedars.java @@ -59,7 +59,7 @@ public class StrengthOfCedars extends CardImpl { this.subtype.add("Arcane"); this.color.setGreen(true); this.getSpellAbility().addEffect(new BoostTargetEffect(new PermanentsOnBattlefieldCount(filter), - new PermanentsOnBattlefieldCount(filter), Constants.Duration.EndOfTurn)); + new PermanentsOnBattlefieldCount(filter), Constants.Duration.EndOfTurn, true)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/YoseiTheMorningStar.java b/Mage.Sets/src/mage/sets/championsofkamigawa/YoseiTheMorningStar.java index 96601a1e9e3..2c2e8bdb7d3 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/YoseiTheMorningStar.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/YoseiTheMorningStar.java @@ -28,23 +28,20 @@ package mage.sets.championsofkamigawa; import java.util.UUID; -import mage.Constants; import mage.Constants.CardType; import mage.Constants.Outcome; -import mage.Constants.PhaseStep; import mage.Constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.DiesTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.SkipNextPlayerUntapStepEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.game.turn.TurnMod; import mage.players.Player; import mage.target.Target; import mage.target.TargetPermanent; @@ -69,7 +66,7 @@ public class YoseiTheMorningStar extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); // When Yosei, the Morning Star dies, target player skips his or her next untap step. Tap up to five target permanents that player controls. - Ability ability = new DiesTriggeredAbility(new SkipNextUntapStepTargetEffect()); + Ability ability = new DiesTriggeredAbility(new SkipNextPlayerUntapStepEffect()); ability.addTarget(new TargetPlayer()); ability.addTarget(new YoseiTheMorningStarTarget()); ability.addEffect(new YoseiTheMorningStarTapEffect()); @@ -86,33 +83,6 @@ public class YoseiTheMorningStar extends CardImpl { } } -class SkipNextUntapStepTargetEffect extends OneShotEffect { - - public SkipNextUntapStepTargetEffect() { - super(Constants.Outcome.Detriment); - staticText = "target player skips his or her next untap step"; - } - - public SkipNextUntapStepTargetEffect(SkipNextUntapStepTargetEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - UUID playerId = source.getFirstTarget(); - if (playerId != null) { - game.getState().getTurnMods().add(new TurnMod(playerId, PhaseStep.UNTAP)); - return true; - } - return false; - } - - @Override - public SkipNextUntapStepTargetEffect copy() { - return new SkipNextUntapStepTargetEffect(); - } -} - class YoseiTheMorningStarTarget extends TargetPermanent { public YoseiTheMorningStarTarget() { diff --git a/Mage.Sets/src/mage/sets/conflux/DragDown.java b/Mage.Sets/src/mage/sets/conflux/DragDown.java index cc9bf6af9f8..13045084e41 100644 --- a/Mage.Sets/src/mage/sets/conflux/DragDown.java +++ b/Mage.Sets/src/mage/sets/conflux/DragDown.java @@ -49,7 +49,7 @@ public class DragDown extends CardImpl { this.color.setBlack(true); // Domain - Target creature gets -1/-1 until end of turn for each basic land type among lands you control. - this.getSpellAbility().addEffect(new BoostTargetEffect(new DomainValue(-1), new DomainValue(-1), Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new BoostTargetEffect(new DomainValue(-1), new DomainValue(-1), Duration.EndOfTurn, true)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/sets/conflux/MightOfAlara.java b/Mage.Sets/src/mage/sets/conflux/MightOfAlara.java index a132de6be9e..aad1baf79af 100644 --- a/Mage.Sets/src/mage/sets/conflux/MightOfAlara.java +++ b/Mage.Sets/src/mage/sets/conflux/MightOfAlara.java @@ -50,7 +50,7 @@ public class MightOfAlara extends CardImpl { this.color.setGreen(true); // Domain - Target creature gets +1/+1 until end of turn for each basic land type among lands you control. - this.getSpellAbility().addEffect(new BoostTargetEffect(new DomainValue(), new DomainValue(), Constants.Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new BoostTargetEffect(new DomainValue(), new DomainValue(), Constants.Duration.EndOfTurn, true)); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); } diff --git a/Mage.Sets/src/mage/sets/eventide/CreakwoodGhoul.java b/Mage.Sets/src/mage/sets/eventide/CreakwoodGhoul.java index 7db5986ee80..7fbb5b3a72c 100644 --- a/Mage.Sets/src/mage/sets/eventide/CreakwoodGhoul.java +++ b/Mage.Sets/src/mage/sets/eventide/CreakwoodGhoul.java @@ -28,7 +28,6 @@ package mage.sets.eventide; import java.util.UUID; - import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; @@ -41,6 +40,7 @@ import mage.abilities.effects.common.GainLifeEffect; import mage.cards.CardImpl; import mage.target.common.TargetCardInGraveyard; + /** * * @author Loki diff --git a/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java b/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java index 4b5a456d720..f3811f9003b 100644 --- a/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java +++ b/Mage.Sets/src/mage/sets/innistrad/DearlyDeparted.java @@ -27,6 +27,8 @@ */ package mage.sets.innistrad; + +import java.util.UUID; import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; @@ -40,14 +42,8 @@ import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.counters.CounterType; import mage.filter.Filter; -import mage.filter.FilterPermanent; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.common.FilterControlledPermanent; -import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreaturePermanent; -import java.util.UUID; - /** * @author nantuko */ diff --git a/Mage.Sets/src/mage/sets/innistrad/ElderOfLaurels.java b/Mage.Sets/src/mage/sets/innistrad/ElderOfLaurels.java index ab5647abb91..62e66500cf9 100644 --- a/Mage.Sets/src/mage/sets/innistrad/ElderOfLaurels.java +++ b/Mage.Sets/src/mage/sets/innistrad/ElderOfLaurels.java @@ -60,7 +60,7 @@ public class ElderOfLaurels extends CardImpl { // {3}{G}: Target creature gets +X/+X until end of turn, where X is the number of creatures you control. PermanentsOnBattlefieldCount amount = new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent()); SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, - new BoostTargetEffect(amount, amount, Duration.EndOfTurn), + new BoostTargetEffect(amount, amount, Duration.EndOfTurn, true), new ManaCostsImpl("{3}{G}")); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/sets/mirrodin/ClockworkBeetle.java b/Mage.Sets/src/mage/sets/mirrodin/ClockworkBeetle.java index fb8e36a5721..73778208c2e 100644 --- a/Mage.Sets/src/mage/sets/mirrodin/ClockworkBeetle.java +++ b/Mage.Sets/src/mage/sets/mirrodin/ClockworkBeetle.java @@ -58,7 +58,7 @@ public class ClockworkBeetle extends CardImpl { this.power = new MageInt(0); this.toughness = new MageInt(0); this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)), "{this} enters the battlefield with two +1/+1 counters on it")); - this.addAbility(new AttacksOrBlocksTriggeredAbility(new ClockworkCondorEffect(), false)); + this.addAbility(new AttacksOrBlocksTriggeredAbility(new ClockworkBeetleEffect(), false)); } public ClockworkBeetle(final ClockworkBeetle card) { @@ -87,8 +87,8 @@ class ClockworkBeetleEffect extends OneShotEffect { if (p != null) { AtTheEndOfCombatDelayedTriggeredAbility ability = new AtTheEndOfCombatDelayedTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P1.createInstance())); ability.setSourceId(source.getSourceId()); - ability.setControllerId(source.getControllerId()); - game.addDelayedTriggeredAbility(ability); + ability.setControllerId(source.getControllerId()); + game.addDelayedTriggeredAbility(ability); } return false; } diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/MightOfTheMasses.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/MightOfTheMasses.java index f933e29c530..4c3de2144a7 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/MightOfTheMasses.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/MightOfTheMasses.java @@ -51,7 +51,7 @@ public class MightOfTheMasses extends CardImpl { PermanentsOnBattlefieldCount value = new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addEffect(new BoostTargetEffect(value, value, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new BoostTargetEffect(value, value, Duration.EndOfTurn, true)); } public MightOfTheMasses(final MightOfTheMasses card) { diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/KashiTribeElite.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/KashiTribeElite.java new file mode 100644 index 00000000000..1ece33843b0 --- /dev/null +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/KashiTribeElite.java @@ -0,0 +1,91 @@ +/* + * 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.saviorsofkamigawa; + +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.DealsCombatDamageToACreatureTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continious.GainAbilityControlledEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.filter.Filter; +import mage.filter.common.FilterControlledPermanent; + +/** + * + * @author LevelX + */ +public class KashiTribeElite extends CardImpl { + + private final static FilterControlledPermanent filter = new FilterControlledPermanent("Legendary Snakes"); + + static { + filter.getSupertype().add("Legendary"); + filter.setScopeSupertype(Filter.ComparisonScope.Any); + filter.getSubtype().add("Snake"); + filter.setScopeSubtype(Filter.ComparisonScope.Any); + } + + public KashiTribeElite(UUID ownerId) { + super(ownerId, 135, "Kashi-Tribe Elite", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{G}{G}"); + this.expansionSetCode = "SOK"; + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(2); + this.toughness = new MageInt(3); + + // Legendary Snakes you control have shroud. (They can't be the targets of spells or abilities.) + this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new GainAbilityControlledEffect(ShroudAbility.getInstance(), Constants.Duration.WhileOnBattlefield, filter, false))); + + // Whenever Kashi-Tribe Elite deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step. + Ability ability; + ability = new DealsCombatDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), false, true); + ability.addEffect(new SkipNextUntapTargetEffect("and it")); + this.addAbility(ability); + + } + + public KashiTribeElite(final KashiTribeElite card) { + super(card); + } + + @Override + public KashiTribeElite copy() { + return new KashiTribeElite(this); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/saviorsofkamigawa/MatsuTribeBirdstalker.java b/Mage.Sets/src/mage/sets/saviorsofkamigawa/MatsuTribeBirdstalker.java new file mode 100644 index 00000000000..df6983909a4 --- /dev/null +++ b/Mage.Sets/src/mage/sets/saviorsofkamigawa/MatsuTribeBirdstalker.java @@ -0,0 +1,86 @@ +/* + * 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.saviorsofkamigawa; + +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.DealsCombatDamageToACreatureTriggeredAbility; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; +import mage.abilities.effects.common.TapTargetEffect; +import mage.abilities.effects.common.continious.GainAbilityControlledEffect; +import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.keyword.ReachAbility; +import mage.abilities.keyword.ShroudAbility; +import mage.cards.CardImpl; +import mage.filter.Filter; +import mage.filter.common.FilterControlledPermanent; + +/** + * + * @author LevelX + */ +public class MatsuTribeBirdstalker extends CardImpl { + + public MatsuTribeBirdstalker(UUID ownerId) { + super(ownerId, 137, "Matsu-Tribe Birdstalker", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}{G}"); + this.expansionSetCode = "SOK"; + this.subtype.add("Snake"); + this.subtype.add("Warrior"); + + this.color.setGreen(true); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // Whenever Kashi-Tribe Elite deals combat damage to a creature, tap that creature and it doesn't untap during its controller's next untap step. + Ability ability; + ability = new DealsCombatDamageToACreatureTriggeredAbility(new TapTargetEffect("that creature"), false, true); + ability.addEffect(new SkipNextUntapTargetEffect("and it")); + this.addAbility(ability); + + // {G}: Matsu-Tribe Birdstalker gains reach until end of turn. (It can block creatures with flying.) + this.addAbility(new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, + new GainAbilitySourceEffect(ReachAbility.getInstance(), Constants.Duration.EndOfTurn), + new ManaCostsImpl("{G}"))); + } + + public MatsuTribeBirdstalker(final MatsuTribeBirdstalker card) { + super(card); + } + + @Override + public MatsuTribeBirdstalker copy() { + return new MatsuTribeBirdstalker(this); + } +} \ No newline at end of file diff --git a/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java b/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java index 3d8bb53995d..f8d7fd00266 100644 --- a/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java +++ b/Mage/src/mage/abilities/common/BeginningOfUpkeepTriggeredAbility.java @@ -34,7 +34,13 @@ public class BeginningOfUpkeepTriggeredAbility extends TriggeredAbilityImpl { + + private boolean setTargetPointer; + + public DealsCombatDamageToACreatureTriggeredAbility(Effect effect, boolean optional) { + this(effect, optional, false); + } + + public DealsCombatDamageToACreatureTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) { + super(Zone.BATTLEFIELD, effect, optional); + this.setTargetPointer = setTargetPointer; + } + + public DealsCombatDamageToACreatureTriggeredAbility(final DealsCombatDamageToACreatureTriggeredAbility ability) { + super(ability); + this.setTargetPointer = ability.setTargetPointer; + } + + @Override + public DealsCombatDamageToACreatureTriggeredAbility copy() { + return new DealsCombatDamageToACreatureTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (event.getType() == EventType.DAMAGED_CREATURE) { + if (event.getSourceId().equals(this.sourceId) + && ((DamagedCreatureEvent) event).isCombatDamage()) { + if (setTargetPointer) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + effect.setValue("damage", event.getAmount()); + } + } + return true; + } + + } + return false; + } + + @Override + public String getRule() { + return "Whenever {this} deals combat damage to a creature, " + super.getRule(); + } + +} diff --git a/Mage/src/mage/abilities/condition/common/CardsInHandCondition.java b/Mage/src/mage/abilities/condition/common/CardsInHandCondition.java new file mode 100644 index 00000000000..fdb5aaf3639 --- /dev/null +++ b/Mage/src/mage/abilities/condition/common/CardsInHandCondition.java @@ -0,0 +1,85 @@ +/* + * 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.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; + +/** + * Cards in controller hand condition. This condition can decorate other conditions + * as well as be used standalone. + * + * + * @author LevelX + */ +public class CardsInHandCondition implements Condition { + + public static enum CountType { MORE_THAN, FEWER_THAN, EQUAL_TO }; + private Condition condition; + private CountType type; + private int count; + + public CardsInHandCondition() { + this(CountType.EQUAL_TO, 0); + } + + public CardsInHandCondition (CountType type, int count ) { + this.type = type; + this.count = count; + } + + public CardsInHandCondition (CountType type, int count, Condition conditionToDecorate ) { + this(type, count); + this.condition = conditionToDecorate; + } + + @Override + public boolean apply(Game game, Ability source) { + boolean conditionApplies = false; + + switch ( this.type ) { + case FEWER_THAN: + conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() < this.count; + break; + case MORE_THAN: + conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() > this.count; + break; + case EQUAL_TO: + conditionApplies = game.getPlayer(source.getControllerId()).getHand().size() == this.count; + break; + } + + //If a decorated condition exists, check it as well and apply them together. + if ( this.condition != null ) { + conditionApplies = conditionApplies && this.condition.apply(game, source); + } + + return conditionApplies; + } +} diff --git a/Mage/src/mage/abilities/effects/common/SkipNextPlayerUntapStepEffect.java b/Mage/src/mage/abilities/effects/common/SkipNextPlayerUntapStepEffect.java new file mode 100644 index 00000000000..619c4a01318 --- /dev/null +++ b/Mage/src/mage/abilities/effects/common/SkipNextPlayerUntapStepEffect.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.abilities.effects.common; + +import mage.Constants; +import mage.Constants.PhaseStep; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.game.Game; +import mage.game.turn.TurnMod; +import mage.players.Player; + +/** + * + * @author LevelX + */ +public class SkipNextPlayerUntapStepEffect extends OneShotEffect { + + public SkipNextPlayerUntapStepEffect() { + super(Constants.Outcome.Detriment); + } + + public SkipNextPlayerUntapStepEffect(String text) { + this(); + staticText = text; + } + + public SkipNextPlayerUntapStepEffect(SkipNextPlayerUntapStepEffect effect) { + super(effect); + } + + @Override + public boolean apply(Game game, Ability source) { + if (targetPointer != null) { + Player player = game.getPlayer(targetPointer.getFirst(source)); + if (player != null) { + game.getState().getTurnMods().add(new TurnMod(player.getId(), PhaseStep.UNTAP)); + return true; + } + } + return false; + } + + @Override + public SkipNextPlayerUntapStepEffect copy() { + return new SkipNextPlayerUntapStepEffect(this); + } + + @Override + public String getText(Mode mode) { + StringBuilder sb = new StringBuilder(); + if (staticText.length() > 0) { + sb.append(staticText); + } + else { + sb.append("target"); + } + sb.append("player skips his or her next untap step"); + return sb.toString(); + } +} diff --git a/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java b/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java index ce9b4b953f9..157250119d3 100644 --- a/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java @@ -54,6 +54,11 @@ public class SkipNextUntapTargetEffect extends ReplacementEffectImpl 0) + return staticText + " doesn't untap during its controller's next untap step"; + else return "Target " + mode.getTargets().get(0).getTargetName() + " doesn't untap during its controller's next untap step"; } diff --git a/Mage/src/mage/abilities/effects/common/TapTargetEffect.java b/Mage/src/mage/abilities/effects/common/TapTargetEffect.java index fa14df58e3a..30acdaf4987 100644 --- a/Mage/src/mage/abilities/effects/common/TapTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/TapTargetEffect.java @@ -47,6 +47,11 @@ public class TapTargetEffect extends OneShotEffect { super(Outcome.Tap); } + public TapTargetEffect(String text) { + this(); + this.staticText = text; + } + public TapTargetEffect(final TapTargetEffect effect) { super(effect); } @@ -71,12 +76,15 @@ public class TapTargetEffect extends OneShotEffect { @Override public String getText(Mode mode) { - Target target = mode.getTargets().get(0); + if (staticText.length() > 0) + return "tap " + staticText; + + Target target = mode.getTargets().get(0); if (target.getMaxNumberOfTargets() > 1) - if (target.getMaxNumberOfTargets() == target.getNumberOfTargets()) - return "tap " + target.getNumberOfTargets() + " target " + mode.getTargets().get(0).getTargetName() + "s"; - else - return "tap up to " + target.getMaxNumberOfTargets() + " target " + mode.getTargets().get(0).getTargetName() + "s"; + if (target.getMaxNumberOfTargets() == target.getNumberOfTargets()) + return "tap " + target.getNumberOfTargets() + " target " + target.getTargetName() + "s"; + else + return "tap up to " + target.getMaxNumberOfTargets() + " target " + target.getTargetName() + "s"; else return "tap target " + mode.getTargets().get(0).getTargetName(); } diff --git a/Mage/src/mage/abilities/effects/common/continious/BecomesCreatureSourceEffect.java b/Mage/src/mage/abilities/effects/common/continious/BecomesCreatureSourceEffect.java index cd5f41d5470..9f01a5fd7cf 100644 --- a/Mage/src/mage/abilities/effects/common/continious/BecomesCreatureSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/BecomesCreatureSourceEffect.java @@ -81,7 +81,7 @@ public class BecomesCreatureSourceEffect extends ContinuousEffectImpl 0) { diff --git a/Mage/src/mage/abilities/effects/common/continious/BoostTargetEffect.java b/Mage/src/mage/abilities/effects/common/continious/BoostTargetEffect.java index 8f4d0354dd2..787c4f07e26 100644 --- a/Mage/src/mage/abilities/effects/common/continious/BoostTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/BoostTargetEffect.java @@ -49,7 +49,9 @@ public class BoostTargetEffect extends ContinuousEffectImpl { private DynamicValue power; private DynamicValue toughness; - + // if true, all dynamic values should be calculated once + protected boolean isLockedIn = false; + public BoostTargetEffect(int power, int toughness, Duration duration) { this(new StaticValue(power), new StaticValue(toughness), duration); } @@ -59,18 +61,41 @@ public class BoostTargetEffect extends ContinuousEffectImpl { this.power = power; this.toughness = toughness; } + /** + * @param power power value to boost + * @param toughness toughness value to boost + * @param duration how long does the effecct apply + * @param continuousCalculation true = power and toughness will be calculated continuously + * false = power and toughness will be calculated once during resolution + */ + public BoostTargetEffect(DynamicValue power, DynamicValue toughness, Duration duration, boolean isLockedIn) { + super(duration, Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, Outcome.BoostCreature); + this.power = power; + this.toughness = toughness; + this.isLockedIn = isLockedIn; + } public BoostTargetEffect(final BoostTargetEffect effect) { super(effect); this.power = effect.power.clone(); this.toughness = effect.toughness.clone(); + this.isLockedIn = effect.isLockedIn; } @Override public BoostTargetEffect copy() { return new BoostTargetEffect(this); } - + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + if (isLockedIn) { + power = new StaticValue(power.calculate(game, source)); + toughness = new StaticValue(toughness.calculate(game, source)); + } + } + @Override public boolean apply(Game game, Ability source) { int affectedTargets = 0; @@ -115,4 +140,8 @@ public class BoostTargetEffect extends ContinuousEffectImpl { sb.append(message); return sb.toString(); } + + public void setLockedIn(boolean isLockedIn) { + this.isLockedIn =isLockedIn; + } } diff --git a/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java b/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java index bda637e15e5..df176d8bcde 100644 --- a/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/GainAbilityControlledEffect.java @@ -34,6 +34,7 @@ import mage.Constants.Outcome; import mage.Constants.SubLayer; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.keyword.FlyingAbility; import mage.filter.FilterPermanent; import mage.game.Game; import mage.game.permanent.Permanent; @@ -104,8 +105,12 @@ public class GainAbilityControlledEffect extends ContinuousEffectImpl