diff --git a/Mage.Sets/src/mage/cards/b/BloodstoneGoblin.java b/Mage.Sets/src/mage/cards/b/BloodstoneGoblin.java
new file mode 100644
index 00000000000..cf306ac8f29
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/b/BloodstoneGoblin.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.b;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.KickerAbility;
+import mage.abilities.keyword.MenaceAbility;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.stack.Spell;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class BloodstoneGoblin extends CardImpl {
+
+ public BloodstoneGoblin(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
+
+ this.subtype.add(SubType.GOBLIN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(2);
+
+ // Whenever you cast a spell, if that spell was kicked, Bloodstone Goblin gets +1/+1 and gains menace until end of turn.
+ this.addAbility(new BloodstoneGoblinTriggeredAbility());
+ }
+
+ public BloodstoneGoblin(final BloodstoneGoblin card) {
+ super(card);
+ }
+
+ @Override
+ public BloodstoneGoblin copy() {
+ return new BloodstoneGoblin(this);
+ }
+}
+
+class BloodstoneGoblinTriggeredAbility extends TriggeredAbilityImpl {
+
+ BloodstoneGoblinTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn).setText("{this} gets +1/+1"), true);
+ this.addEffect(new GainAbilitySourceEffect(new MenaceAbility(), Duration.EndOfTurn).setText("and gains menace until end of turn"));
+ }
+
+ BloodstoneGoblinTriggeredAbility(final BloodstoneGoblinTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public BloodstoneGoblinTriggeredAbility copy() {
+ return new BloodstoneGoblinTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.SPELL_CAST;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ Spell spell = game.getStack().getSpell(event.getTargetId());
+ if (spell != null && spell.getControllerId().equals(controllerId)) {
+ for (Ability ability : spell.getAbilities()) {
+ if (ability instanceof KickerAbility && ((KickerAbility) ability).getKickedCounter(game, spell.getSpellAbility()) > 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever you cast a spell, if it was kicked," + super.getRule();
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChainersTorment.java b/Mage.Sets/src/mage/cards/c/ChainersTorment.java
new file mode 100644
index 00000000000..446eae23666
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChainersTorment.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.SagaAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DamagePlayersEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SagaChapter;
+import mage.constants.TargetController;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.ChainersTormentNightmareToken;
+import mage.players.Player;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class ChainersTorment extends CardImpl {
+
+ public ChainersTorment(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}");
+
+ this.subtype.add(SubType.SAGA);
+
+ // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
+ SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
+
+ // I, II — Chainer's Torment deals 2 damage to each opponent and you gain 2 life.
+ Ability ability = sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II, new DamagePlayersEffect(2, TargetController.OPPONENT));
+ ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life"));
+
+ // III — Create an X/X black Nightmare Horror creature token, where X is half your life total, rounded up. It deals X damage to you.
+ sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ChainersTormentEffect());
+ this.addAbility(sagaAbility);
+ }
+
+ public ChainersTorment(final ChainersTorment card) {
+ super(card);
+ }
+
+ @Override
+ public ChainersTorment copy() {
+ return new ChainersTorment(this);
+ }
+}
+
+class ChainersTormentEffect extends OneShotEffect {
+
+ ChainersTormentEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "Create an X/X black Nightmare Horror creature token, where X is half your life total, rounded up. It deals X damage to you";
+ }
+
+ ChainersTormentEffect(final ChainersTormentEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ChainersTormentEffect copy() {
+ return new ChainersTormentEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
+ }
+ int xValue = (int) Math.ceil((1.0 * Math.max(0, player.getLife())) / 2);
+ CreateTokenEffect effect = new CreateTokenEffect(new ChainersTormentNightmareToken(xValue));
+ if (effect.apply(game, source)) {
+ for (UUID tokenId : effect.getLastAddedTokenIds()) {
+ Permanent token = game.getPermanentOrLKIBattlefield(tokenId);
+ if (token != null) {
+ player.damage(xValue, tokenId, game, false, true);
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChandraBoldPyromancer.java b/Mage.Sets/src/mage/cards/c/ChandraBoldPyromancer.java
new file mode 100644
index 00000000000..1aec07ca717
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChandraBoldPyromancer.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.cards.c;
+
+import java.util.UUID;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.LoyaltyAbility;
+import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
+import mage.abilities.effects.Effects;
+import mage.abilities.effects.common.BasicManaEffect;
+import mage.abilities.effects.common.DamageAllControlledTargetEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
+import mage.target.TargetPlayer;
+import mage.target.common.TargetCreatureOrPlaneswalker;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class ChandraBoldPyromancer extends CardImpl {
+
+ public ChandraBoldPyromancer(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{R}{R}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.CHANDRA);
+ this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5));
+
+ // +1: Add {R}{R}. Chandra, Bold Pyromancer deals 2 damage to target player.
+ Ability ability = new LoyaltyAbility(new BasicManaEffect(Mana.RedMana(2)), +1);
+ ability.addEffect(new DamageTargetEffect(2));
+ ability.addTarget(new TargetPlayer());
+ this.addAbility(ability);
+
+ // −3: Chandra, Bold Pyromancer deals 3 damage to target creature or planeswalker.
+ ability = new LoyaltyAbility(new DamageTargetEffect(3), -3);
+ ability.addTarget(new TargetCreatureOrPlaneswalker());
+ this.addAbility(ability);
+
+ // −7: Chandra, Bold Pyromancer deals 10 damage to target player and each creature and planeswalker they control.
+ Effects effects1 = new Effects();
+ effects1.add(new DamageTargetEffect(10));
+ effects1.add(new DamageAllControlledTargetEffect(10, new FilterCreatureOrPlaneswalkerPermanent()).setText("and each creature and planeswalker they control"));
+ LoyaltyAbility ability3 = new LoyaltyAbility(effects1, -7);
+ ability3.addTarget(new TargetPlayer());
+ this.addAbility(ability3);
+ }
+
+ public ChandraBoldPyromancer(final ChandraBoldPyromancer card) {
+ super(card);
+ }
+
+ @Override
+ public ChandraBoldPyromancer copy() {
+ return new ChandraBoldPyromancer(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChandrasOutburst.java b/Mage.Sets/src/mage/cards/c/ChandrasOutburst.java
new file mode 100644
index 00000000000..4373e2d7206
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChandrasOutburst.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.filter.FilterCard;
+import mage.filter.predicate.mageobject.NamePredicate;
+import mage.target.common.TargetPlayerOrPlaneswalker;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class ChandrasOutburst extends CardImpl {
+
+ private final static FilterCard filter = new FilterCard("Chandra, Bold Pyromancer");
+
+ static {
+ filter.add(new NamePredicate("Chandra, Bold Pyromancer"));
+ }
+
+ public ChandrasOutburst(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{R}{R}");
+
+ // Chandra's Outburst deals 4 damage to target player or planeswalker.
+ this.getSpellAbility().addEffect(new DamageTargetEffect(4));
+ this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
+
+ // Search your library and/or graveyard for a card named Chandra, Bold Pyromancer, reveal it, and put it into your hand. If you search your library this way, shuffle it.
+ this.getSpellAbility().addEffect(new SearchLibraryGraveyardPutInHandEffect(filter));
+ }
+
+ public ChandrasOutburst(final ChandrasOutburst card) {
+ super(card);
+ }
+
+ @Override
+ public ChandrasOutburst copy() {
+ return new ChandrasOutburst(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FightWithFire.java b/Mage.Sets/src/mage/cards/f/FightWithFire.java
new file mode 100644
index 00000000000..099186f56b5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/FightWithFire.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.cards.f;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.SpellAbility;
+import mage.abilities.condition.common.KickedCondition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.DamageMultiEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.keyword.KickerAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.game.Game;
+import mage.target.common.TargetAnyTargetAmount;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class FightWithFire extends CardImpl {
+
+ public FightWithFire(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
+
+ // Kicker {5}{R}
+ this.addAbility(new KickerAbility("{5}{R}"));
+
+ // Fight with Fire deals 5 damage to target creature. If this spell was kicked, it deals 10 damage divided as you choose among any number of targets instead. (Those targets can include players and planeswalkers.)
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
+ new DamageMultiEffect(10),
+ new DamageTargetEffect(5),
+ KickedCondition.instance,
+ "{this} deals 5 damage to target creature. If this spell was kicked, "
+ + "it deals 10 damage divided as you choose among any number of targets instead."
+ + " (Those targets can include players and planeswalkers.)"
+ ));
+ }
+
+ public FightWithFire(final FightWithFire card) {
+ super(card);
+ }
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ if (ability instanceof SpellAbility) {
+ if (KickedCondition.instance.apply(game, ability)) {
+ ability.getTargets().clear();
+ getSpellAbility().addTarget(new TargetAnyTargetAmount(10));
+ }
+ }
+ }
+
+ @Override
+ public FightWithFire copy() {
+ return new FightWithFire(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/h/HallarTheFirefletcher.java b/Mage.Sets/src/mage/cards/h/HallarTheFirefletcher.java
new file mode 100644
index 00000000000..8cfbf4cfccd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/h/HallarTheFirefletcher.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.h;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.dynamicvalue.common.CountersSourceCount;
+import mage.abilities.effects.common.DamagePlayersEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.keyword.KickerAbility;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.stack.Spell;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class HallarTheFirefletcher extends CardImpl {
+
+ public HallarTheFirefletcher(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ELF);
+ this.subtype.add(SubType.ARCHER);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Trample
+ this.addAbility(TrampleAbility.getInstance());
+
+ // Whenever you cast a spell, if that spell was kicked, put a +1/+1 counter on Hallar, the Firefletcher, then Hallar deals damage equal to the number of +1/+1 counters on it to each opponent.
+ this.addAbility(new HallarTheFirefletcherTriggeredAbility());
+ }
+
+ public HallarTheFirefletcher(final HallarTheFirefletcher card) {
+ super(card);
+ }
+
+ @Override
+ public HallarTheFirefletcher copy() {
+ return new HallarTheFirefletcher(this);
+ }
+}
+
+class HallarTheFirefletcherTriggeredAbility extends TriggeredAbilityImpl {
+
+ HallarTheFirefletcherTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()).setText("put a +1/+1 counter on {this}"), true);
+ this.addEffect(new DamagePlayersEffect(Outcome.Benefit, new CountersSourceCount(CounterType.P1P1), TargetController.OPPONENT)
+ .setText("then {this} deals damage equal to the number of +1/+1 counters on it to each opponent")
+ );
+ }
+
+ HallarTheFirefletcherTriggeredAbility(final HallarTheFirefletcherTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public HallarTheFirefletcherTriggeredAbility copy() {
+ return new HallarTheFirefletcherTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.SPELL_CAST;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ Spell spell = game.getStack().getSpell(event.getTargetId());
+ if (spell != null && spell.getControllerId().equals(controllerId)) {
+ for (Ability ability : spell.getAbilities()) {
+ if (ability instanceof KickerAbility && ((KickerAbility) ability).getKickedCounter(game, spell.getSpellAbility()) > 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever you cast a spell, if it was kicked," + super.getRule();
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/ShannaSisaysLegacy.java b/Mage.Sets/src/mage/cards/s/ShannaSisaysLegacy.java
new file mode 100644
index 00000000000..36c618fcc2c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/ShannaSisaysLegacy.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
+import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+import mage.cards.Card;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.game.stack.StackObject;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class ShannaSisaysLegacy extends CardImpl {
+
+ private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creatures you control");
+
+ public ShannaSisaysLegacy(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.HUMAN);
+ this.subtype.add(SubType.WARRIOR);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // Shanna, Sisay's Legacy can't be the target of abilities your opponents control.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ShannaSisaysLegacyEffect()));
+
+ // Shanna gets +1/+1 for each creature you control.
+ DynamicValue value = new PermanentsOnBattlefieldCount(filter);
+ this.addAbility(new SimpleStaticAbility(
+ Zone.BATTLEFIELD,
+ new BoostSourceEffect(value, value, Duration.WhileOnBattlefield)
+ .setText("{this} gets +1/+1 for each creature you control")
+ ));
+ }
+
+ public ShannaSisaysLegacy(final ShannaSisaysLegacy card) {
+ super(card);
+ }
+
+ @Override
+ public ShannaSisaysLegacy copy() {
+ return new ShannaSisaysLegacy(this);
+ }
+}
+
+class ShannaSisaysLegacyEffect extends ContinuousRuleModifyingEffectImpl {
+
+ public ShannaSisaysLegacyEffect() {
+ super(Duration.WhileOnBattlefield, Outcome.BoostCreature);
+ staticText = "{this} can't be the target of abilities your opponents control";
+ }
+
+ public ShannaSisaysLegacyEffect(final ShannaSisaysLegacyEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ShannaSisaysLegacyEffect copy() {
+ return new ShannaSisaysLegacyEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public String getInfoMessage(Ability source, GameEvent event, Game game) {
+ Permanent sourcePermanent = game.getPermanent(source.getSourceId());
+ if (sourcePermanent != null) {
+ return sourcePermanent.getLogName() + " can't be the target of abilities you control";
+ }
+ return null;
+ }
+
+ @Override
+ public boolean checksEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.TARGET;
+ }
+
+ @Override
+ public boolean applies(GameEvent event, Ability source, Game game) {
+ Card targetCard = game.getCard(event.getTargetId());
+ StackObject stackObject = (StackObject) game.getStack().getStackObject(event.getSourceId());
+ if (targetCard != null && stackObject != null && targetCard.getId().equals(source.getSourceId())) {
+ if (stackObject instanceof Ability) {
+ if (!stackObject.getControllerId().equals(source.getControllerId())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SlimefootTheStowaway.java b/Mage.Sets/src/mage/cards/s/SlimefootTheStowaway.java
new file mode 100644
index 00000000000..f79048827f5
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SlimefootTheStowaway.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DamagePlayersEffect;
+import mage.abilities.effects.common.GainLifeEffect;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.ZoneChangeEvent;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.SaprolingToken;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class SlimefootTheStowaway extends CardImpl {
+
+ public SlimefootTheStowaway(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}");
+
+ this.addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.FUNGUS);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(3);
+
+ // Whenever a Saproling you control dies, Slimefoot, the Stowaway deals 1 damage to each opponent and you gain 1 life.
+ this.addAbility(new SlimefootTheStowawayTriggeredAbility());
+
+ // {4}: Create a 1/1 green Saproling creature token.
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken()), new ManaCostsImpl("{4}")));
+ }
+
+ public SlimefootTheStowaway(final SlimefootTheStowaway card) {
+ super(card);
+ }
+
+ @Override
+ public SlimefootTheStowaway copy() {
+ return new SlimefootTheStowaway(this);
+ }
+}
+
+class SlimefootTheStowawayTriggeredAbility extends TriggeredAbilityImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Saproling");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.SAPROLING));
+ }
+
+ public SlimefootTheStowawayTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT), false);
+ this.addEffect(new GainLifeEffect(1));
+ }
+
+ public SlimefootTheStowawayTriggeredAbility(final SlimefootTheStowawayTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ if (zEvent.getFromZone() == Zone.BATTLEFIELD && zEvent.getToZone() == Zone.GRAVEYARD) {
+ Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
+ if (permanent != null && permanent.getControllerId().equals(this.controllerId) && filter.match(permanent, game)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public SlimefootTheStowawayTriggeredAbility copy() {
+ return new SlimefootTheStowawayTriggeredAbility(this);
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever a Saproling you control dies, {this} deals 1 damage to each opponent and you gain 1 life.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SorcerersWand.java b/Mage.Sets/src/mage/cards/s/SorcerersWand.java
new file mode 100644
index 00000000000..27088c0220d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/SorcerersWand.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.cards.s;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.common.SourceHasSubtypeCondition;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.DamageTargetEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.abilities.keyword.EquipAbility;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.target.common.TargetPlayerOrPlaneswalker;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class SorcerersWand extends CardImpl {
+
+ public SorcerersWand(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
+
+ this.subtype.add(SubType.EQUIPMENT);
+
+ // Equipped creature has "{T}: This creature deals 1 damage to target player or planeswalker. If this creature is a Wizard, it deals 2 damage to that player or planeswalker instead."
+ Ability ability = new SimpleActivatedAbility(
+ new ConditionalOneShotEffect(
+ new DamageTargetEffect(2),
+ new DamageTargetEffect(1),
+ new SourceHasSubtypeCondition(SubType.WIZARD),
+ "This creature deals 1 damage to target player or planeswalker. "
+ + "If this creature is a Wizard, it deals 2 damage to that player or planeswalker instead."
+ ), new TapSourceCost()
+ );
+ ability.addTarget(new TargetPlayerOrPlaneswalker());
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ability, AttachmentType.EQUIPMENT)));
+
+ // Equip {3}
+ this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(3)));
+ }
+
+ public SorcerersWand(final SorcerersWand card) {
+ super(card);
+ }
+
+ @Override
+ public SorcerersWand copy() {
+ return new SorcerersWand(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TheFirstEruption.java b/Mage.Sets/src/mage/cards/t/TheFirstEruption.java
new file mode 100644
index 00000000000..ef0c8949b99
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TheFirstEruption.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.t;
+
+import java.util.UUID;
+import mage.Mana;
+import mage.abilities.Ability;
+import mage.abilities.common.SagaAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.BasicManaEffect;
+import mage.abilities.effects.common.CreateTokenEffect;
+import mage.abilities.effects.common.DamageAllEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SagaChapter;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterControlledPermanent;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.AbilityPredicate;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.game.permanent.token.BelzenlokDemonToken;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.common.TargetControlledPermanent;
+
+/**
+ *
+ * @author TheElk801
+ */
+public class TheFirstEruption extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each creature without flying");
+
+ static {
+ filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
+ }
+
+ public TheFirstEruption(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
+
+ this.subtype.add(SubType.SAGA);
+
+ // (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
+ SagaAbility sagaAbility = new SagaAbility(this, SagaChapter.CHAPTER_III);
+
+ // I — The First Eruption deals 1 damage to each creature without flying.
+ sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, new DamageAllEffect(1, filter));
+
+ // II — Add {R}{R}.
+ sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_II, new BasicManaEffect(Mana.RedMana(2)));
+
+ // III — Sacrifice a Mountain. If you do, The First Eruption deals 3 damage to each creature.
+ sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new CreateTokenEffect(new BelzenlokDemonToken()));
+ this.addAbility(sagaAbility);
+ }
+
+ public TheFirstEruption(final TheFirstEruption card) {
+ super(card);
+ }
+
+ @Override
+ public TheFirstEruption copy() {
+ return new TheFirstEruption(this);
+ }
+}
+
+class TheFirstEruptionEffect extends OneShotEffect {
+
+ private static final FilterControlledPermanent filter = new FilterControlledPermanent("a Mountain");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.MOUNTAIN));
+ }
+
+ TheFirstEruptionEffect() {
+ super(Outcome.Benefit);
+ this.staticText = "Sacrifice a Mountain. If you do, {this} deals 3 damage to each creature";
+ }
+
+ TheFirstEruptionEffect(final TheFirstEruptionEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TheFirstEruptionEffect copy() {
+ return new TheFirstEruptionEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+
+ if (controller == null) {
+ return false;
+ }
+
+ Target target = new TargetControlledPermanent(1, 1, filter, false);
+ boolean sacrificed = false;
+ if (target.canChoose(controller.getId(), game)) {
+ while (controller.canRespond() && !target.isChosen() && target.canChoose(controller.getId(), game)) {
+ controller.chooseTarget(Outcome.Sacrifice, target, source, game);
+ }
+
+ for (int idx = 0; idx < target.getTargets().size(); idx++) {
+ Permanent permanent = game.getPermanent(target.getTargets().get(idx));
+ if (permanent != null) {
+ sacrificed |= permanent.sacrifice(source.getSourceId(), game);
+ }
+ }
+ }
+
+ if (sacrificed) {
+ return new DamageAllEffect(3, StaticFilters.FILTER_PERMANENT_CREATURE).apply(game, source);
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/t/TianaShipsCaretaker.java b/Mage.Sets/src/mage/cards/t/TianaShipsCaretaker.java
new file mode 100644
index 00000000000..1924902e087
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/t/TianaShipsCaretaker.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of BetaSteward_at_googlemail.com.
+ */
+package mage.cards.t;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
+import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
+import mage.abilities.keyword.FlyingAbility;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.SuperType;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+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.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author spjspj
+ */
+public class TianaShipsCaretaker extends CardImpl {
+
+ public TianaShipsCaretaker(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{W}");
+
+ addSuperType(SuperType.LEGENDARY);
+ this.subtype.add(SubType.ANGEL);
+ this.subtype.add(SubType.ARTIFICER);
+ this.power = new MageInt(3);
+ this.toughness = new MageInt(3);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // First strike
+ this.addAbility(FirstStrikeAbility.getInstance());
+
+ // Whenever an Aura or Equipment you control is put into a graveyard from the battlefield, you may return that card to its owner's hand at the beginning of the next end step.
+ this.addAbility(new TianaShipsCaretakerTriggeredAbility());
+ }
+
+ public TianaShipsCaretaker(final TianaShipsCaretaker card) {
+ super(card);
+ }
+
+ @Override
+ public TianaShipsCaretaker copy() {
+ return new TianaShipsCaretaker(this);
+ }
+}
+
+class TianaShipsCaretakerTriggeredAbility extends TriggeredAbilityImpl {
+
+ TianaShipsCaretakerTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new TianaShipsCaretakerEffect(), true);
+ }
+
+ TianaShipsCaretakerTriggeredAbility(final TianaShipsCaretakerTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public TianaShipsCaretakerTriggeredAbility copy() {
+ return new TianaShipsCaretakerTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
+ if (zEvent.getTarget() == null) {
+ return false;
+ }
+ Permanent permanent = game.getPermanentOrLKIBattlefield(zEvent.getTarget().getId());
+
+ if (permanent != null
+ && zEvent.getToZone() == Zone.GRAVEYARD
+ && zEvent.getFromZone() == Zone.BATTLEFIELD
+ && (permanent.isArtifact() && permanent.hasSubtype(SubType.EQUIPMENT, game)
+ || permanent.isEnchantment() && permanent.hasSubtype(SubType.AURA, game))
+ && permanent.getControllerId().equals(this.controllerId)) {
+ this.getEffects().setTargetPointer(new FixedTarget(zEvent.getTargetId()));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public String getRule() {
+ return "Whenever an Aura or Equipment you control is put into a graveyard from the battlefield, " + super.getRule();
+ }
+}
+
+class TianaShipsCaretakerEffect extends OneShotEffect {
+
+ TianaShipsCaretakerEffect() {
+ super(Outcome.PutCardInPlay);
+ this.staticText = "you may return that card to its owner's hand at the beginning of the next end step";
+ }
+
+ TianaShipsCaretakerEffect(final TianaShipsCaretakerEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public TianaShipsCaretakerEffect copy() {
+ return new TianaShipsCaretakerEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Card card = game.getCard(getTargetPointer().getFirst(game, source));
+ if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) {
+ Effect effect = new ReturnFromGraveyardToHandTargetEffect();
+ effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
+ effect.setText("return that card to your hand at the beginning of the next end step");
+ game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/sets/Dominaria.java b/Mage.Sets/src/mage/sets/Dominaria.java
index 81b36db0d5a..bd763058b17 100644
--- a/Mage.Sets/src/mage/sets/Dominaria.java
+++ b/Mage.Sets/src/mage/sets/Dominaria.java
@@ -77,6 +77,7 @@ public class Dominaria extends ExpansionSet {
cards.add(new SetCardInfo("Blessed Light", 7, Rarity.UNCOMMON, mage.cards.b.BlessedLight.class));
cards.add(new SetCardInfo("Blessing of Belzenlok", 77, Rarity.COMMON, mage.cards.b.BlessingOfBelzenlok.class));
cards.add(new SetCardInfo("Blink of an Eye", 46, Rarity.COMMON, mage.cards.b.BlinkOfAnEye.class));
+ cards.add(new SetCardInfo("Bloodstone Goblin", 115, Rarity.COMMON, mage.cards.b.BloodstoneGoblin.class));
cards.add(new SetCardInfo("Bloodtallow Candle", 212, Rarity.COMMON, mage.cards.b.BloodtallowCandle.class));
cards.add(new SetCardInfo("Board the Weatherlight", 8, Rarity.UNCOMMON, mage.cards.b.BoardTheWeatherlight.class));
cards.add(new SetCardInfo("Broken Bond", 157, Rarity.COMMON, mage.cards.b.BrokenBond.class));
@@ -86,7 +87,10 @@ public class Dominaria extends ExpansionSet {
cards.add(new SetCardInfo("Caligo Skin-Witch", 80, Rarity.COMMON, mage.cards.c.CaligoSkinWitch.class));
cards.add(new SetCardInfo("Call the Cavalry", 9, Rarity.COMMON, mage.cards.c.CallTheCavalry.class));
cards.add(new SetCardInfo("Cast Down", 81, Rarity.UNCOMMON, mage.cards.c.CastDown.class));
+ cards.add(new SetCardInfo("Chainer's Torment", 82, Rarity.UNCOMMON, mage.cards.c.ChainersTorment.class));
cards.add(new SetCardInfo("Champion of the Flame", 116, Rarity.UNCOMMON, mage.cards.c.ChampionOfTheFlame.class));
+ cards.add(new SetCardInfo("Chandra's Outburst", 276, Rarity.RARE, mage.cards.c.ChandrasOutburst.class));
+ cards.add(new SetCardInfo("Chandra, Bold Pyromancer", 275, Rarity.MYTHIC, mage.cards.c.ChandraBoldPyromancer.class));
cards.add(new SetCardInfo("Charge", 10, Rarity.COMMON, mage.cards.c.Charge.class));
cards.add(new SetCardInfo("Clifftop Retreat", 239, Rarity.RARE, mage.cards.c.ClifftopRetreat.class));
cards.add(new SetCardInfo("Cloudreader Sphinx", 47, Rarity.COMMON, mage.cards.c.CloudreaderSphinx.class));
@@ -112,6 +116,7 @@ public class Dominaria extends ExpansionSet {
cards.add(new SetCardInfo("Feral Abomination", 92, Rarity.COMMON, mage.cards.f.FeralAbomination.class));
cards.add(new SetCardInfo("Fervent Strike", 117, Rarity.COMMON, mage.cards.f.FerventStrike.class));
cards.add(new SetCardInfo("Fiery Intervention", 118, Rarity.COMMON, mage.cards.f.FieryIntervention.class));
+ cards.add(new SetCardInfo("Fight with Fire", 119, Rarity.UNCOMMON, mage.cards.f.FightWithFire.class));
cards.add(new SetCardInfo("Final Parting", 93, Rarity.UNCOMMON, mage.cards.f.FinalParting.class));
cards.add(new SetCardInfo("Fire Elemental", 120, Rarity.COMMON, mage.cards.f.FireElemental.class));
cards.add(new SetCardInfo("Firefist Adept", 121, Rarity.UNCOMMON, mage.cards.f.FirefistAdept.class));
@@ -138,6 +143,7 @@ public class Dominaria extends ExpansionSet {
cards.add(new SetCardInfo("Grow from the Ashes", 164, Rarity.COMMON, mage.cards.g.GrowFromTheAshes.class));
cards.add(new SetCardInfo("Grunn, the Lonely King", 165, Rarity.UNCOMMON, mage.cards.g.GrunnTheLonelyKing.class));
cards.add(new SetCardInfo("Guardians of Koilos", 216, Rarity.COMMON, mage.cards.g.GuardiansOfKoilos.class));
+ cards.add(new SetCardInfo("Hallar, the Firefletcher", 196, Rarity.UNCOMMON, mage.cards.h.HallarTheFirefletcher.class));
cards.add(new SetCardInfo("Helm of the Host", 217, Rarity.RARE, mage.cards.h.HelmOfTheHost.class));
cards.add(new SetCardInfo("Hinterland Harbor", 240, Rarity.RARE, mage.cards.h.HinterlandHarbor.class));
cards.add(new SetCardInfo("History of Benalia", 21, Rarity.MYTHIC, mage.cards.h.HistoryOfBenalia.class));
@@ -231,14 +237,17 @@ public class Dominaria extends ExpansionSet {
cards.add(new SetCardInfo("Serra Disciple", 34, Rarity.COMMON, mage.cards.s.SerraDisciple.class));
cards.add(new SetCardInfo("Settle the Score", 103, Rarity.UNCOMMON, mage.cards.s.SettleTheScore.class));
cards.add(new SetCardInfo("Shalai, Voice of Plenty", 35, Rarity.RARE, mage.cards.s.ShalaiVoiceOfPlenty.class));
+ cards.add(new SetCardInfo("Shanna, Sisay's Legacy", 204, Rarity.UNCOMMON, mage.cards.s.ShannaSisaysLegacy.class));
cards.add(new SetCardInfo("Shivan Fire", 142, Rarity.COMMON, mage.cards.s.ShivanFire.class));
cards.add(new SetCardInfo("Short Sword", 229, Rarity.COMMON, mage.cards.s.ShortSword.class));
cards.add(new SetCardInfo("Siege-Gang Commander", 143, Rarity.RARE, mage.cards.s.SiegeGangCommander.class));
cards.add(new SetCardInfo("Skirk Prospector", 144, Rarity.COMMON, mage.cards.s.SkirkProspector.class));
cards.add(new SetCardInfo("Skittering Surveyor", 230, Rarity.COMMON, mage.cards.s.SkitteringSurveyor.class));
cards.add(new SetCardInfo("Skizzik", 145, Rarity.UNCOMMON, mage.cards.s.Skizzik.class));
+ cards.add(new SetCardInfo("Slimefoot, the Stowaway", 205, Rarity.UNCOMMON, mage.cards.s.SlimefootTheStowaway.class));
cards.add(new SetCardInfo("Slinn Voda, the Rising Deep", 66, Rarity.UNCOMMON, mage.cards.s.SlinnVodaTheRisingDeep.class));
cards.add(new SetCardInfo("Song of Freyalise", 179, Rarity.UNCOMMON, mage.cards.s.SongOfFreyalise.class));
+ cards.add(new SetCardInfo("Sorcerer's Wand", 231, Rarity.UNCOMMON, mage.cards.s.SorcerersWand.class));
cards.add(new SetCardInfo("Soul Salvage", 104, Rarity.COMMON, mage.cards.s.SoulSalvage.class));
cards.add(new SetCardInfo("Sparring Construct", 232, Rarity.COMMON, mage.cards.s.SparringConstruct.class));
cards.add(new SetCardInfo("Spore Swarm", 180, Rarity.UNCOMMON, mage.cards.s.SporeSwarm.class));
@@ -266,11 +275,13 @@ public class Dominaria extends ExpansionSet {
cards.add(new SetCardInfo("Thallid Soothsayer", 107, Rarity.UNCOMMON, mage.cards.t.ThallidSoothsayer.class));
cards.add(new SetCardInfo("The Antiquities War", 42, Rarity.RARE, mage.cards.t.TheAntiquitiesWar.class));
cards.add(new SetCardInfo("The Eldest Reborn", 90, Rarity.UNCOMMON, mage.cards.t.TheEldestReborn.class));
+ cards.add(new SetCardInfo("The First Eruption", 122, Rarity.RARE, mage.cards.t.TheFirstEruption.class));
cards.add(new SetCardInfo("The Flame of Keld", 123, Rarity.UNCOMMON, mage.cards.t.TheFlameOfKeld.class));
cards.add(new SetCardInfo("The Mending of Dominaria", 173, Rarity.RARE, mage.cards.t.TheMendingOfDominaria.class));
cards.add(new SetCardInfo("The Mirari Conjecture", 57, Rarity.RARE, mage.cards.t.TheMirariConjecture.class));
cards.add(new SetCardInfo("Thorn Elemental", 185, Rarity.UNCOMMON, mage.cards.t.ThornElemental.class));
cards.add(new SetCardInfo("Thran Temporal Gateway", 233, Rarity.RARE, mage.cards.t.ThranTemporalGateway.class));
+ cards.add(new SetCardInfo("Tiana, Ship's Caretaker", 208, Rarity.UNCOMMON, mage.cards.t.TianaShipsCaretaker.class));
cards.add(new SetCardInfo("Timber Gorge", 279, Rarity.COMMON, mage.cards.t.TimberGorge.class));
cards.add(new SetCardInfo("Time of Ice", 70, Rarity.UNCOMMON, mage.cards.t.TimeOfIce.class));
cards.add(new SetCardInfo("Tolarian Scholar", 71, Rarity.COMMON, mage.cards.t.TolarianScholar.class));
diff --git a/Mage/src/main/java/mage/abilities/effects/common/DamageAllControlledTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DamageAllControlledTargetEffect.java
index 5a4622b6e2c..cc0940579df 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/DamageAllControlledTargetEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/DamageAllControlledTargetEffect.java
@@ -25,13 +25,12 @@
* 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.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
-import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
@@ -41,10 +40,10 @@ import mage.game.permanent.Permanent;
*/
public class DamageAllControlledTargetEffect extends OneShotEffect {
- private FilterCreaturePermanent filter;
+ private FilterPermanent filter;
private int amount;
- public DamageAllControlledTargetEffect(int amount, FilterCreaturePermanent filter) {
+ public DamageAllControlledTargetEffect(int amount, FilterPermanent filter) {
super(Outcome.Damage);
this.amount = amount;
this.filter = filter;
@@ -64,7 +63,7 @@ public class DamageAllControlledTargetEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- for (Permanent permanent: game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game)) {
+ for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game)) {
permanent.damage(amount, source.getSourceId(), game, false, true);
}
return true;
diff --git a/Mage/src/main/java/mage/game/permanent/token/ChainersTormentNightmareToken.java b/Mage/src/main/java/mage/game/permanent/token/ChainersTormentNightmareToken.java
new file mode 100644
index 00000000000..db1d907981b
--- /dev/null
+++ b/Mage/src/main/java/mage/game/permanent/token/ChainersTormentNightmareToken.java
@@ -0,0 +1,55 @@
+/*
+* 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.game.permanent.token;
+
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.MageInt;
+
+/**
+ *
+ * @author spjspj
+ */
+public class ChainersTormentNightmareToken extends TokenImpl {
+
+ public ChainersTormentNightmareToken(int xValue) {
+ super("Nightmare", "X/X black Nightmare artifact creature token");
+ cardType.add(CardType.CREATURE);
+ subtype.add(SubType.NIGHTMARE);
+ power = new MageInt(xValue);
+ toughness = new MageInt(xValue);
+ }
+
+ public ChainersTormentNightmareToken(final ChainersTormentNightmareToken token) {
+ super(token);
+ }
+
+ public ChainersTormentNightmareToken copy() {
+ return new ChainersTormentNightmareToken(this);
+ }
+}
diff --git a/Mage/src/main/java/mage/target/common/TargetAnyTargetAmount.java b/Mage/src/main/java/mage/target/common/TargetAnyTargetAmount.java
new file mode 100644
index 00000000000..f5e95cd7772
--- /dev/null
+++ b/Mage/src/main/java/mage/target/common/TargetAnyTargetAmount.java
@@ -0,0 +1,218 @@
+/*
+ * 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.target.common;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+import mage.MageObject;
+import mage.abilities.Ability;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.constants.Zone;
+import mage.filter.Filter;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreaturePlayerOrPlaneswalker;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetAmount;
+
+/**
+ *
+ * @author BetaSteward_at_googlemail.com
+ */
+public class TargetAnyTargetAmount extends TargetAmount {
+
+ protected final FilterCreaturePlayerOrPlaneswalker filter;
+
+ public TargetAnyTargetAmount(int amount) {
+ // 107.1c If a rule or ability instructs a player to choose “any number,” that player may choose
+ // any positive number or zero, unless something (such as damage or counters) is being divided
+ // or distributed among “any number” of players and/or objects. In that case, a nonzero number
+ // of players and/or objects must be chosen if possible.
+ this(new StaticValue(amount));
+ this.minNumberOfTargets = 1;
+ }
+
+ public TargetAnyTargetAmount(DynamicValue amount) {
+ super(amount);
+ this.zone = Zone.ALL;
+ this.filter = new FilterCreaturePlayerOrPlaneswalker("targets");
+ this.targetName = filter.getMessage();
+ }
+
+ public TargetAnyTargetAmount(final TargetAnyTargetAmount target) {
+ super(target);
+ this.filter = target.filter.copy();
+ }
+
+ @Override
+ public Filter getFilter() {
+ return this.filter;
+ }
+
+ @Override
+ public boolean canTarget(UUID objectId, Game game) {
+ Permanent permanent = game.getPermanent(objectId);
+ if (permanent != null) {
+ return filter.match(permanent, game);
+ }
+ Player player = game.getPlayer(objectId);
+ return player != null && filter.match(player, game);
+ }
+
+ @Override
+ public boolean canTarget(UUID objectId, Ability source, Game game) {
+ Permanent permanent = game.getPermanent(objectId);
+ Player player = game.getPlayer(objectId);
+
+ if (source != null) {
+ MageObject targetSource = source.getSourceObject(game);
+ if (permanent != null) {
+ return permanent.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
+ }
+ if (player != null) {
+ return player.canBeTargetedBy(targetSource, source.getControllerId(), game) && filter.match(player, game);
+ }
+ }
+
+ if (permanent != null) {
+ return filter.match(permanent, game);
+ }
+ return player != null && filter.match(player, game);
+ }
+
+ @Override
+ public boolean canTarget(UUID playerId, UUID objectId, Ability source, Game game) {
+ return canTarget(objectId, source, game);
+ }
+
+ @Override
+ public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
+ int count = 0;
+ MageObject targetSource = game.getObject(sourceId);
+ for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) {
+ count++;
+ if (count >= this.minNumberOfTargets) {
+ return true;
+ }
+ }
+ }
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT, sourceControllerId, game)) {
+ if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
+ count++;
+ if (count >= this.minNumberOfTargets) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canChoose(UUID sourceControllerId, Game game) {
+ int count = 0;
+ for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null && filter.match(player, game)) {
+ count++;
+ if (count >= this.minNumberOfTargets) {
+ return true;
+ }
+ }
+ }
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT, sourceControllerId, game)) {
+ if (filter.match(permanent, null, sourceControllerId, game)) {
+ count++;
+ if (count >= this.minNumberOfTargets) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Set possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
+ Set possibleTargets = new HashSet<>();
+ MageObject targetSource = game.getObject(sourceId);
+ for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null && player.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(player, game)) {
+ possibleTargets.add(playerId);
+ }
+ }
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT, sourceControllerId, game)) {
+ if (permanent.canBeTargetedBy(targetSource, sourceControllerId, game) && filter.match(permanent, sourceId, sourceControllerId, game)) {
+ possibleTargets.add(permanent.getId());
+ }
+ }
+ return possibleTargets;
+ }
+
+ @Override
+ public Set possibleTargets(UUID sourceControllerId, Game game) {
+ Set possibleTargets = new HashSet<>();
+ for (UUID playerId : game.getState().getPlayersInRange(sourceControllerId, game)) {
+ Player player = game.getPlayer(playerId);
+ if (player != null && filter.match(player, game)) {
+ possibleTargets.add(playerId);
+ }
+ }
+ for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT, sourceControllerId, game)) {
+ if (filter.match(permanent, null, sourceControllerId, game)) {
+ possibleTargets.add(permanent.getId());
+ }
+ }
+ return possibleTargets;
+ }
+
+ @Override
+ public String getTargetedName(Game game) {
+ StringBuilder sb = new StringBuilder();
+ for (UUID targetId : getTargets()) {
+ Permanent permanent = game.getPermanent(targetId);
+ if (permanent != null) {
+ sb.append(permanent.getLogName()).append('(').append(getTargetAmount(targetId)).append(") ");
+ } else {
+ Player player = game.getPlayer(targetId);
+ sb.append(player.getLogName()).append('(').append(getTargetAmount(targetId)).append(") ");
+ }
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public TargetAnyTargetAmount copy() {
+ return new TargetAnyTargetAmount(this);
+ }
+
+}