From 08a7332d92823dffed51041d2c1a91ba8409da81 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:40:48 +0100 Subject: [PATCH 01/52] Minor Invasion Plans text fix --- Mage.Sets/src/mage/cards/i/InvasionPlans.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/i/InvasionPlans.java b/Mage.Sets/src/mage/cards/i/InvasionPlans.java index 3e00e929eb2..55d41fd13db 100644 --- a/Mage.Sets/src/mage/cards/i/InvasionPlans.java +++ b/Mage.Sets/src/mage/cards/i/InvasionPlans.java @@ -68,8 +68,8 @@ public class InvasionPlans extends CardImpl { class InvasionPlansEffect extends ContinuousRuleModifyingEffectImpl { public InvasionPlansEffect() { - super(Duration.WhileOnBattlefield, Outcome.Benefit, true, false); - staticText = "The attacking player chooses how each creature blocks each "; + super(Duration.WhileOnBattlefield, Outcome.Benefit, false, false); + staticText = "The attacking player chooses how each creature blocks each turn"; } public InvasionPlansEffect(final InvasionPlansEffect effect) { From d5635e404a734aac5b3d3178591bc89c599058bc Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:41:50 +0100 Subject: [PATCH 02/52] Kookus numbering fix --- Mage.Sets/src/mage/sets/Visions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Visions.java b/Mage.Sets/src/mage/sets/Visions.java index 339ced90a71..4f8f5d0e792 100644 --- a/Mage.Sets/src/mage/sets/Visions.java +++ b/Mage.Sets/src/mage/sets/Visions.java @@ -117,7 +117,7 @@ public class Visions extends ExpansionSet { cards.add(new SetCardInfo("King Cheetah", 60, Rarity.COMMON, mage.cards.k.KingCheetah.class)); cards.add(new SetCardInfo("Knight of Valor", 111, Rarity.COMMON, mage.cards.k.KnightOfValor.class)); cards.add(new SetCardInfo("Knight of the Mists", 36, Rarity.COMMON, mage.cards.k.KnightOfTheMists.class)); - cards.add(new SetCardInfo("Kookus", 85, Rarity.RARE, mage.cards.k.Kookus.class)); + cards.add(new SetCardInfo("Kookus", 86, Rarity.RARE, mage.cards.k.Kookus.class)); cards.add(new SetCardInfo("Lead-Belly Chimera", 148, Rarity.UNCOMMON, mage.cards.l.LeadBellyChimera.class)); cards.add(new SetCardInfo("Lichenthrope", 62, Rarity.RARE, mage.cards.l.Lichenthrope.class)); cards.add(new SetCardInfo("Lightning Cloud", 87, Rarity.RARE, mage.cards.l.LightningCloud.class)); From 0efc03bc1b15733fe317703d161d9213f8a4bcde Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:46:13 +0100 Subject: [PATCH 03/52] Added control change announcement --- Mage.Sets/src/mage/cards/RiskyMove.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/RiskyMove.java b/Mage.Sets/src/mage/cards/RiskyMove.java index 321c407d7b3..322719a5854 100644 --- a/Mage.Sets/src/mage/cards/RiskyMove.java +++ b/Mage.Sets/src/mage/cards/RiskyMove.java @@ -63,8 +63,7 @@ public class RiskyMove extends CardImpl { this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new RiskyMoveGetControlEffect(), TargetController.ANY, false, true)); // When you gain control of Risky Move from another player, choose a creature you control and an opponent. Flip a coin. If you lose the flip, that opponent gains control of that creature. - Ability ability = new RiskyMoveTriggeredAbility(); - this.addAbility(ability); + this.addAbility(new RiskyMoveTriggeredAbility()); } public RiskyMove(final RiskyMove card) { @@ -194,6 +193,7 @@ class RiskyMoveFlipCoinEffect extends OneShotEffect { ContinuousEffect effect = new RiskyMoveCreatureGainControlEffect(Duration.Custom, chosenOpponent.getId()); effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); + game.informPlayers(chosenOpponent.getLogName() + " has gained control of " + permanent.getLogName()); return true; } } From c6a80e1b6b30473ce0f213c9dd1aa4a8e6b479c6 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:47:56 +0100 Subject: [PATCH 04/52] Some improvements --- .../src/mage/cards/g/GoblinFestival.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Mage.Sets/src/mage/cards/g/GoblinFestival.java b/Mage.Sets/src/mage/cards/g/GoblinFestival.java index 8a12d1021a3..b6bf5778ae2 100644 --- a/Mage.Sets/src/mage/cards/g/GoblinFestival.java +++ b/Mage.Sets/src/mage/cards/g/GoblinFestival.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.common.SimpleActivatedAbility; -import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffectImpl; @@ -93,15 +92,24 @@ class GoblinFestivalChangeControlEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (controller != null) { if (!controller.flipCoin(game)) { - Target target = new TargetOpponent(); - target.setNotTarget(true); - if (controller.chooseTarget(outcome, target, source, game)) { - ContinuousEffect effect = new GoblinFestivalGainControlEffect(Duration.Custom, target.getFirstTarget()); - effect.setTargetPointer(new FixedTarget(source.getSourceId())); - game.addEffect(effect, source); - return true; + if (sourcePermanent != null) { + Target target = new TargetOpponent(true); + if (target.canChoose(source.getSourceId(), controller.getId(), game)) { + while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) { + controller.chooseTarget(outcome, target, source, game); + } + } + Player chosenOpponent = game.getPlayer(target.getFirstTarget()); + if (chosenOpponent != null) { + ContinuousEffect effect = new GoblinFestivalGainControlEffect(Duration.Custom, chosenOpponent.getId()); + effect.setTargetPointer(new FixedTarget(sourcePermanent.getId())); + game.addEffect(effect, source); + game.informPlayers(chosenOpponent.getLogName() + " has gained control of " + sourcePermanent.getLogName()); + return true; + } } } } From a52c98aa254e659389a424cb0a3e78be296c4c22 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:49:39 +0100 Subject: [PATCH 05/52] Typo fix --- .../mage/abilities/effects/common/combat/GoadTargetEffect.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java index 5b5a7b55dd3..093693bb29f 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/combat/GoadTargetEffect.java @@ -74,7 +74,7 @@ public class GoadTargetEffect extends OneShotEffect { effect = new CantAttackYouEffect(Duration.UntilYourNextTurn); effect.setTargetPointer(new FixedTarget(getTargetPointer().getFirst(game, source))); game.addEffect(effect, source); - game.informPlayers(controller.getLogName() + " is goating " + targetCreature.getLogName()); + game.informPlayers(controller.getLogName() + " is goading " + targetCreature.getLogName()); } return true; } From c646fbe1034e657bab24ed747775fa8f3b724ace Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:51:25 +0100 Subject: [PATCH 06/52] Implemented Fickle Efreet --- Mage.Sets/src/mage/cards/f/FickleEfreet.java | 158 +++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/f/FickleEfreet.java diff --git a/Mage.Sets/src/mage/cards/f/FickleEfreet.java b/Mage.Sets/src/mage/cards/f/FickleEfreet.java new file mode 100644 index 00000000000..0b5e1d27fd5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FickleEfreet.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.cards.f; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.common.AttacksOrBlocksTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetOpponent; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class FickleEfreet extends CardImpl { + + public FickleEfreet(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + this.subtype.add(SubType.EFREET); + + this.power = new MageInt(5); + this.toughness = new MageInt(2); + + // Whenever Fickle Efreet attacks or blocks, flip a coin at end of combat. If you lose the flip, an opponent gains control of Fickle Efreet. + this.addAbility(new AttacksOrBlocksTriggeredAbility(new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new FickleEfreetChangeControlEffect()), true), false)); + } + + public FickleEfreet(final FickleEfreet card) { + super(card); + } + + @Override + public FickleEfreet copy() { + return new FickleEfreet(this); + } +} + + +class FickleEfreetChangeControlEffect extends OneShotEffect { + + public FickleEfreetChangeControlEffect() { + super(Outcome.Benefit); + this.staticText = "flip a coin at end of combat. If you lose the flip, choose one of your opponents. That player gains control of {this}"; + } + + public FickleEfreetChangeControlEffect(final FickleEfreetChangeControlEffect effect) { + super(effect); + } + + @Override + public FickleEfreetChangeControlEffect copy() { + return new FickleEfreetChangeControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (controller != null) { + if (!controller.flipCoin(game)) { + if (sourcePermanent != null) { + Target target = new TargetOpponent(true); + if (target.canChoose(source.getSourceId(), controller.getId(), game)) { + while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) { + controller.chooseTarget(outcome, target, source, game); + } + } + Player chosenOpponent = game.getPlayer(target.getFirstTarget()); + if (chosenOpponent != null) { + ContinuousEffect effect = new FickleEfreetGainControlEffect(Duration.Custom, target.getFirstTarget()); + effect.setTargetPointer(new FixedTarget(sourcePermanent.getId())); + game.addEffect(effect, source); + game.informPlayers(chosenOpponent.getLogName() + " has gained control of " + sourcePermanent.getLogName()); + return true; + } + } + } + } + return false; + } +} + +class FickleEfreetGainControlEffect extends ContinuousEffectImpl { + + UUID controller; + + public FickleEfreetGainControlEffect(Duration duration, UUID controller) { + super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl); + this.controller = controller; + } + + public FickleEfreetGainControlEffect(final FickleEfreetGainControlEffect effect) { + super(effect); + this.controller = effect.controller; + } + + @Override + public FickleEfreetGainControlEffect copy() { + return new FickleEfreetGainControlEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getFirstTarget()); + if (targetPointer != null) { + permanent = game.getPermanent(targetPointer.getFirst(game, source)); + } + if (permanent != null) { + return permanent.changeControllerId(controller, game); + } + return false; + } + + @Override + public String getText(Mode mode) { + return "That player gains control of {this}"; + } +} From 3c2d75728e2413fa0bca4e44b82c4dbac5c16c9d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:52:43 +0100 Subject: [PATCH 07/52] Implemented Goblin Lyre --- Mage.Sets/src/mage/cards/g/GoblinLyre.java | 106 +++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinLyre.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinLyre.java b/Mage.Sets/src/mage/cards/g/GoblinLyre.java new file mode 100644 index 00000000000..96d7411cc97 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinLyre.java @@ -0,0 +1,106 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.SacrificeSourceCost; +import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; +import mage.abilities.dynamicvalue.common.PermanentsTargetOpponentControlsCount; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author L_J + */ +public class GoblinLyre extends CardImpl { + + public GoblinLyre(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); + + // Sacrifice Goblin Lyre: Flip a coin. If you win the flip, Goblin Lyre deals damage to target opponent equal to the number of creatures you control. If you lose the flip, Goblin Lyre deals damage to you equal to the number of creatures that opponent controls. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GoblinLyreEffect(), new SacrificeSourceCost()); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public GoblinLyre(final GoblinLyre card) { + super(card); + } + + @Override + public GoblinLyre copy() { + return new GoblinLyre(this); + } +} + +class GoblinLyreEffect extends OneShotEffect { + + public GoblinLyreEffect() { + super(Outcome.Damage); + this.staticText = "Flip a coin. If you win the flip, {this} deals damage to target opponent equal to the number of creatures you control. If you lose the flip, {this} deals damage to you equal to the number of creatures that opponent controls"; + } + + public GoblinLyreEffect(final GoblinLyreEffect effect) { + super(effect); + } + + @Override + public GoblinLyreEffect copy() { + return new GoblinLyreEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (controller != null) { + if (controller.flipCoin(game)) { + if (opponent != null) { + opponent.damage(new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent()).calculate(game, source, this), source.getSourceId(), game, false, true); + return true; + } + } else { + controller.damage(new PermanentsTargetOpponentControlsCount(new FilterCreaturePermanent()).calculate(game, source, this), source.getSourceId(), game, false, true); + return true; + } + } + return false; + } +} From d907dc5ccd730a615432d66c7c428a797d4f9126 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:53:54 +0100 Subject: [PATCH 08/52] Implemented Goblin Psychopath --- .../src/mage/cards/g/GoblinPsychopath.java | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/g/GoblinPsychopath.java diff --git a/Mage.Sets/src/mage/cards/g/GoblinPsychopath.java b/Mage.Sets/src/mage/cards/g/GoblinPsychopath.java new file mode 100644 index 00000000000..a64aa200543 --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GoblinPsychopath.java @@ -0,0 +1,136 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.g; + +import java.util.UUID; +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.AttacksOrBlocksTriggeredAbility; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.events.DamageEvent; +import mage.game.events.GameEvent; +import mage.players.Player; + +/** + * + * @author L_J + */ +public class GoblinPsychopath extends CardImpl { + + public GoblinPsychopath(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.MUTANT); + this.power = new MageInt(5); + this.toughness = new MageInt(5); + + // Whenever Goblin Psychopath attacks or blocks, flip a coin. If you lose the flip, the next time it would deal combat damage this turn, it deals that damage to you instead. + this.addAbility(new AttacksOrBlocksTriggeredAbility(new GoblinPsychopathEffect(), false)); + } + + public GoblinPsychopath(final GoblinPsychopath card) { + super(card); + } + + @Override + public GoblinPsychopath copy() { + return new GoblinPsychopath(this); + } +} + +class GoblinPsychopathEffect extends ReplacementEffectImpl { + + private boolean wonFlip; + + public GoblinPsychopathEffect() { + super(Duration.EndOfTurn, Outcome.RedirectDamage); + staticText = "flip a coin. If you lose the flip, the next time it would deal combat damage this turn, it deals that damage to you instead"; + } + + public GoblinPsychopathEffect(final GoblinPsychopathEffect effect) { + super(effect); + } + + @Override + public void init(Ability source, Game game) { + this.wonFlip = game.getPlayer(source.getControllerId()).flipCoin(game); + super.init(source, game); + } + + @Override + public GoblinPsychopathEffect copy() { + return new GoblinPsychopathEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGE_CREATURE || + event.getType() == GameEvent.EventType.DAMAGE_PLANESWALKER || + event.getType() == GameEvent.EventType.DAMAGE_PLAYER; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + MageObject object = game.getObject(event.getSourceId()); + if (object == null) { + game.informPlayers("Couldn't find source of damage"); + return false; + } + return event.getSourceId().equals(source.getSourceId()); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + MageObject object = game.getObject(event.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null && object != null) { + if (this.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) { + DamageEvent damageEvent = (DamageEvent) event; + if (damageEvent.isCombatDamage()) { + if (!wonFlip) { + // TODO: make this redirect damage from all blockers + controller.damage(event.getAmount(), source.getSourceId(), game, false, true); + String sourceLogName = source != null ? game.getObject(source.getSourceId()).getLogName() + ": " : ""; + game.informPlayers(sourceLogName + "Redirected " + event.getAmount() + " damage to " + controller.getLogName()); + this.discard(); + return true; + } + } + } + } + return false; + } +} From f8d7d7d7ab3cea11816d0d4e5dbe73a385ea930c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:57:03 +0100 Subject: [PATCH 09/52] Implemented Mogg Assassin --- Mage.Sets/src/mage/cards/m/MoggAssassin.java | 144 +++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MoggAssassin.java diff --git a/Mage.Sets/src/mage/cards/m/MoggAssassin.java b/Mage.Sets/src/mage/cards/m/MoggAssassin.java new file mode 100644 index 00000000000..b783ffd8eb6 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MoggAssassin.java @@ -0,0 +1,144 @@ +/* + * 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.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.filter.predicate.ObjectPlayer; +import mage.players.Player; +import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponentsCreaturePermanent; + +/** + * + * @author L_J + */ +public class MoggAssassin extends CardImpl { + + private final UUID originalId; + + public MoggAssassin(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}"); + this.subtype.add(SubType.GOBLIN); + this.subtype.add(SubType.ASSASSIN); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + //TODO: Make ability properly copiable + // {T}: You choose target creature an opponent controls, and that opponent chooses target creature. Flip a coin. If you win the flip, destroy the creature you chose. If you lose the flip, destroy the creature your opponent chose. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MoggAssassinEffect(), new TapSourceCost()); + ability.addTarget(new TargetOpponentsCreaturePermanent()); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + originalId = ability.getOriginalId(); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if(ability.getOriginalId().equals(originalId)) { + Player controller = game.getPlayer(ability.getControllerId()); + if(controller != null && ability.getTargets().get(0) != null) { + UUID opponentId = null; + if (game.getOpponents(controller.getId()).size() > 1) { + Permanent permanent = game.getPermanentOrLKIBattlefield(ability.getTargets().get(0).getFirstTarget()); + if (permanent != null) { + opponentId = permanent.getControllerId(); + } + } else { + opponentId = game.getOpponents(controller.getId()).iterator().next(); + } + if(opponentId != null) { + ability.getTargets().get(1).setTargetController(opponentId); + } + } + } + } + + public MoggAssassin(final MoggAssassin card) { + super(card); + this.originalId = card.originalId; + } + + @Override + public MoggAssassin copy() { + return new MoggAssassin(this); + } + +} + +class MoggAssassinEffect extends OneShotEffect { + + public MoggAssassinEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "You choose target creature an opponent controls, and that opponent chooses target creature. Flip a coin. If you win the flip, destroy the creature you chose. If you lose the flip, destroy the creature your opponent chose"; + } + + public MoggAssassinEffect(final MoggAssassinEffect effect) { + super(effect); + } + + @Override + public MoggAssassinEffect copy() { + return new MoggAssassinEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent chosenPermanent = game.getPermanent(source.getTargets().get(0).getFirstTarget()); + Permanent opponentsPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (controller.flipCoin(game)) { + if (chosenPermanent != null) { + chosenPermanent.destroy(source.getSourceId(), game, false); + return true; + } + } else { + if (opponentsPermanent != null) { + opponentsPermanent.destroy(source.getSourceId(), game, false); + return true; + } + } + } + return false; + } +} From fbe524794d7af9d79614de2ab1b5682d8e54a9d0 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 20:58:29 +0100 Subject: [PATCH 10/52] Sorted imports --- Mage.Sets/src/mage/cards/m/MoggAssassin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/m/MoggAssassin.java b/Mage.Sets/src/mage/cards/m/MoggAssassin.java index b783ffd8eb6..09fc83429b2 100644 --- a/Mage.Sets/src/mage/cards/m/MoggAssassin.java +++ b/Mage.Sets/src/mage/cards/m/MoggAssassin.java @@ -40,9 +40,9 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.Zone; +import mage.filter.predicate.ObjectPlayer; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.filter.predicate.ObjectPlayer; import mage.players.Player; import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetOpponentsCreaturePermanent; From 73b8c40e5df61333e1f6e01a6c353a0ca39a1e64 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 21:00:50 +0100 Subject: [PATCH 11/52] Implemented Fickle Efreet --- Mage.Sets/src/mage/sets/Prophecy.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Prophecy.java b/Mage.Sets/src/mage/sets/Prophecy.java index 1d2677b16c7..9f3172aa2f7 100644 --- a/Mage.Sets/src/mage/sets/Prophecy.java +++ b/Mage.Sets/src/mage/sets/Prophecy.java @@ -88,6 +88,7 @@ public class Prophecy extends ExpansionSet { cards.add(new SetCardInfo("Excavation", 33, Rarity.UNCOMMON, mage.cards.e.Excavation.class)); cards.add(new SetCardInfo("Fault Riders", 88, Rarity.COMMON, mage.cards.f.FaultRiders.class)); cards.add(new SetCardInfo("Fen Stalker", 64, Rarity.COMMON, mage.cards.f.FenStalker.class)); + cards.add(new SetCardInfo("Fickle Efreet", 89, Rarity.RARE, mage.cards.f.FickleEfreet.class)); cards.add(new SetCardInfo("Flameshot", 90, Rarity.UNCOMMON, mage.cards.f.Flameshot.class)); cards.add(new SetCardInfo("Flowering Field", 9, Rarity.UNCOMMON, mage.cards.f.FloweringField.class)); cards.add(new SetCardInfo("Foil", 34, Rarity.UNCOMMON, mage.cards.f.Foil.class)); From 5d8202f0aca496d10be3f58c67767f096ded8f0b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 21:01:47 +0100 Subject: [PATCH 12/52] Implemented Goblin Lyre --- Mage.Sets/src/mage/sets/IceAge.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java index 01deb964249..f7ca4d9134d 100644 --- a/Mage.Sets/src/mage/sets/IceAge.java +++ b/Mage.Sets/src/mage/sets/IceAge.java @@ -151,6 +151,7 @@ public class IceAge extends ExpansionSet { cards.add(new SetCardInfo("Glacial Chasm", 331, Rarity.UNCOMMON, mage.cards.g.GlacialChasm.class)); cards.add(new SetCardInfo("Glacial Crevasses", 187, Rarity.RARE, mage.cards.g.GlacialCrevasses.class)); cards.add(new SetCardInfo("Glacial Wall", 71, Rarity.UNCOMMON, mage.cards.g.GlacialWall.class)); + cards.add(new SetCardInfo("Goblin Lyre", 294, Rarity.RARE, mage.cards.g.GoblinLyre.class)); cards.add(new SetCardInfo("Goblin Mutant", 188, Rarity.UNCOMMON, mage.cards.g.GoblinMutant.class)); cards.add(new SetCardInfo("Goblin Snowman", 191, Rarity.UNCOMMON, mage.cards.g.GoblinSnowman.class)); cards.add(new SetCardInfo("Gorilla Pack", 135, Rarity.COMMON, mage.cards.g.GorillaPack.class)); From 0ccc6bef39d65e5953797d5f28ef27570495485c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 21:02:42 +0100 Subject: [PATCH 13/52] Implemented Goblin Psychopath --- Mage.Sets/src/mage/sets/Scourge.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Scourge.java b/Mage.Sets/src/mage/sets/Scourge.java index d3462236f71..122d20e4058 100644 --- a/Mage.Sets/src/mage/sets/Scourge.java +++ b/Mage.Sets/src/mage/sets/Scourge.java @@ -55,7 +55,7 @@ public class Scourge extends ExpansionSet { this.numBoosterRare = 1; this.ratioBoosterMythic = 0; cards.add(new SetCardInfo("Accelerated Mutation", 109, Rarity.COMMON, mage.cards.a.AcceleratedMutation.class)); - cards.add(new SetCardInfo("Ageless Sentinels", 1, Rarity.RARE, mage.cards.a.AgelessSentinels.class)); + cards.add(new SetCardInfo("Ageless Sentinels", 1, Rarity.RARE, mage.cards.a.AgelessSentinels.class)); cards.add(new SetCardInfo("Alpha Status", 110, Rarity.UNCOMMON, mage.cards.a.AlphaStatus.class)); cards.add(new SetCardInfo("Ambush Commander", 111, Rarity.RARE, mage.cards.a.AmbushCommander.class)); cards.add(new SetCardInfo("Ancient Ooze", 112, Rarity.RARE, mage.cards.a.AncientOoze.class)); @@ -66,7 +66,7 @@ public class Scourge extends ExpansionSet { cards.add(new SetCardInfo("Aven Liberator", 4, Rarity.COMMON, mage.cards.a.AvenLiberator.class)); cards.add(new SetCardInfo("Bladewing's Thrall", 55, Rarity.UNCOMMON, mage.cards.b.BladewingsThrall.class)); cards.add(new SetCardInfo("Bladewing the Risen", 136, Rarity.RARE, mage.cards.b.BladewingTheRisen.class)); - cards.add(new SetCardInfo("Bonethorn Valesk", 82, Rarity.COMMON, mage.cards.b.BonethornValesk.class)); + cards.add(new SetCardInfo("Bonethorn Valesk", 82, Rarity.COMMON, mage.cards.b.BonethornValesk.class)); cards.add(new SetCardInfo("Brain Freeze", 29, Rarity.UNCOMMON, mage.cards.b.BrainFreeze.class)); cards.add(new SetCardInfo("Break Asunder", 113, Rarity.COMMON, mage.cards.b.BreakAsunder.class)); cards.add(new SetCardInfo("Cabal Conditioning", 56, Rarity.RARE, mage.cards.c.CabalConditioning.class)); @@ -116,6 +116,7 @@ public class Scourge extends ExpansionSet { cards.add(new SetCardInfo("Frozen Solid", 36, Rarity.COMMON, mage.cards.f.FrozenSolid.class)); cards.add(new SetCardInfo("Gilded Light", 16, Rarity.UNCOMMON, mage.cards.g.GildedLight.class)); cards.add(new SetCardInfo("Goblin Brigand", 94, Rarity.COMMON, mage.cards.g.GoblinBrigand.class)); + cards.add(new SetCardInfo("Goblin Psychopath", 95, Rarity.UNCOMMON, mage.cards.g.GoblinPsychopath.class)); cards.add(new SetCardInfo("Goblin Warchief", 97, Rarity.UNCOMMON, mage.cards.g.GoblinWarchief.class)); cards.add(new SetCardInfo("Goblin War Strike", 96, Rarity.COMMON, mage.cards.g.GoblinWarStrike.class)); cards.add(new SetCardInfo("Grip of Chaos", 98, Rarity.RARE, mage.cards.g.GripOfChaos.class)); @@ -133,7 +134,7 @@ public class Scourge extends ExpansionSet { cards.add(new SetCardInfo("Mind's Desire", 41, Rarity.RARE, mage.cards.m.MindsDesire.class)); cards.add(new SetCardInfo("Mischievous Quanar", 42, Rarity.RARE, mage.cards.m.MischievousQuanar.class)); cards.add(new SetCardInfo("Misguided Rage", 99, Rarity.COMMON, mage.cards.m.MisguidedRage.class)); - cards.add(new SetCardInfo("Mistform Warchief", 43, Rarity.UNCOMMON, mage.cards.m.MistformWarchief.class)); + cards.add(new SetCardInfo("Mistform Warchief", 43, Rarity.UNCOMMON, mage.cards.m.MistformWarchief.class)); cards.add(new SetCardInfo("Nefashu", 70, Rarity.RARE, mage.cards.n.Nefashu.class)); cards.add(new SetCardInfo("Noble Templar", 19, Rarity.COMMON, mage.cards.n.NobleTemplar.class)); cards.add(new SetCardInfo("One with Nature", 125, Rarity.UNCOMMON, mage.cards.o.OneWithNature.class)); @@ -142,7 +143,7 @@ public class Scourge extends ExpansionSet { cards.add(new SetCardInfo("Putrid Raptor", 71, Rarity.UNCOMMON, mage.cards.p.PutridRaptor.class)); cards.add(new SetCardInfo("Pyrostatic Pillar", 100, Rarity.UNCOMMON, mage.cards.p.PyrostaticPillar.class)); cards.add(new SetCardInfo("Rain of Blades", 20, Rarity.UNCOMMON, mage.cards.r.RainOfBlades.class)); - cards.add(new SetCardInfo("Raven Guild Initiate", 46, Rarity.COMMON, mage.cards.r.RavenGuildInitiate.class)); + cards.add(new SetCardInfo("Raven Guild Initiate", 46, Rarity.COMMON, mage.cards.r.RavenGuildInitiate.class)); cards.add(new SetCardInfo("Raven Guild Master", 47, Rarity.RARE, mage.cards.r.RavenGuildMaster.class)); cards.add(new SetCardInfo("Reaping the Graves", 72, Rarity.COMMON, mage.cards.r.ReapingTheGraves.class)); cards.add(new SetCardInfo("Recuperate", 21, Rarity.COMMON, mage.cards.r.Recuperate.class)); From 53bde045d32b11f45de39386857c225444013853 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Sun, 5 Nov 2017 21:03:37 +0100 Subject: [PATCH 14/52] Implemented Mogg Assassin --- Mage.Sets/src/mage/sets/Exodus.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Exodus.java b/Mage.Sets/src/mage/sets/Exodus.java index 65d7537e62b..59c6cd1644f 100644 --- a/Mage.Sets/src/mage/sets/Exodus.java +++ b/Mage.Sets/src/mage/sets/Exodus.java @@ -76,7 +76,7 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Dauthi Warlord", 59, Rarity.UNCOMMON, mage.cards.d.DauthiWarlord.class)); cards.add(new SetCardInfo("Death's Duet", 60, Rarity.COMMON, mage.cards.d.DeathsDuet.class)); cards.add(new SetCardInfo("Dominating Licid", 30, Rarity.RARE, mage.cards.d.DominatingLicid.class)); - cards.add(new SetCardInfo("Elven Palisade", 109, Rarity.UNCOMMON, mage.cards.e.ElvenPalisade.class)); + cards.add(new SetCardInfo("Elven Palisade", 109, Rarity.UNCOMMON, mage.cards.e.ElvenPalisade.class)); cards.add(new SetCardInfo("Elvish Berserker", 110, Rarity.COMMON, mage.cards.e.ElvishBerserker.class)); cards.add(new SetCardInfo("Entropic Specter", 61, Rarity.RARE, mage.cards.e.EntropicSpecter.class)); cards.add(new SetCardInfo("Ephemeron", 31, Rarity.RARE, mage.cards.e.Ephemeron.class)); @@ -104,8 +104,9 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Merfolk Looter", 39, Rarity.COMMON, mage.cards.m.MerfolkLooter.class)); cards.add(new SetCardInfo("Mindless Automaton", 135, Rarity.RARE, mage.cards.m.MindlessAutomaton.class)); cards.add(new SetCardInfo("Mind Over Matter", 40, Rarity.RARE, mage.cards.m.MindOverMatter.class)); - cards.add(new SetCardInfo("Mirozel", 41, Rarity.UNCOMMON, mage.cards.m.Mirozel.class)); + cards.add(new SetCardInfo("Mirozel", 41, Rarity.UNCOMMON, mage.cards.m.Mirozel.class)); cards.add(new SetCardInfo("Mirri, Cat Warrior", 114, Rarity.RARE, mage.cards.m.MirriCatWarrior.class)); + cards.add(new SetCardInfo("Mogg Assassin", 88, Rarity.UNCOMMON, mage.cards.m.MoggAssassin.class)); cards.add(new SetCardInfo("Nausea", 67, Rarity.COMMON, mage.cards.n.Nausea.class)); cards.add(new SetCardInfo("Necrologia", 68, Rarity.UNCOMMON, mage.cards.n.Necrologia.class)); cards.add(new SetCardInfo("Null Brooch", 136, Rarity.RARE, mage.cards.n.NullBrooch.class)); @@ -123,7 +124,7 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Pit Spawn", 70, Rarity.RARE, mage.cards.p.PitSpawn.class)); cards.add(new SetCardInfo("Plaguebearer", 71, Rarity.RARE, mage.cards.p.Plaguebearer.class)); cards.add(new SetCardInfo("Plated Rootwalla", 116, Rarity.COMMON, mage.cards.p.PlatedRootwalla.class)); - cards.add(new SetCardInfo("Predatory Hunger", 117, Rarity.COMMON, mage.cards.p.PredatoryHunger.class)); + cards.add(new SetCardInfo("Predatory Hunger", 117, Rarity.COMMON, mage.cards.p.PredatoryHunger.class)); cards.add(new SetCardInfo("Price of Progress", 95, Rarity.UNCOMMON, mage.cards.p.PriceOfProgress.class)); cards.add(new SetCardInfo("Pygmy Troll", 118, Rarity.COMMON, mage.cards.p.PygmyTroll.class)); cards.add(new SetCardInfo("Rabid Wolverines", 119, Rarity.COMMON, mage.cards.r.RabidWolverines.class)); @@ -134,19 +135,19 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Reclaim", 120, Rarity.COMMON, mage.cards.r.Reclaim.class)); cards.add(new SetCardInfo("Reconnaissance", 17, Rarity.UNCOMMON, mage.cards.r.Reconnaissance.class)); cards.add(new SetCardInfo("Recurring Nightmare", 72, Rarity.RARE, mage.cards.r.RecurringNightmare.class)); - cards.add(new SetCardInfo("Resuscitate", 121, Rarity.UNCOMMON, mage.cards.r.Resuscitate.class)); + cards.add(new SetCardInfo("Resuscitate", 121, Rarity.UNCOMMON, mage.cards.r.Resuscitate.class)); cards.add(new SetCardInfo("Robe of Mirrors", 43, Rarity.COMMON, mage.cards.r.RobeOfMirrors.class)); cards.add(new SetCardInfo("Rootwater Alligator", 122, Rarity.COMMON, mage.cards.r.RootwaterAlligator.class)); cards.add(new SetCardInfo("Rootwater Mystic", 44, Rarity.COMMON, mage.cards.r.RootwaterMystic.class)); cards.add(new SetCardInfo("Sabertooth Wyvern", 99, Rarity.UNCOMMON, mage.cards.s.SabertoothWyvern.class)); - cards.add(new SetCardInfo("Scalding Salamander", 100, Rarity.UNCOMMON, mage.cards.s.ScaldingSalamander.class)); + cards.add(new SetCardInfo("Scalding Salamander", 100, Rarity.UNCOMMON, mage.cards.s.ScaldingSalamander.class)); cards.add(new SetCardInfo("Scare Tactics", 73, Rarity.COMMON, mage.cards.s.ScareTactics.class)); cards.add(new SetCardInfo("School of Piranha", 45, Rarity.COMMON, mage.cards.s.SchoolOfPiranha.class)); cards.add(new SetCardInfo("Scrivener", 46, Rarity.UNCOMMON, mage.cards.s.Scrivener.class)); cards.add(new SetCardInfo("Seismic Assault", 101, Rarity.RARE, mage.cards.s.SeismicAssault.class)); cards.add(new SetCardInfo("Shackles", 18, Rarity.COMMON, mage.cards.s.Shackles.class)); cards.add(new SetCardInfo("Shattering Pulse", 102, Rarity.COMMON, mage.cards.s.ShatteringPulse.class)); - cards.add(new SetCardInfo("Shield Mate", 19, Rarity.COMMON, mage.cards.s.ShieldMate.class)); + cards.add(new SetCardInfo("Shield Mate", 19, Rarity.COMMON, mage.cards.s.ShieldMate.class)); cards.add(new SetCardInfo("Skyshaper", 137, Rarity.UNCOMMON, mage.cards.s.Skyshaper.class)); cards.add(new SetCardInfo("Skyshroud Elite", 123, Rarity.UNCOMMON, mage.cards.s.SkyshroudElite.class)); cards.add(new SetCardInfo("Slaughter", 74, Rarity.UNCOMMON, mage.cards.s.Slaughter.class)); @@ -178,6 +179,6 @@ public class Exodus extends ExpansionSet { cards.add(new SetCardInfo("Whiptongue Frog", 52, Rarity.COMMON, mage.cards.w.WhiptongueFrog.class)); cards.add(new SetCardInfo("Wood Elves", 130, Rarity.COMMON, mage.cards.w.WoodElves.class)); cards.add(new SetCardInfo("Workhorse", 142, Rarity.RARE, mage.cards.w.Workhorse.class)); - cards.add(new SetCardInfo("Zealots en-Dal", 26, Rarity.UNCOMMON, mage.cards.z.ZealotsEnDal.class)); + cards.add(new SetCardInfo("Zealots en-Dal", 26, Rarity.UNCOMMON, mage.cards.z.ZealotsEnDal.class)); } } From ffde9d08868ef2820d1e8541129420c811fcfb18 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 00:19:41 +0100 Subject: [PATCH 15/52] Ugly fix for Mogg Assassin's targetting --- Mage.Sets/src/mage/cards/m/MoggAssassin.java | 47 +++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MoggAssassin.java b/Mage.Sets/src/mage/cards/m/MoggAssassin.java index 09fc83429b2..bb8225654c5 100644 --- a/Mage.Sets/src/mage/cards/m/MoggAssassin.java +++ b/Mage.Sets/src/mage/cards/m/MoggAssassin.java @@ -40,11 +40,16 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.Zone; -import mage.filter.predicate.ObjectPlayer; +import mage.game.Controllable; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.ObjectPlayer; +import mage.filter.predicate.ObjectPlayerPredicate; import mage.players.Player; +import mage.target.Target; import mage.target.common.TargetCreaturePermanent; +import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponentsCreaturePermanent; /** @@ -73,19 +78,29 @@ public class MoggAssassin extends CardImpl { @Override public void adjustTargets(Ability ability, Game game) { - if(ability.getOriginalId().equals(originalId)) { + if (ability.getOriginalId().equals(originalId)) { Player controller = game.getPlayer(ability.getControllerId()); - if(controller != null && ability.getTargets().get(0) != null) { + if (controller != null) { UUID opponentId = null; if (game.getOpponents(controller.getId()).size() > 1) { - Permanent permanent = game.getPermanentOrLKIBattlefield(ability.getTargets().get(0).getFirstTarget()); - if (permanent != null) { - opponentId = permanent.getControllerId(); + ability.getTargets().clear(); + Target target1 = new TargetOpponent(true); + if (controller.chooseTarget(Outcome.Neutral, target1, ability, game)) { + opponentId = target1.getFirstTarget(); + } else { + opponentId = game.getOpponents(controller.getId()).iterator().next(); } + FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature controlled by the chosen opponent"); + filter.add(new ChosenOpponentControlledPredicate(opponentId)); + Target target2 = new TargetCreaturePermanent(filter); + Target target3 = new TargetCreaturePermanent(); + ability.addTarget(target2); + ability.addTarget(target3); } else { opponentId = game.getOpponents(controller.getId()).iterator().next(); } - if(opponentId != null) { + + if (opponentId != null) { ability.getTargets().get(1).setTargetController(opponentId); } } @@ -104,6 +119,24 @@ public class MoggAssassin extends CardImpl { } +class ChosenOpponentControlledPredicate implements ObjectPlayerPredicate> { + + private final UUID controller; + + public ChosenOpponentControlledPredicate(UUID controller) { + this.controller = controller; + } + + @Override + public boolean apply(ObjectPlayer input, Game game) { + Controllable object = input.getObject(); + if (object.getControllerId().equals(controller)) { + return true; + } + return false; + } +} + class MoggAssassinEffect extends OneShotEffect { public MoggAssassinEffect() { From 471807fe3b3907c3cfd657c5a5fb1fdeb488a434 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 01:09:02 +0100 Subject: [PATCH 16/52] Much nicer targetting fix --- Mage.Sets/src/mage/cards/m/MoggAssassin.java | 37 +++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/Mage.Sets/src/mage/cards/m/MoggAssassin.java b/Mage.Sets/src/mage/cards/m/MoggAssassin.java index bb8225654c5..18cfb3c453b 100644 --- a/Mage.Sets/src/mage/cards/m/MoggAssassin.java +++ b/Mage.Sets/src/mage/cards/m/MoggAssassin.java @@ -40,16 +40,11 @@ import mage.constants.CardType; import mage.constants.SubType; import mage.constants.Outcome; import mage.constants.Zone; -import mage.game.Controllable; import mage.game.Game; import mage.game.permanent.Permanent; -import mage.filter.common.FilterCreaturePermanent; -import mage.filter.predicate.ObjectPlayer; -import mage.filter.predicate.ObjectPlayerPredicate; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; -import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponentsCreaturePermanent; /** @@ -83,19 +78,13 @@ public class MoggAssassin extends CardImpl { if (controller != null) { UUID opponentId = null; if (game.getOpponents(controller.getId()).size() > 1) { - ability.getTargets().clear(); - Target target1 = new TargetOpponent(true); - if (controller.chooseTarget(Outcome.Neutral, target1, ability, game)) { - opponentId = target1.getFirstTarget(); + Target target = ability.getTargets().get(0); + if (controller.chooseTarget(Outcome.DestroyPermanent, target, ability, game)) { + Permanent permanent = game.getPermanent(target.getFirstTarget()); + opponentId = permanent.getControllerId(); } else { opponentId = game.getOpponents(controller.getId()).iterator().next(); } - FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature controlled by the chosen opponent"); - filter.add(new ChosenOpponentControlledPredicate(opponentId)); - Target target2 = new TargetCreaturePermanent(filter); - Target target3 = new TargetCreaturePermanent(); - ability.addTarget(target2); - ability.addTarget(target3); } else { opponentId = game.getOpponents(controller.getId()).iterator().next(); } @@ -119,24 +108,6 @@ public class MoggAssassin extends CardImpl { } -class ChosenOpponentControlledPredicate implements ObjectPlayerPredicate> { - - private final UUID controller; - - public ChosenOpponentControlledPredicate(UUID controller) { - this.controller = controller; - } - - @Override - public boolean apply(ObjectPlayer input, Game game) { - Controllable object = input.getObject(); - if (object.getControllerId().equals(controller)) { - return true; - } - return false; - } -} - class MoggAssassinEffect extends OneShotEffect { public MoggAssassinEffect() { From 131ad04e800ad3190b410e9dc26ac59820c3c062 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 11:20:37 +0100 Subject: [PATCH 17/52] Implemented Loxodon Peacekeeper --- .../src/mage/cards/l/LoxodonPeacekeeper.java | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java diff --git a/Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java b/Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java new file mode 100644 index 00000000000..6154921fa10 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java @@ -0,0 +1,162 @@ +/* + * 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.l; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.effects.ContinuousEffect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.continuous.GainControlTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TargetController; +import mage.filter.FilterPlayer; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.other.PlayerIdPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class LoxodonPeacekeeper extends CardImpl { + + public LoxodonPeacekeeper(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}"); + this.subtype.add(SubType.ELEPHANT); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(4); + this.toughness = new MageInt(4); + + // At the beginning of your upkeep, the player with the lowest life total gains control of Loxodon Peacekeeper. If two or more players are tied for lowest life total, you choose one of them, and that player gains control of Loxodon Peacekeeper. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new LoxodonPeacekeeperEffect(), TargetController.YOU, false)); + + } + + public LoxodonPeacekeeper(final LoxodonPeacekeeper card) { + super(card); + } + + @Override + public LoxodonPeacekeeper copy() { + return new LoxodonPeacekeeper(this); + } +} + +class LoxodonPeacekeeperEffect extends OneShotEffect { + + public LoxodonPeacekeeperEffect() { + super(Outcome.Benefit); + this.staticText = "the player with the lowest life total gains control of {this}. If two or more players are tied for lowest life total, you choose one of them, and that player gains control of {this}"; + } + + public LoxodonPeacekeeperEffect(final LoxodonPeacekeeperEffect effect) { + super(effect); + } + + @Override + public LoxodonPeacekeeperEffect copy() { + return new LoxodonPeacekeeperEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (sourcePermanent != null) { + int lowLife = Integer.MAX_VALUE; + Set tiedPlayers = new HashSet<>(); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.getLife() < lowLife) { + lowLife = player.getLife(); + } + } + } + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + if (player.getLife() == lowLife) { + tiedPlayers.add(playerId); + } + } + } + + if (tiedPlayers.size() > 0) { + UUID newControllerId = null; + if (tiedPlayers.size() > 1) { + FilterPlayer filter = new FilterPlayer("a player tied for lowest life total"); + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + if (!tiedPlayers.contains(playerId)) { + filter.add(Predicates.not(new PlayerIdPredicate(playerId))); + } + } + TargetPlayer target = new TargetPlayer(1, 1, true, filter); + if (target.canChoose(source.getSourceId(), controller.getId(), game)) { + while (!target.isChosen() && target.canChoose(controller.getId(), game) && controller.canRespond()) { + controller.chooseTarget(outcome, target, source, game); + } + } else { + return false; + } + newControllerId = game.getPlayer(target.getFirstTarget()).getId(); + } else { + for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { + if (tiedPlayers.contains(playerId)) { + newControllerId = playerId; + game.informPlayers(game.getPlayer(playerId).getLogName() + " has gained control of " + sourcePermanent.getLogName()); + + } + } + } + if (newControllerId != null) { + ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, newControllerId); + effect.setTargetPointer(new FixedTarget(sourcePermanent, game)); + game.addEffect(effect, source); + return true; + } + } + } + } + return false; + } +} From bf85dca9f7229cff7512742f3e90bb4e491656b6 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 11:20:49 +0100 Subject: [PATCH 18/52] Implemented Loxodon Peacekeeper --- Mage.Sets/src/mage/sets/Mirrodin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Mirrodin.java b/Mage.Sets/src/mage/sets/Mirrodin.java index a8f3fc7340b..f2d02d8f864 100644 --- a/Mage.Sets/src/mage/sets/Mirrodin.java +++ b/Mage.Sets/src/mage/sets/Mirrodin.java @@ -150,6 +150,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Lodestone Myr", 200, Rarity.RARE, mage.cards.l.LodestoneMyr.class)); cards.add(new SetCardInfo("Looming Hoverguard", 38, Rarity.UNCOMMON, mage.cards.l.LoomingHoverguard.class)); cards.add(new SetCardInfo("Loxodon Mender", 12, Rarity.COMMON, mage.cards.l.LoxodonMender.class)); + cards.add(new SetCardInfo("Loxodon Peacekeeper", 13, Rarity.RARE, mage.cards.l.LoxodonPeacekeeper.class)); cards.add(new SetCardInfo("Loxodon Punisher", 14, Rarity.RARE, mage.cards.l.LoxodonPunisher.class)); cards.add(new SetCardInfo("Loxodon Warhammer", 201, Rarity.UNCOMMON, mage.cards.l.LoxodonWarhammer.class)); cards.add(new SetCardInfo("Lumengrid Sentinel", 40, Rarity.UNCOMMON, mage.cards.l.LumengridSentinel.class)); From d5af4ad4b3ab2f34d599e17f49365c2310ba5841 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 11:34:52 +0100 Subject: [PATCH 19/52] informPlayers improvements --- Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java b/Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java index 6154921fa10..c06d39dea45 100644 --- a/Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java +++ b/Mage.Sets/src/mage/cards/l/LoxodonPeacekeeper.java @@ -143,8 +143,7 @@ class LoxodonPeacekeeperEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { if (tiedPlayers.contains(playerId)) { newControllerId = playerId; - game.informPlayers(game.getPlayer(playerId).getLogName() + " has gained control of " + sourcePermanent.getLogName()); - + break; } } } @@ -152,6 +151,7 @@ class LoxodonPeacekeeperEffect extends OneShotEffect { ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, newControllerId); effect.setTargetPointer(new FixedTarget(sourcePermanent, game)); game.addEffect(effect, source); + game.informPlayers(game.getPlayer(newControllerId).getLogName() + " has gained control of " + sourcePermanent.getLogName()); return true; } } From 4cf6e22be6cb6fb7a7a67cbb0d34ff03a8fc51c7 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 13:17:47 +0100 Subject: [PATCH 20/52] Implemented Lumengrid Augur --- .../src/mage/cards/l/LumengridAugur.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LumengridAugur.java diff --git a/Mage.Sets/src/mage/cards/l/LumengridAugur.java b/Mage.Sets/src/mage/cards/l/LumengridAugur.java new file mode 100644 index 00000000000..10c15e651c8 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LumengridAugur.java @@ -0,0 +1,111 @@ +/* + * 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.l; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author L_J + */ +public class LumengridAugur extends CardImpl { + + public LumengridAugur(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}"); + this.subtype.add(SubType.VEDALKEN); + this.subtype.add(SubType.WIZARD); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // {1}, {T}: Target player draws a card, then discards a card. If that player discards an artifact card this way, untap Lumengrid Augur. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LumengridAugurEffect(), new GenericManaCost(1)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public LumengridAugur(final LumengridAugur card) { + super(card); + } + + @Override + public LumengridAugur copy() { + return new LumengridAugur(this); + } +} + +class LumengridAugurEffect extends OneShotEffect { + + public LumengridAugurEffect() { + super(Outcome.DrawCard); + staticText = "Target player draws a card, then discards a card. If that player discards an artifact card this way, untap {this}"; + } + + public LumengridAugurEffect(final LumengridAugurEffect effect) { + super(effect); + } + + @Override + public LumengridAugurEffect copy() { + return new LumengridAugurEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); + Permanent sourcePermanent = game.getPermanent(source.getSourceId()); + if (player != null) { + player.drawCards(1, game); + Card discardedCard = player.discardOne(false, source, game); + if (discardedCard != null && discardedCard.isArtifact()) { + if (sourcePermanent != null) { + sourcePermanent.untap(game); + } + } + return true; + } + return false; + } +} From 49b40432e3554f0f85813109c1288185f68fde5c Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 13:18:33 +0100 Subject: [PATCH 21/52] Implemented Myr Prototype --- Mage.Sets/src/mage/cards/m/MyrPrototype.java | 112 +++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MyrPrototype.java diff --git a/Mage.Sets/src/mage/cards/m/MyrPrototype.java b/Mage.Sets/src/mage/cards/m/MyrPrototype.java new file mode 100644 index 00000000000..0a451bb2931 --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MyrPrototype.java @@ -0,0 +1,112 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.m; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.mana.ManaCosts; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.combat.CantAttackBlockUnlessPaysSourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; +import mage.constants.Zone; +import mage.counters.CounterType; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; + +/** + * + * @author emerald000 & L_J + */ +public class MyrPrototype extends CardImpl { + + public MyrPrototype(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{5}"); + this.subtype.add(SubType.MYR); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // At the beginning of your upkeep, put a +1/+1 counter on Myr Prototype. + this.addAbility(new BeginningOfUpkeepTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), TargetController.YOU, false)); + + // Myr Prototype can't attack or block unless you pay {1} for each +1/+1 counter on it. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MyrPrototypeCantAttackUnlessYouPayEffect())); + } + + public MyrPrototype(final MyrPrototype card) { + super(card); + } + + @Override + public MyrPrototype copy() { + return new MyrPrototype(this); + } +} + +class MyrPrototypeCantAttackUnlessYouPayEffect extends CantAttackBlockUnlessPaysSourceEffect { + + MyrPrototypeCantAttackUnlessYouPayEffect() { + super(new ManaCostsImpl("{0}"), RestrictType.ATTACK_AND_BLOCK); + staticText = "{this} can't attack or block unless you pay {1} for each +1/+1 counter on it"; + } + + MyrPrototypeCantAttackUnlessYouPayEffect(MyrPrototypeCantAttackUnlessYouPayEffect effect) { + super(effect); + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return source.getSourceId().equals(event.getSourceId()); + } + + @Override + public ManaCosts getManaCostToPay(GameEvent event, Ability source, Game game) { + Permanent sourceObject = game.getPermanent(source.getSourceId()); + if (sourceObject != null) { + int counter = sourceObject.getCounters(game).getCount(CounterType.P1P1); + if (counter > 0) { + return new ManaCostsImpl<>("{" + counter + '}'); + } + } + return null; + } + + @Override + public MyrPrototypeCantAttackUnlessYouPayEffect copy() { + return new MyrPrototypeCantAttackUnlessYouPayEffect(this); + } + +} From 6fc977c843551b19bd9773e3a7e6ffeb9acc86ba Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 13:20:23 +0100 Subject: [PATCH 22/52] Implemented Lumengrid Augur and Myr Prototype --- Mage.Sets/src/mage/sets/Mirrodin.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Mirrodin.java b/Mage.Sets/src/mage/sets/Mirrodin.java index f2d02d8f864..d1fd1c453b4 100644 --- a/Mage.Sets/src/mage/sets/Mirrodin.java +++ b/Mage.Sets/src/mage/sets/Mirrodin.java @@ -153,6 +153,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Loxodon Peacekeeper", 13, Rarity.RARE, mage.cards.l.LoxodonPeacekeeper.class)); cards.add(new SetCardInfo("Loxodon Punisher", 14, Rarity.RARE, mage.cards.l.LoxodonPunisher.class)); cards.add(new SetCardInfo("Loxodon Warhammer", 201, Rarity.UNCOMMON, mage.cards.l.LoxodonWarhammer.class)); + cards.add(new SetCardInfo("Lumengrid Augur", 39, Rarity.RARE, mage.cards.l.LumengridAugur.class)); cards.add(new SetCardInfo("Lumengrid Sentinel", 40, Rarity.UNCOMMON, mage.cards.l.LumengridSentinel.class)); cards.add(new SetCardInfo("Lumengrid Warden", 41, Rarity.COMMON, mage.cards.l.LumengridWarden.class)); cards.add(new SetCardInfo("Luminous Angel", 15, Rarity.RARE, mage.cards.l.LuminousAngel.class)); @@ -176,6 +177,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Myr Enforcer", 211, Rarity.COMMON, mage.cards.m.MyrEnforcer.class)); cards.add(new SetCardInfo("Myr Incubator", 212, Rarity.RARE, mage.cards.m.MyrIncubator.class)); cards.add(new SetCardInfo("Myr Mindservant", 213, Rarity.UNCOMMON, mage.cards.m.MyrMindservant.class)); + cards.add(new SetCardInfo("Myr Prototype", 214, Rarity.UNCOMMON, mage.cards.m.MyrPrototype.class)); cards.add(new SetCardInfo("Myr Retriever", 215, Rarity.UNCOMMON, mage.cards.m.MyrRetriever.class)); cards.add(new SetCardInfo("Necrogen Mists", 69, Rarity.RARE, mage.cards.n.NecrogenMists.class)); cards.add(new SetCardInfo("Necrogen Spellbomb", 216, Rarity.COMMON, mage.cards.n.NecrogenSpellbomb.class)); From 3509bdfa565d1e90c39733b5cef3df6249874217 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 20:44:32 +0100 Subject: [PATCH 23/52] Implemented Maddening Imp --- Mage.Sets/src/mage/cards/m/MaddeningImp.java | 200 +++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/m/MaddeningImp.java diff --git a/Mage.Sets/src/mage/cards/m/MaddeningImp.java b/Mage.Sets/src/mage/cards/m/MaddeningImp.java new file mode 100644 index 00000000000..e56010487fa --- /dev/null +++ b/Mage.Sets/src/mage/cards/m/MaddeningImp.java @@ -0,0 +1,200 @@ +/* + * 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.m; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.condition.InvertCondition; +import mage.abilities.condition.common.TargetAttackedThisTurnCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.decorator.ConditionalActivatedAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.combat.AttacksIfAbleAllEffect; +import mage.abilities.keyword.FlyingAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterCreaturePermanent; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.SubtypePredicate; +import mage.filter.predicate.permanent.ControllerPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.watchers.common.AttackedThisTurnWatcher; + +/** + * + * @author L_J + */ +public class MaddeningImp extends CardImpl { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Wall creatures"); + + static { + filter.add(Predicates.not(new SubtypePredicate(SubType.WALL))); + filter.add(new ControllerPredicate(TargetController.ACTIVE)); + filter.setMessage("non-Wall creatures the active player controls"); + } + + public MaddeningImp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}"); + this.subtype.add(SubType.IMP); + this.power = new MageInt(1); + this.toughness = new MageInt(1); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // {T}: Non-Wall creatures the active player controls attack this turn if able. At the beginning of the next end step, destroy each of those creatures that didn't attack this turn. Activate this ability only during an opponent's turn and only before combat. + Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new AttacksIfAbleAllEffect(filter, Duration.EndOfTurn), + new TapSourceCost(), new MaddeningImpTurnCondition(), + "{T}: Non-Wall creatures the active player controls attack this turn if able. " + + "At the beginning of the next end step, destroy each of those creatures that didn't attack this turn. " + + "Activate this ability only during an opponent's turn and only before combat."); + ability.addEffect(new MaddeningImpCreateDelayedTriggeredAbilityEffect()); + this.addAbility(ability, new AttackedThisTurnWatcher()); + + } + + public MaddeningImp(final MaddeningImp card) { + super(card); + } + + @Override + public MaddeningImp copy() { + return new MaddeningImp(this); + } +} + +class MaddeningImpTurnCondition implements Condition { + + @Override + public boolean apply(Game game, Ability source) { + Player activePlayer = game.getPlayer(game.getActivePlayerId()); + return activePlayer != null && activePlayer.hasOpponent(source.getControllerId(), game) && game.getPhase().getStep().getType().getIndex() < 5; + } + + @Override + public String toString() { + return ""; + } +} + +class MaddeningImpCreateDelayedTriggeredAbilityEffect extends OneShotEffect { + + private static final FilterCreaturePermanent filter = new FilterCreaturePermanent(); + + static { + filter.add(Predicates.not(new SubtypePredicate(SubType.WALL))); + filter.add(new ControllerPredicate(TargetController.ACTIVE)); + } + + public MaddeningImpCreateDelayedTriggeredAbilityEffect() { + super(Outcome.DestroyPermanent); + this.staticText = "At the beginning of the next end step, destroy each of those creatures that didn't attack this turn"; + } + + public MaddeningImpCreateDelayedTriggeredAbilityEffect(final MaddeningImpCreateDelayedTriggeredAbilityEffect effect) { + super(effect); + } + + @Override + public MaddeningImpCreateDelayedTriggeredAbilityEffect copy() { + return new MaddeningImpCreateDelayedTriggeredAbilityEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(game.getActivePlayerId()); + if (player != null) { + Set activeCreatures = new HashSet<>(); + for (Permanent creature : game.getBattlefield().getAllActivePermanents(filter, player.getId(), game)) { + if (creature != null) { + activeCreatures.add(new MageObjectReference(creature, game)); + } + } + AtTheBeginOfNextEndStepDelayedTriggeredAbility delayedAbility + = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(Zone.ALL, new MaddeningImpDelayedDestroyEffect(activeCreatures), TargetController.ANY, new InvertCondition(TargetAttackedThisTurnCondition.instance)); + delayedAbility.getDuration(); + game.addDelayedTriggeredAbility(delayedAbility, source); + return true; + } + return false; + } +} + +class MaddeningImpDelayedDestroyEffect extends OneShotEffect { + + private Set activeCreatures; + + MaddeningImpDelayedDestroyEffect(Set activeCreatures) { + super(Outcome.DestroyPermanent); + this.activeCreatures = activeCreatures; + this.staticText = "At the beginning of the next end step, destroy each of those creatures that didn't attack this turn"; + } + + MaddeningImpDelayedDestroyEffect(final MaddeningImpDelayedDestroyEffect effect) { + super(effect); + this.activeCreatures = effect.activeCreatures; + } + + @Override + public MaddeningImpDelayedDestroyEffect copy() { + return new MaddeningImpDelayedDestroyEffect(this); + } + + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(game.getActivePlayerId()); + if (player != null) { + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(player.getId())) { + + MageObjectReference mor = new MageObjectReference(permanent, game); + // Only affect permanents present when the ability resolved + if (!activeCreatures.contains(mor)) { + continue; + } + // Creatures that attacked are safe. + AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get(AttackedThisTurnWatcher.class.getSimpleName()); + if (watcher != null && watcher.getAttackedThisTurnCreatures().contains(mor)) { + continue; + } + // Destroy the rest. + permanent.destroy(source.getSourceId(), game, false); + } + return true; + } + return false; + } +} From 137d1be277bbf335d2b771f95b57dc45ead4b2dc Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 20:44:49 +0100 Subject: [PATCH 24/52] Implemented Reap --- Mage.Sets/src/mage/cards/r/Reap.java | 95 ++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/r/Reap.java diff --git a/Mage.Sets/src/mage/cards/r/Reap.java b/Mage.Sets/src/mage/cards/r/Reap.java new file mode 100644 index 00000000000..242acfd7f40 --- /dev/null +++ b/Mage.Sets/src/mage/cards/r/Reap.java @@ -0,0 +1,95 @@ +/* + * 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.r; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.SpellAbility; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.game.Game; +import mage.filter.FilterCard; +import mage.filter.FilterPermanent; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.players.Player; +import mage.target.Target; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.common.TargetOpponent; + +/** + * + * @author L_J + */ +public class Reap extends CardImpl { + + private static final FilterPermanent filter = new FilterPermanent("black permanents"); + + static { + filter.add(new ColorPredicate(ObjectColor.BLACK)); + } + + public Reap(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{G}"); + + // Return up to X target cards from your graveyard to your hand, where X is the number of black permanents target opponent controls as you cast Reap. + this.getSpellAbility().addEffect(new ReturnToHandTargetEffect().setText("Return up to X target cards from your graveyard to your hand, where X is the number of black permanents target opponent controls as you cast Reap.")); + this.getSpellAbility().addTarget(new TargetOpponent()); + this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, 0, new FilterCard("cards from your graveyard"))); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if (ability instanceof SpellAbility) { + Player controller = game.getPlayer(ability.getControllerId()); + if (controller != null) { + ability.getTargets().clear(); + UUID opponentId = null; + Target target = new TargetOpponent(); + if (controller.chooseTarget(Outcome.ReturnToHand, target, ability, game)) { + opponentId = target.getFirstTarget(); + } + int numbTargets = game.getBattlefield().getAllActivePermanents(filter, opponentId, game).size(); + ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, new FilterCard("cards from your graveyard"))); + } + } + } + + + public Reap(final Reap card) { + super(card); + } + + @Override + public Reap copy() { + return new Reap(this); + } +} From b04947886040a5c3f9633e3221baf64bb93182ac Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 20:46:52 +0100 Subject: [PATCH 25/52] Implemented Maddening Imp and Reap --- Mage.Sets/src/mage/sets/Tempest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Tempest.java b/Mage.Sets/src/mage/sets/Tempest.java index eb67ac2a83b..a42508ca057 100644 --- a/Mage.Sets/src/mage/sets/Tempest.java +++ b/Mage.Sets/src/mage/sets/Tempest.java @@ -182,6 +182,7 @@ public class Tempest extends ExpansionSet { cards.add(new SetCardInfo("Lobotomy", 342, Rarity.UNCOMMON, mage.cards.l.Lobotomy.class)); cards.add(new SetCardInfo("Lotus Petal", 284, Rarity.COMMON, mage.cards.l.LotusPetal.class)); cards.add(new SetCardInfo("Lowland Giant", 187, Rarity.COMMON, mage.cards.l.LowlandGiant.class)); + cards.add(new SetCardInfo("Maddening Imp", 37, Rarity.RARE, mage.cards.m.MaddeningImp.class)); cards.add(new SetCardInfo("Magmasaur", 188, Rarity.RARE, mage.cards.m.Magmasaur.class)); cards.add(new SetCardInfo("Manakin", 286, Rarity.COMMON, mage.cards.m.Manakin.class)); cards.add(new SetCardInfo("Mana Severance", 73, Rarity.RARE, mage.cards.m.ManaSeverance.class)); @@ -244,6 +245,7 @@ public class Tempest extends ExpansionSet { cards.add(new SetCardInfo("Rats of Rath", 44, Rarity.COMMON, mage.cards.r.RatsOfRath.class)); cards.add(new SetCardInfo("Reality Anchor", 140, Rarity.COMMON, mage.cards.r.RealityAnchor.class)); cards.add(new SetCardInfo("Reanimate", 45, Rarity.UNCOMMON, mage.cards.r.Reanimate.class)); + cards.add(new SetCardInfo("Reap", 141, Rarity.UNCOMMON, mage.cards.r.Reap.class)); cards.add(new SetCardInfo("Reckless Spite", 46, Rarity.UNCOMMON, mage.cards.r.RecklessSpite.class)); cards.add(new SetCardInfo("Recycle", 142, Rarity.RARE, mage.cards.r.Recycle.class)); cards.add(new SetCardInfo("Reflecting Pool", 328, Rarity.RARE, mage.cards.r.ReflectingPool.class)); From 79bbca50d8c2cb367efa1a1797fe46e5eabbc954 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 21:03:36 +0100 Subject: [PATCH 26/52] Removed Tsabo's Assassin duplicate --- Mage.Sets/src/mage/sets/Invasion.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Invasion.java b/Mage.Sets/src/mage/sets/Invasion.java index 1a287d0fe72..acceed6c7e9 100644 --- a/Mage.Sets/src/mage/sets/Invasion.java +++ b/Mage.Sets/src/mage/sets/Invasion.java @@ -345,7 +345,6 @@ public class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Tsabo's Decree", 129, Rarity.RARE, mage.cards.t.TsabosDecree.class)); cards.add(new SetCardInfo("Tsabo's Web", 317, Rarity.RARE, mage.cards.t.TsabosWeb.class)); cards.add(new SetCardInfo("Tsabo Tavoc", 281, Rarity.RARE, mage.cards.t.TsaboTavoc.class)); - cards.add(new SetCardInfo("Tsabo's Assassin", 128, Rarity.RARE, mage.cards.t.TsabosAssassin.class)); cards.add(new SetCardInfo("Turf Wound", 177, Rarity.COMMON, mage.cards.t.TurfWound.class)); cards.add(new SetCardInfo("Twilight's Call", 130, Rarity.RARE, mage.cards.t.TwilightsCall.class)); cards.add(new SetCardInfo("Undermine", 282, Rarity.RARE, mage.cards.u.Undermine.class)); From aae9cbefaec9446519abac6c760097d5cd450bd1 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 21:06:19 +0100 Subject: [PATCH 27/52] Fixed Soul Burn numbering --- Mage.Sets/src/mage/sets/Invasion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/sets/Invasion.java b/Mage.Sets/src/mage/sets/Invasion.java index acceed6c7e9..a0d5f71e373 100644 --- a/Mage.Sets/src/mage/sets/Invasion.java +++ b/Mage.Sets/src/mage/sets/Invasion.java @@ -292,7 +292,7 @@ public class Invasion extends ExpansionSet { cards.add(new SetCardInfo("Slimy Kavu", 170, Rarity.COMMON, mage.cards.s.SlimyKavu.class)); cards.add(new SetCardInfo("Slinking Serpent", 274, Rarity.UNCOMMON, mage.cards.s.SlinkingSerpent.class)); cards.add(new SetCardInfo("Smoldering Tar", 275, Rarity.UNCOMMON, mage.cards.s.SmolderingTar.class)); - cards.add(new SetCardInfo("Soul Burn", 351, Rarity.COMMON, mage.cards.s.SoulBurn.class)); + cards.add(new SetCardInfo("Soul Burn", 124, Rarity.COMMON, mage.cards.s.SoulBurn.class)); cards.add(new SetCardInfo("Sparring Golem", 312, Rarity.UNCOMMON, mage.cards.s.SparringGolem.class)); cards.add(new SetCardInfo("Spinal Embrace", 276, Rarity.RARE, mage.cards.s.SpinalEmbrace.class)); cards.add(new SetCardInfo("Spirit of Resistance", 38, Rarity.RARE, mage.cards.s.SpiritOfResistance.class)); From 8eb5c3a70e095cda8aa68ab4a73f9cc3273269e4 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 21:44:50 +0100 Subject: [PATCH 28/52] Implemented Surprise Deployment --- .../src/mage/cards/s/SurpriseDeployment.java | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SurpriseDeployment.java diff --git a/Mage.Sets/src/mage/cards/s/SurpriseDeployment.java b/Mage.Sets/src/mage/cards/s/SurpriseDeployment.java new file mode 100644 index 00000000000..6eafd6e0767 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SurpriseDeployment.java @@ -0,0 +1,132 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.s; + +import java.util.UUID; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.DelayedTriggeredAbility; +import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; +import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.TurnPhase; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.filter.predicate.Predicates; +import mage.filter.predicate.mageobject.ColorPredicate; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class SurpriseDeployment extends CardImpl { + + public SurpriseDeployment(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{W}"); + + // Cast Surprise Deployment only during combat. + this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT)); + + // You may put a nonwhite creature card from your hand onto the battlefield. At the beginning of the next end step, return that creature to your hand. (Return it only if it's on the battlefield.) + this.getSpellAbility().addEffect(new SurpriseDeploymentEffect()); + } + + public SurpriseDeployment(final SurpriseDeployment card) { + super(card); + } + + @Override + public SurpriseDeployment copy() { + return new SurpriseDeployment(this); + } +} + +class SurpriseDeploymentEffect extends OneShotEffect { + + private static final String choiceText = "Put a nonwhite creature card from your hand onto the battlefield?"; + + private static final FilterCreatureCard filter = new FilterCreatureCard(); + + static { + filter.add(Predicates.not(new ColorPredicate(ObjectColor.WHITE))); + } + + public SurpriseDeploymentEffect() { + super(Outcome.Benefit); + this.staticText = "You may put a nonwhite creature card from your hand onto the battlefield. At the beginning of the next end step, return that creature to your hand"; + } + + public SurpriseDeploymentEffect(final SurpriseDeploymentEffect effect) { + super(effect); + } + + @Override + public SurpriseDeploymentEffect copy() { + return new SurpriseDeploymentEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + if (controller.chooseUse(Outcome.PutCreatureInPlay, choiceText, source, game)) { + TargetCardInHand target = new TargetCardInHand(filter); + if (controller.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) { + Card card = game.getCard(target.getFirstTarget()); + if (card != null) { + if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) { + Permanent permanent = game.getPermanent(card.getId()); + if (permanent != null) { + ReturnToHandTargetEffect effect = new ReturnToHandTargetEffect(); + effect.setTargetPointer(new FixedTarget(permanent, game)); + DelayedTriggeredAbility delayedAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect); + game.addDelayedTriggeredAbility(delayedAbility, source); + return true; + } + } + } + return false; + } + } + return true; + } + return false; + } +} From 5cb7506cfede9e100e0744268b8d6da632491721 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Tue, 7 Nov 2017 21:46:15 +0100 Subject: [PATCH 29/52] Implemented Surprise Deployment --- Mage.Sets/src/mage/sets/Planeshift.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Planeshift.java b/Mage.Sets/src/mage/sets/Planeshift.java index c44e08f37cf..bc0f02483c6 100644 --- a/Mage.Sets/src/mage/sets/Planeshift.java +++ b/Mage.Sets/src/mage/sets/Planeshift.java @@ -181,6 +181,7 @@ public class Planeshift extends ExpansionSet { cards.add(new SetCardInfo("Sunken Hope", 37, Rarity.RARE, mage.cards.s.SunkenHope.class)); cards.add(new SetCardInfo("Sunscape Battlemage", 16, Rarity.UNCOMMON, mage.cards.s.SunscapeBattlemage.class)); cards.add(new SetCardInfo("Sunscape Familiar", 17, Rarity.COMMON, mage.cards.s.SunscapeFamiliar.class)); + cards.add(new SetCardInfo("Surprise Deployment", 18, Rarity.UNCOMMON, mage.cards.s.SurpriseDeployment.class)); cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74a", Rarity.RARE, TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Tahngarth, Talruum Hero", "74b", Rarity.RARE, TahngarthTalruumHero.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Terminal Moraine", 142, Rarity.UNCOMMON, mage.cards.t.TerminalMoraine.class)); From 2de676d17ec017768367f7e063b1bc0864ca33da Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 11:42:30 +0100 Subject: [PATCH 30/52] Implemented Holistic Wisdom --- .../src/mage/cards/h/HolisticWisdom.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/h/HolisticWisdom.java diff --git a/Mage.Sets/src/mage/cards/h/HolisticWisdom.java b/Mage.Sets/src/mage/cards/h/HolisticWisdom.java new file mode 100644 index 00000000000..0b5e4f6e6e5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/h/HolisticWisdom.java @@ -0,0 +1,118 @@ +/* + * 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.ArrayList; +import java.util.List; +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.Cost; +import mage.abilities.costs.common.ExileFromHandCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.Effect; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.ReturnToHandTargetEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.FilterCard; +import mage.game.Game; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetCardInYourGraveyard; +import mage.target.targetpointer.FixedTarget; + +/** + * + * @author L_J + */ +public class HolisticWisdom extends CardImpl { + + public HolisticWisdom(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{G}{G}"); + + // {2}, Exile a card from your hand: Return target card from your graveyard to your hand if it shares a card type with the card exiled this way. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new HolisticWisdomEffect(), new ManaCostsImpl("{2}")); + ability.addCost(new ExileFromHandCost(new TargetCardInHand(new FilterCard("a card from your hand")))); + ability.addTarget(new TargetCardInYourGraveyard()); + this.addAbility(ability); + } + + public HolisticWisdom(final HolisticWisdom card) { + super(card); + } + + @Override + public HolisticWisdom copy() { + return new HolisticWisdom(this); + } +} + +class HolisticWisdomEffect extends OneShotEffect { + + public HolisticWisdomEffect() { + super(Outcome.ReturnToHand); + this.staticText = "Return target card from your graveyard to your hand if it shares a card type with the card exiled this way"; + } + + public HolisticWisdomEffect(final HolisticWisdomEffect effect) { + super(effect); + } + + @Override + public HolisticWisdomEffect copy() { + return new HolisticWisdomEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Card card = game.getCard(source.getFirstTarget()); + if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) { + for (Cost cost : source.getCosts()) { + if (cost instanceof ExileFromHandCost) { + List cardtypes = new ArrayList<>(); + ExileFromHandCost exileCost = (ExileFromHandCost) cost; + for (CardType cardtype : exileCost.getCards().get(0).getCardType()) { + cardtypes.add(cardtype); + } + for (CardType cardtype : card.getCardType()) { + if (cardtypes.contains(cardtype)) { + Effect effect = new ReturnToHandTargetEffect(); + effect.setTargetPointer(new FixedTarget(card.getId())); + return effect.apply(game, source); + } + } + } + } + } + return false; + } +} From f6bcc4bf0d0eabeb034fb44441045d2f25378a16 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 11:43:12 +0100 Subject: [PATCH 31/52] Implemented Phantom Whelp --- Mage.Sets/src/mage/cards/p/PhantomWhelp.java | 70 ++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PhantomWhelp.java diff --git a/Mage.Sets/src/mage/cards/p/PhantomWhelp.java b/Mage.Sets/src/mage/cards/p/PhantomWhelp.java new file mode 100644 index 00000000000..ace645b93e0 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PhantomWhelp.java @@ -0,0 +1,70 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.p; + +import java.util.UUID; +import mage.MageInt; +import mage.abilities.common.AttacksOrBlocksTriggeredAbility; +import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ReturnToHandSourceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; + +/** + * + * @author fireshoes & L_J + */ +public class PhantomWhelp extends CardImpl { + + public PhantomWhelp(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}"); + this.subtype.add(SubType.ILLUSION); + this.subtype.add(SubType.HOUND); + this.power = new MageInt(2); + this.toughness = new MageInt(2); + + // When Phantom Whelp attacks or blocks, return it to its owner's hand at end of combat. (Return it only if it's on the battlefield.) + Effect effect = new CreateDelayedTriggeredAbilityEffect( + new AtTheEndOfCombatDelayedTriggeredAbility(new ReturnToHandSourceEffect(true))); + effect.setText("return it to its owner's hand at end of combat"); + this.addAbility(new AttacksOrBlocksTriggeredAbility(effect, false)); + } + + public PhantomWhelp(final PhantomWhelp card) { + super(card); + } + + @Override + public PhantomWhelp copy() { + return new PhantomWhelp(this); + } +} From 6abd9f7b4f3f49faac8bd06100891b997bd9e169 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 11:44:01 +0100 Subject: [PATCH 32/52] Implemented Steam Vines --- Mage.Sets/src/mage/cards/s/SteamVines.java | 142 +++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SteamVines.java diff --git a/Mage.Sets/src/mage/cards/s/SteamVines.java b/Mage.Sets/src/mage/cards/s/SteamVines.java new file mode 100644 index 00000000000..514159305a5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SteamVines.java @@ -0,0 +1,142 @@ +/* + * 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.BecomesTappedAttachedTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.AttachEffect; +import mage.abilities.keyword.EnchantAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.Filter; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.Target; +import mage.target.TargetPermanent; +import mage.target.common.TargetLandPermanent; + +/** + * + * @author jeffwadsworth & L_J + */ +public class SteamVines extends CardImpl { + + public SteamVines(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{R}"); + this.subtype.add(SubType.AURA); + + // Enchant land + TargetPermanent auraTarget = new TargetLandPermanent(); + this.getSpellAbility().addTarget(auraTarget); + this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); + Ability ability = new EnchantAbility(auraTarget.getTargetName()); + this.addAbility(ability); + + // When enchanted land becomes tapped, destroy it and Steam Vines deals 1 damage to that land's controller. That player attaches Steam Vines to a land of his or her choice. + this.addAbility(new BecomesTappedAttachedTriggeredAbility(new SteamVinesEffect(), "enchanted land")); + + } + + public SteamVines(final SteamVines card) { + super(card); + } + + @Override + public SteamVines copy() { + return new SteamVines(this); + } +} + +class SteamVinesEffect extends OneShotEffect { + + public SteamVinesEffect() { + super(Outcome.Detriment); + staticText = "destroy it and {this} deals 1 damage to that land's controller. That player attaches {this} to a land of his or her choice"; + } + + public SteamVinesEffect(final SteamVinesEffect effect) { + super(effect); + } + + @Override + public SteamVinesEffect copy() { + return new SteamVinesEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent kudzu = game.getPermanentOrLKIBattlefield(source.getSourceId()); + Card kudzuCard = game.getCard(source.getSourceId()); + if (kudzu != null) { + Permanent enchantedLand = game.getPermanentOrLKIBattlefield(kudzu.getAttachedTo()); + Player controller = game.getPlayer(source.getControllerId()); + if (enchantedLand != null + && controller != null) { + Player landsController = game.getPlayer(enchantedLand.getControllerId()); + if (game.getState().getZone(enchantedLand.getId()) == Zone.BATTLEFIELD) { // if 2 or more Steam Vines were on a land + enchantedLand.destroy(source.getId(), game, false); + landsController.damage(1, source.getSourceId(), game, false, true); + } + if (!game.getBattlefield().getAllActivePermanents(CardType.LAND).isEmpty()) { //lands are available on the battlefield + Target target = new TargetLandPermanent(); + target.setNotTarget(true); //not a target, it is chosen + if (kudzuCard != null + && landsController != null) { + if (landsController.choose(Outcome.Detriment, target, source.getId(), game)) { + if (target.getFirstTarget() != null) { + Permanent landChosen = game.getPermanent(target.getFirstTarget()); + if (landChosen != null) { + for (Target targetTest : kudzuCard.getSpellAbility().getTargets()) { + Filter filterTest = targetTest.getFilter(); + if (filterTest.match(landChosen, game)) { + if (game.getBattlefield().containsPermanent(landChosen.getId())) { //verify that it is still on the battlefield + game.getState().setValue("attachTo:" + kudzuCard.getId(), landChosen); + Zone zone = game.getState().getZone(kudzuCard.getId()); + kudzuCard.putOntoBattlefield(game, zone, source.getSourceId(), controller.getId()); + return landChosen.addAttachment(kudzuCard.getId(), game); + } + } + } + } + } + } + } + } + } + } + return false; + } +} From 9a35106528e7043ebb3f1b4410769f8771a4a33d Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 11:46:27 +0100 Subject: [PATCH 33/52] Implemented Holistic Wisdom, Phantom Whelp and Steam Vines --- Mage.Sets/src/mage/sets/Odyssey.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index 34e731e088e..25397550b9e 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -184,6 +184,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Halberdier", 196, Rarity.COMMON, mage.cards.h.Halberdier.class)); cards.add(new SetCardInfo("Hallowed Healer", 25, Rarity.COMMON, mage.cards.h.HallowedHealer.class)); cards.add(new SetCardInfo("Haunting Echoes", 142, Rarity.RARE, mage.cards.h.HauntingEchoes.class)); + cards.add(new SetCardInfo("Holistic Wisdom", 243, Rarity.RARE, mage.cards.h.HolisticWisdom.class)); cards.add(new SetCardInfo("Howling Gale", 244, Rarity.UNCOMMON, mage.cards.h.HowlingGale.class)); cards.add(new SetCardInfo("Immobilizing Ink", 87, Rarity.COMMON, mage.cards.i.ImmobilizingInk.class)); cards.add(new SetCardInfo("Impulsive Maneuvers", 197, Rarity.RARE, mage.cards.i.ImpulsiveManeuvers.class)); @@ -274,6 +275,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 334, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); + cards.add(new SetCardInfo("Phantom Whelp", 93, Rarity.COMMON, mage.cards.p.PhantomWhelp.class)); cards.add(new SetCardInfo("Predict", 94, Rarity.UNCOMMON, mage.cards.p.Predict.class)); cards.add(new SetCardInfo("Price of Glory", 214, Rarity.UNCOMMON, mage.cards.p.PriceOfGlory.class)); cards.add(new SetCardInfo("Primal Frenzy", 262, Rarity.COMMON, mage.cards.p.PrimalFrenzy.class)); @@ -333,6 +335,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Squirrel Nest", 274, Rarity.UNCOMMON, mage.cards.s.SquirrelNest.class)); cards.add(new SetCardInfo("Stalking Bloodsucker", 163, Rarity.RARE, mage.cards.s.StalkingBloodsucker.class)); cards.add(new SetCardInfo("Standstill", 102, Rarity.UNCOMMON, mage.cards.s.Standstill.class)); + cards.add(new SetCardInfo("Steam Vines", 223, Rarity.UNCOMMON, mage.cards.s.SteamVines.class)); cards.add(new SetCardInfo("Steamclaw", 310, Rarity.UNCOMMON, mage.cards.s.Steamclaw.class)); cards.add(new SetCardInfo("Still Life", 275, Rarity.UNCOMMON, mage.cards.s.StillLife.class)); cards.add(new SetCardInfo("Stone-Tongue Basilisk", 276, Rarity.RARE, mage.cards.s.StoneTongueBasilisk.class)); From d5482366ba377ec1f7a8fb93eae79028c7faa148 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 11:48:04 +0100 Subject: [PATCH 34/52] Added missing Kudzu --- Mage.Sets/src/mage/sets/UnlimitedEdition.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/UnlimitedEdition.java b/Mage.Sets/src/mage/sets/UnlimitedEdition.java index 32df097c5e0..cfecaacda2a 100644 --- a/Mage.Sets/src/mage/sets/UnlimitedEdition.java +++ b/Mage.Sets/src/mage/sets/UnlimitedEdition.java @@ -154,6 +154,7 @@ public class UnlimitedEdition extends ExpansionSet { cards.add(new SetCardInfo("Karma", 211, Rarity.UNCOMMON, mage.cards.k.Karma.class)); cards.add(new SetCardInfo("Keldon Warlord", 161, Rarity.UNCOMMON, mage.cards.k.KeldonWarlord.class)); cards.add(new SetCardInfo("Kormus Bell", 257, Rarity.RARE, mage.cards.k.KormusBell.class)); + cards.add(new SetCardInfo("Kudzu", 113, Rarity.RARE, mage.cards.k.Kudzu.class)); cards.add(new SetCardInfo("Lance", 212, Rarity.UNCOMMON, mage.cards.l.Lance.class)); cards.add(new SetCardInfo("Ley Druid", 114, Rarity.UNCOMMON, mage.cards.l.LeyDruid.class)); cards.add(new SetCardInfo("Library of Leng", 258, Rarity.UNCOMMON, mage.cards.l.LibraryOfLeng.class)); From f4c89169b14e9cfd58de98c2cf0c8aa3de4177c4 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 11:48:12 +0100 Subject: [PATCH 35/52] Added missing Kudzu --- Mage.Sets/src/mage/sets/RevisedEdition.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/RevisedEdition.java b/Mage.Sets/src/mage/sets/RevisedEdition.java index de67e20007f..ae43bcfa15e 100644 --- a/Mage.Sets/src/mage/sets/RevisedEdition.java +++ b/Mage.Sets/src/mage/sets/RevisedEdition.java @@ -163,6 +163,7 @@ public class RevisedEdition extends ExpansionSet { cards.add(new SetCardInfo("Keldon Warlord", 159, Rarity.UNCOMMON, mage.cards.k.KeldonWarlord.class)); cards.add(new SetCardInfo("Kird Ape", 160, Rarity.COMMON, mage.cards.k.KirdApe.class)); cards.add(new SetCardInfo("Kormus Bell", 260, Rarity.RARE, mage.cards.k.KormusBell.class)); + cards.add(new SetCardInfo("Kudzu", 112, Rarity.RARE, mage.cards.k.Kudzu.class)); cards.add(new SetCardInfo("Lance", 211, Rarity.UNCOMMON, mage.cards.l.Lance.class)); cards.add(new SetCardInfo("Ley Druid", 113, Rarity.UNCOMMON, mage.cards.l.LeyDruid.class)); cards.add(new SetCardInfo("Library of Leng", 261, Rarity.UNCOMMON, mage.cards.l.LibraryOfLeng.class)); From 975af0ec8db19be83ffc08529da762d64017708e Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 14:12:03 +0100 Subject: [PATCH 36/52] Implemented Liar's Pendulum --- Mage.Sets/src/mage/cards/l/LiarsPendulum.java | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LiarsPendulum.java diff --git a/Mage.Sets/src/mage/cards/l/LiarsPendulum.java b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java new file mode 100644 index 00000000000..e793d34b54f --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java @@ -0,0 +1,142 @@ +/* + * 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.l; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.SplitCard; +import mage.cards.repository.CardRepository; +import mage.choices.Choice; +import mage.choices.ChoiceImpl; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetOpponent; + +/** + * + * @author L_J + */ +public class LiarsPendulum extends CardImpl { + + public LiarsPendulum(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); + + // {2}, {T}: Choose a card name. Target opponent guesses whether a card with that name is in your hand. You may reveal your hand. If you do and your opponent guessed wrong, draw a card. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LiarsPendulumEffect(), new GenericManaCost(2)); + ability.addCost(new TapSourceCost()); + ability.addTarget(new TargetOpponent()); + this.addAbility(ability); + } + + public LiarsPendulum(final LiarsPendulum card) { + super(card); + } + + @Override + public LiarsPendulum copy() { + return new LiarsPendulum(this); + } +} + + +class LiarsPendulumEffect extends OneShotEffect { + + public LiarsPendulumEffect() { + super(Outcome.DrawCard); + this.staticText = "Choose a card name. Target opponent guesses whether a card with that name is in your hand. You may reveal your hand. If you do and your opponent guessed wrong, draw a card"; + } + + public LiarsPendulumEffect(final LiarsPendulumEffect effect) { + super(effect); + } + + @Override + public LiarsPendulumEffect copy() { + return new LiarsPendulumEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (controller != null && opponent != null) { + // Name a card. + Choice choice = new ChoiceImpl(); + choice.setChoices(CardRepository.instance.getNames()); + while (!controller.choose(Outcome.Benefit, choice, game)) { + if (!controller.canRespond()) { + return false; + } + } + String cardName = choice.getChoice(); + game.informPlayers("Card named: " + cardName); + boolean opponentGuess = false; + + if (opponent.chooseUse(Outcome.Neutral, "Is the chosen card (" + cardName + ") in " + controller.getLogName() + "'s hand?", source, game)) { + opponentGuess = true; + } + boolean rightGuess = !opponentGuess; + + for (Card card : controller.getHand().getCards(game)) { + if (card.isSplitCard()){ + SplitCard splitCard = (SplitCard) card; + if (splitCard.getLeftHalfCard().getName().equals(cardName)){ + rightGuess = opponentGuess; + } + else if (splitCard.getRightHalfCard().getName().equals(cardName)){ + rightGuess = opponentGuess; + } + } + if (card.getName().equals(cardName)) { + rightGuess = opponentGuess; + } + } + game.informPlayers(opponent.getLogName() + " guesses that " + cardName + " is " + (opponentGuess ? "" : "not") + " in " + controller.getLogName() + "'s hand"); + + if (controller.chooseUse(outcome, "Reveal your hand?", source, game)) { + controller.revealCards("hand of " + controller.getName(), controller.getHand(), game); + if (!rightGuess) { + controller.drawCards(1, game); + return true; + } + } + } + return false; + } + +} From b68faa6ef49313f40f8620b041998fe35f96eda6 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 14:12:59 +0100 Subject: [PATCH 37/52] Implemented Liar's Pendulum --- Mage.Sets/src/mage/sets/Mirrodin.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Mirrodin.java b/Mage.Sets/src/mage/sets/Mirrodin.java index d1fd1c453b4..51363efc4e4 100644 --- a/Mage.Sets/src/mage/sets/Mirrodin.java +++ b/Mage.Sets/src/mage/sets/Mirrodin.java @@ -143,6 +143,7 @@ public class Mirrodin extends ExpansionSet { cards.add(new SetCardInfo("Leonin Skyhunter", 11, Rarity.UNCOMMON, mage.cards.l.LeoninSkyhunter.class)); cards.add(new SetCardInfo("Leonin Sun Standard", 194, Rarity.RARE, mage.cards.l.LeoninSunStandard.class)); cards.add(new SetCardInfo("Leveler", 195, Rarity.RARE, mage.cards.l.Leveler.class)); + cards.add(new SetCardInfo("Liar's Pendulum", 196, Rarity.RARE, mage.cards.l.LiarsPendulum.class)); cards.add(new SetCardInfo("Lifespark Spellbomb", 197, Rarity.COMMON, mage.cards.l.LifesparkSpellbomb.class)); cards.add(new SetCardInfo("Lightning Coils", 198, Rarity.RARE, mage.cards.l.LightningCoils.class)); cards.add(new SetCardInfo("Lightning Greaves", 199, Rarity.UNCOMMON, mage.cards.l.LightningGreaves.class)); From 07cd3b67bbc949e48f7486d892a28994824c0f89 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 16:03:51 +0100 Subject: [PATCH 38/52] Added message to card choice --- Mage.Sets/src/mage/cards/l/LiarsPendulum.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/cards/l/LiarsPendulum.java b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java index e793d34b54f..f8f38dcb8c8 100644 --- a/Mage.Sets/src/mage/cards/l/LiarsPendulum.java +++ b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java @@ -98,6 +98,7 @@ class LiarsPendulumEffect extends OneShotEffect { // Name a card. Choice choice = new ChoiceImpl(); choice.setChoices(CardRepository.instance.getNames()); + choice.setMessage("Choose a card name"); while (!controller.choose(Outcome.Benefit, choice, game)) { if (!controller.canRespond()) { return false; From cd26cc0e880df80335de54d40997fd617758868b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Wed, 8 Nov 2017 17:05:11 +0100 Subject: [PATCH 39/52] Moved "return true" statement --- Mage.Sets/src/mage/cards/l/LiarsPendulum.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/l/LiarsPendulum.java b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java index f8f38dcb8c8..d0117ed33f8 100644 --- a/Mage.Sets/src/mage/cards/l/LiarsPendulum.java +++ b/Mage.Sets/src/mage/cards/l/LiarsPendulum.java @@ -133,9 +133,9 @@ class LiarsPendulumEffect extends OneShotEffect { controller.revealCards("hand of " + controller.getName(), controller.getHand(), game); if (!rightGuess) { controller.drawCards(1, game); - return true; } } + return true; } return false; } From facbca9e0a0f1d61fae7c64b68acb03d8a959fce Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 10:46:21 +0100 Subject: [PATCH 40/52] Implemented Shriveling Rot --- Mage.Sets/src/mage/cards/s/ShrivelingRot.java | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/ShrivelingRot.java diff --git a/Mage.Sets/src/mage/cards/s/ShrivelingRot.java b/Mage.Sets/src/mage/cards/s/ShrivelingRot.java new file mode 100644 index 00000000000..55c73743425 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/ShrivelingRot.java @@ -0,0 +1,190 @@ +/* + * 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.DelayedTriggeredAbility; +import mage.abilities.Mode; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.Effect; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.DestroyTargetEffect; +import mage.abilities.keyword.EntwineAbility; +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.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; +import mage.game.events.ZoneChangeEvent; + +/** + * + * @author L_J + */ +public class ShrivelingRot extends CardImpl { + + public ShrivelingRot(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{B}{B}"); + + // Choose one - + // Until end of turn, whenever a creature is dealt damage, destroy it. + this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new ShrivelingRotDestroyTriggeredAbility())); + // Until end of turn, whenever a creature dies, that creature's controller loses life equal to its toughness. + Mode mode = new Mode(); + mode.getEffects().add(new CreateDelayedTriggeredAbilityEffect(new ShrivelingRotLoseLifeTriggeredAbility())); + this.getSpellAbility().getModes().addMode(mode); + + // Entwine {2}{B} + this.addAbility(new EntwineAbility("{2}{B}")); + } + + public ShrivelingRot(final ShrivelingRot card) { + super(card); + } + + @Override + public ShrivelingRot copy() { + return new ShrivelingRot(this); + } +} + +class ShrivelingRotDestroyTriggeredAbility extends DelayedTriggeredAbility { + + ShrivelingRotDestroyTriggeredAbility() { + super(new DestroyTargetEffect(), Duration.EndOfTurn, false); + } + + ShrivelingRotDestroyTriggeredAbility(final ShrivelingRotDestroyTriggeredAbility ability) { + super(ability); + } + + @Override + public ShrivelingRotDestroyTriggeredAbility copy() { + return new ShrivelingRotDestroyTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.DAMAGED_CREATURE; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + for (Effect effect : this.getEffects()) { + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + } + return true; + } + + @Override + public String getRule() { + return "Until end of turn, whenever a creature is dealt damage, destroy it."; + } +} + +class ShrivelingRotLoseLifeTriggeredAbility extends DelayedTriggeredAbility { + + ShrivelingRotLoseLifeTriggeredAbility() { + super(new ShrivelingRotEffect(), Duration.EndOfTurn, false); + } + + ShrivelingRotLoseLifeTriggeredAbility(final ShrivelingRotLoseLifeTriggeredAbility ability) { + super(ability); + } + + @Override + public ShrivelingRotLoseLifeTriggeredAbility copy() { + return new ShrivelingRotLoseLifeTriggeredAbility(this); + } + + @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) { + if (zEvent.getTarget().isCreature()) { + Effect effect = this.getEffects().get(0); + effect.setTargetPointer(new FixedTarget(event.getTargetId())); + return true; + } + } + return false; + } + + @Override + public String getRule() { + return "Until end of turn, whenever a creature dies, that creature's controller loses life equal to its toughness."; + } +} + +class ShrivelingRotEffect extends OneShotEffect { + + public ShrivelingRotEffect() { + super(Outcome.LoseLife); + staticText = "that creature's controller loses life equal to its toughness"; + } + + public ShrivelingRotEffect(final ShrivelingRotEffect effect) { + super(effect); + } + + @Override + public ShrivelingRotEffect copy() { + return new ShrivelingRotEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source)); + if (permanent != null) { + if (permanent.getZoneChangeCounter(game) + 1 == game.getState().getZoneChangeCounter(permanent.getId()) + && !game.getState().getZone(permanent.getId()).equals(Zone.GRAVEYARD)) { + // A replacement effect has moved the card to another zone as graveyard + return true; + } + Player permanentController = game.getPlayer(permanent.getControllerId()); + if (permanentController != null) { + int amount = permanent.getToughness().getValue(); + permanentController.loseLife(amount, game, false); + return true; + } + } + return false; + } +} From 368a7143631070e7c08aa1c5e48a58d4fd382a8b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 10:47:03 +0100 Subject: [PATCH 41/52] Implemented Shriveling Rot --- Mage.Sets/src/mage/sets/Darksteel.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Darksteel.java b/Mage.Sets/src/mage/sets/Darksteel.java index 923073de62e..bb2699723c5 100644 --- a/Mage.Sets/src/mage/sets/Darksteel.java +++ b/Mage.Sets/src/mage/sets/Darksteel.java @@ -140,6 +140,7 @@ public class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Second Sight", 33, Rarity.UNCOMMON, mage.cards.s.SecondSight.class)); cards.add(new SetCardInfo("Serum Powder", 138, Rarity.RARE, mage.cards.s.SerumPowder.class)); cards.add(new SetCardInfo("Shield of Kaldra", 139, Rarity.RARE, mage.cards.s.ShieldOfKaldra.class)); + cards.add(new SetCardInfo("Shriveling Rot", 54, Rarity.RARE, mage.cards.s.ShrivelingRot.class)); cards.add(new SetCardInfo("Shunt", 68, Rarity.RARE, mage.cards.s.Shunt.class)); cards.add(new SetCardInfo("Skullclamp", 140, Rarity.UNCOMMON, mage.cards.s.Skullclamp.class)); cards.add(new SetCardInfo("Slobad, Goblin Tinkerer", 69, Rarity.RARE, mage.cards.s.SlobadGoblinTinkerer.class)); From 8f3c4c1fcbdadb889dde0357ba84a03314f33366 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 11:09:56 +0100 Subject: [PATCH 42/52] Text fix --- Mage.Sets/src/mage/cards/p/PulseOfTheGrid.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/p/PulseOfTheGrid.java b/Mage.Sets/src/mage/cards/p/PulseOfTheGrid.java index 704e3d3570d..485af3b3c5c 100644 --- a/Mage.Sets/src/mage/cards/p/PulseOfTheGrid.java +++ b/Mage.Sets/src/mage/cards/p/PulseOfTheGrid.java @@ -68,7 +68,7 @@ class PulseOfTheGridReturnToHandEffect extends OneShotEffect { PulseOfTheGridReturnToHandEffect() { super(Outcome.Benefit); - this.staticText = "Draw two cards, then discard a card. Then if an opponent has more cards in hand than you, return {this} to its owner's hand"; + this.staticText = "Then if an opponent has more cards in hand than you, return {this} to its owner's hand"; } PulseOfTheGridReturnToHandEffect(final PulseOfTheGridReturnToHandEffect effect) { From 01516d3b28ec1da74f57ba8f7110ec991aa7eb62 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 13:16:27 +0100 Subject: [PATCH 43/52] Implemented Pulse of the Dross --- .../src/mage/cards/p/PulseOfTheDross.java | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PulseOfTheDross.java diff --git a/Mage.Sets/src/mage/cards/p/PulseOfTheDross.java b/Mage.Sets/src/mage/cards/p/PulseOfTheDross.java new file mode 100644 index 00000000000..f0be2b5f5be --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PulseOfTheDross.java @@ -0,0 +1,101 @@ +/* + * 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.p; + +import java.util.UUID; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; +import mage.cards.Card; +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.game.Game; +import mage.players.Player; +import mage.target.TargetPlayer; + +/** + * + * @author emerald000 & L_J + */ +public class PulseOfTheDross extends CardImpl { + + public PulseOfTheDross(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{B}{B}"); + + // Target player reveals three cards from his or her hand and you choose one of them. That player discards that card. + this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(TargetController.ANY, 3)); + this.getSpellAbility().addEffect(new PulseOfTheDrossReturnToHandEffect()); + this.getSpellAbility().addTarget(new TargetPlayer()); + } + + public PulseOfTheDross(final PulseOfTheDross card) { + super(card); + } + + @Override + public PulseOfTheDross copy() { + return new PulseOfTheDross(this); + } +} + +class PulseOfTheDrossReturnToHandEffect extends OneShotEffect { + + PulseOfTheDrossReturnToHandEffect() { + super(Outcome.Benefit); + this.staticText = "Then if that player has more cards in hand than you, return {this} to its owner's hand"; + } + + PulseOfTheDrossReturnToHandEffect(final PulseOfTheDrossReturnToHandEffect effect) { + super(effect); + } + + @Override + public PulseOfTheDrossReturnToHandEffect copy() { + return new PulseOfTheDrossReturnToHandEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Player player = game.getPlayer(source.getFirstTarget()); + if (player != null) { + if (player.getHand().size() > controller.getHand().size()) { + Card card = game.getCard(source.getSourceId()); + controller.moveCards(card, Zone.HAND, source, game); + } + return true; + } + } + return false; + } +} From ee3a9c35e2020c23160d54f8cf4962d16a0572ff Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 13:17:17 +0100 Subject: [PATCH 44/52] Implemented Scrounge --- Mage.Sets/src/mage/cards/s/Scrounge.java | 107 +++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/Scrounge.java diff --git a/Mage.Sets/src/mage/cards/s/Scrounge.java b/Mage.Sets/src/mage/cards/s/Scrounge.java new file mode 100644 index 00000000000..77ad5c21747 --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/Scrounge.java @@ -0,0 +1,107 @@ +/* + * 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.effects.OneShotEffect; +import mage.cards.*; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.filter.common.FilterArtifactCard; +import mage.filter.predicate.other.OwnerIdPredicate; +import mage.game.Game; +import mage.players.Player; +import mage.target.common.TargetCardInGraveyard; +import mage.target.common.TargetOpponent; + +/** + * + * @author LoneFox & L_J + */ +public class Scrounge extends CardImpl { + + public Scrounge(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}"); + + // Target opponent chooses an artifact card in his or her graveyard. Put that card onto the battlefield under your control. + this.getSpellAbility().addEffect(new ScroungeEffect()); + this.getSpellAbility().addTarget(new TargetOpponent()); + } + + public Scrounge(final Scrounge card) { + super(card); + } + + @Override + public Scrounge copy() { + return new Scrounge(this); + } +} + +class ScroungeEffect extends OneShotEffect { + + public ScroungeEffect() { + super(Outcome.Benefit); + staticText = "Target opponent chooses an artifact card in his or her graveyard. Put that card onto the battlefield under your control"; + } + + public ScroungeEffect(final ScroungeEffect effect) { + super(effect); + } + + @Override + public ScroungeEffect copy() { + return new ScroungeEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); + if (controller != null && opponent != null) { + FilterArtifactCard filter = new FilterArtifactCard(); + filter.add(new OwnerIdPredicate(opponent.getId())); + TargetCardInGraveyard chosenCard = new TargetCardInGraveyard(filter); + chosenCard.setNotTarget(true); + if (chosenCard.canChoose(opponent.getId(), game)) { + opponent.chooseTarget(Outcome.ReturnToHand, chosenCard, source, game); + Card card = game.getCard(chosenCard.getFirstTarget()); + game.informPlayers("Scrounge: " + opponent.getLogName() + " has chosen " + card.getLogName()); + if (card != null) { + Cards cardsToMove = new CardsImpl(); + cardsToMove.add(card); + controller.moveCards(cardsToMove, Zone.BATTLEFIELD, source, game); + } + return true; + } + } + return false; + } +} From 570199e0b3bc480d113fb3680fcedb3bfef96b90 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 13:17:35 +0100 Subject: [PATCH 45/52] Implemented Pulse of the Dross and Scrounge --- Mage.Sets/src/mage/sets/Darksteel.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mage.Sets/src/mage/sets/Darksteel.java b/Mage.Sets/src/mage/sets/Darksteel.java index bb2699723c5..67b77deb03e 100644 --- a/Mage.Sets/src/mage/sets/Darksteel.java +++ b/Mage.Sets/src/mage/sets/Darksteel.java @@ -121,6 +121,7 @@ public class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Pristine Angel", 9, Rarity.RARE, mage.cards.p.PristineAngel.class)); cards.add(new SetCardInfo("Psychic Overload", 28, Rarity.UNCOMMON, mage.cards.p.PsychicOverload.class)); cards.add(new SetCardInfo("Pteron Ghost", 10, Rarity.COMMON, mage.cards.p.PteronGhost.class)); + cards.add(new SetCardInfo("Pulse of the Dross", 50, Rarity.RARE, mage.cards.p.PulseOfTheDross.class)); cards.add(new SetCardInfo("Pulse of the Fields", 11, Rarity.RARE, mage.cards.p.PulseOfTheFields.class)); cards.add(new SetCardInfo("Pulse of the Forge", 66, Rarity.RARE, mage.cards.p.PulseOfTheForge.class)); cards.add(new SetCardInfo("Pulse of the Grid", 29, Rarity.RARE, mage.cards.p.PulseOfTheGrid.class)); @@ -137,6 +138,7 @@ public class Darksteel extends ExpansionSet { cards.add(new SetCardInfo("Savage Beating", 67, Rarity.RARE, mage.cards.s.SavageBeating.class)); cards.add(new SetCardInfo("Scavenging Scarab", 51, Rarity.COMMON, mage.cards.s.ScavengingScarab.class)); cards.add(new SetCardInfo("Screams from Within", 52, Rarity.UNCOMMON, mage.cards.s.ScreamsFromWithin.class)); + cards.add(new SetCardInfo("Scrounge", 53, Rarity.UNCOMMON, mage.cards.s.Scrounge.class)); cards.add(new SetCardInfo("Second Sight", 33, Rarity.UNCOMMON, mage.cards.s.SecondSight.class)); cards.add(new SetCardInfo("Serum Powder", 138, Rarity.RARE, mage.cards.s.SerumPowder.class)); cards.add(new SetCardInfo("Shield of Kaldra", 139, Rarity.RARE, mage.cards.s.ShieldOfKaldra.class)); From 568eafc7ffb7ceb05f8cda2b9e341cf7e2f60e38 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 13:43:28 +0100 Subject: [PATCH 46/52] Minor edits --- Mage.Sets/src/mage/cards/s/Scrounge.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/cards/s/Scrounge.java b/Mage.Sets/src/mage/cards/s/Scrounge.java index 77ad5c21747..b4fa332d95d 100644 --- a/Mage.Sets/src/mage/cards/s/Scrounge.java +++ b/Mage.Sets/src/mage/cards/s/Scrounge.java @@ -93,14 +93,14 @@ class ScroungeEffect extends OneShotEffect { if (chosenCard.canChoose(opponent.getId(), game)) { opponent.chooseTarget(Outcome.ReturnToHand, chosenCard, source, game); Card card = game.getCard(chosenCard.getFirstTarget()); - game.informPlayers("Scrounge: " + opponent.getLogName() + " has chosen " + card.getLogName()); if (card != null) { + game.informPlayers ("Scrounge: " + opponent.getLogName() + " has chosen " + card.getLogName()); Cards cardsToMove = new CardsImpl(); cardsToMove.add(card); controller.moveCards(cardsToMove, Zone.BATTLEFIELD, source, game); } - return true; } + return true; } return false; } From 6ac67e23fa70a0465be333983e6d108e9f3ab2cf Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 15:25:06 +0100 Subject: [PATCH 47/52] Implemented Cryptwailing --- Mage.Sets/src/mage/cards/c/Cryptwailing.java | 67 ++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/c/Cryptwailing.java diff --git a/Mage.Sets/src/mage/cards/c/Cryptwailing.java b/Mage.Sets/src/mage/cards/c/Cryptwailing.java new file mode 100644 index 00000000000..1ad88cbebe5 --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/Cryptwailing.java @@ -0,0 +1,67 @@ +/* + * 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.common.ActivateAsSorceryActivatedAbility; +import mage.abilities.costs.common.ExileFromGraveCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.common.discard.DiscardTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.filter.common.FilterCreatureCard; +import mage.target.TargetPlayer; +import mage.target.common.TargetCardInYourGraveyard; + +/** + * + * @author LevelX2 & L_J + */ +public class Cryptwailing extends CardImpl { + + public Cryptwailing(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}"); + + // {1}, Exile two creature cards from your graveyard: Target player discards a card. Activate this ability only any time you could cast a sorcery. + ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new DiscardTargetEffect(1), new GenericManaCost(1)); + ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(2,2, new FilterCreatureCard("two creature cards from your graveyard")))); + ability.addTarget(new TargetPlayer()); + this.addAbility(ability); + } + + public Cryptwailing(final Cryptwailing card) { + super(card); + } + + @Override + public Cryptwailing copy() { + return new Cryptwailing(this); + } +} From f80b7b6d8e505a03016f595b03f88b0c109a7126 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 15:25:16 +0100 Subject: [PATCH 48/52] Implemented Living Inferno --- Mage.Sets/src/mage/cards/l/LivingInferno.java | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/l/LivingInferno.java diff --git a/Mage.Sets/src/mage/cards/l/LivingInferno.java b/Mage.Sets/src/mage/cards/l/LivingInferno.java new file mode 100644 index 00000000000..aaa17b732e4 --- /dev/null +++ b/Mage.Sets/src/mage/cards/l/LivingInferno.java @@ -0,0 +1,132 @@ +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.cards.l; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import mage.MageInt; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.Outcome; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.target.Target; +import mage.target.common.TargetCreaturePermanentAmount; + +/** + * + * @author LevelX2 & L_J + */ +public class LivingInferno extends CardImpl { + + private final UUID originalId; + + public LivingInferno(UUID ownerId, CardSetInfo setInfo) { + super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{R}{R}"); + this.subtype.add(SubType.ELEMENTAL); + this.power = new MageInt(8); + this.toughness = new MageInt(5); + + // {T}: Living Inferno deals damage equal to its power divided as you choose among any number of target creatures. Each of those creatures deals damage equal to its power to Living Inferno. + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LivingInfernoEffect(), new TapSourceCost()); + ability.addTarget(new TargetCreaturePermanentAmount(1)); + this.addAbility(ability); + originalId = ability.getOriginalId(); + } + + @Override + public void adjustTargets(Ability ability, Game game) { + if(ability.getOriginalId().equals(originalId)) { + Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(ability.getSourceId()); + if (sourcePermanent != null) { + int xValue = sourcePermanent.getPower().getValue(); + ability.getTargets().clear(); + ability.addTarget(new TargetCreaturePermanentAmount(xValue)); + } + } + } + + public LivingInferno(final LivingInferno card) { + super(card); + this.originalId = card.originalId; + } + + @Override + public LivingInferno copy() { + return new LivingInferno(this); + } +} + +class LivingInfernoEffect extends OneShotEffect { + + public LivingInfernoEffect() { + super(Outcome.Benefit); + this.staticText = "{this} deals damage equal to its power divided as you choose among any number of target creatures. Each of those creatures deals damage equal to its power to {this}"; + } + + public LivingInfernoEffect(final LivingInfernoEffect effect) { + super(effect); + } + + @Override + public LivingInfernoEffect copy() { + return new LivingInfernoEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + if (!source.getTargets().isEmpty()) { + Target multiTarget = source.getTargets().get(0); + Set permanents = new HashSet<>(); + for (UUID target : multiTarget.getTargets()) { + Permanent permanent = game.getPermanent(target); + if (permanent != null) { + permanents.add(permanent); + permanent.damage(multiTarget.getTargetAmount(target), source.getSourceId(), game, false, true); + } + } + // Each of those creatures deals damage equal to its power to Living Inferno + Permanent sourceCreature = game.getPermanent(source.getSourceId()); + if (sourceCreature != null) { + for (Permanent permanent : permanents) { + sourceCreature.damage(permanent.getPower().getValue(), permanent.getId(), game, false, true); + } + } + return true; + } + return false; + } +} From a8d0d535027fd2044a959409efc369d9c26bd4fa Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Thu, 9 Nov 2017 15:26:27 +0100 Subject: [PATCH 49/52] Implemented Cryptwailing and Living Inferno --- Mage.Sets/src/mage/sets/Guildpact.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Mage.Sets/src/mage/sets/Guildpact.java b/Mage.Sets/src/mage/sets/Guildpact.java index 5b51825dd85..e1d9e70c17f 100644 --- a/Mage.Sets/src/mage/sets/Guildpact.java +++ b/Mage.Sets/src/mage/sets/Guildpact.java @@ -61,7 +61,7 @@ public class Guildpact extends ExpansionSet { cards.add(new SetCardInfo("Beastmaster's Magemark", 80, Rarity.COMMON, mage.cards.b.BeastmastersMagemark.class)); cards.add(new SetCardInfo("Belfry Spirit", 2, Rarity.UNCOMMON, mage.cards.b.BelfrySpirit.class)); cards.add(new SetCardInfo("Benediction of Moons", 3, Rarity.COMMON, mage.cards.b.BenedictionOfMoons.class)); - cards.add(new SetCardInfo("Bioplasm", 81, Rarity.RARE, mage.cards.b.Bioplasm.class)); + cards.add(new SetCardInfo("Bioplasm", 81, Rarity.RARE, mage.cards.b.Bioplasm.class)); cards.add(new SetCardInfo("Blind Hunter", 102, Rarity.COMMON, mage.cards.b.BlindHunter.class)); cards.add(new SetCardInfo("Bloodscale Prowler", 64, Rarity.COMMON, mage.cards.b.BloodscaleProwler.class)); cards.add(new SetCardInfo("Borborygmos", 103, Rarity.RARE, mage.cards.b.Borborygmos.class)); @@ -73,13 +73,14 @@ public class Guildpact extends ExpansionSet { cards.add(new SetCardInfo("Crash Landing", 82, Rarity.UNCOMMON, mage.cards.c.CrashLanding.class)); cards.add(new SetCardInfo("Cremate", 45, Rarity.COMMON, mage.cards.c.Cremate.class)); cards.add(new SetCardInfo("Cry of Contrition", 46, Rarity.COMMON, mage.cards.c.CryOfContrition.class)); + cards.add(new SetCardInfo("Cryptwailing", 47, Rarity.UNCOMMON, mage.cards.c.Cryptwailing.class)); cards.add(new SetCardInfo("Crystal Seer", 23, Rarity.UNCOMMON, mage.cards.c.CrystalSeer.class)); cards.add(new SetCardInfo("Culling Sun", 109, Rarity.RARE, mage.cards.c.CullingSun.class)); cards.add(new SetCardInfo("Daggerclaw Imp", 48, Rarity.UNCOMMON, mage.cards.d.DaggerclawImp.class)); cards.add(new SetCardInfo("Debtors' Knell", 141, Rarity.RARE, mage.cards.d.DebtorsKnell.class)); cards.add(new SetCardInfo("Djinn Illuminatus", 142, Rarity.RARE, mage.cards.d.DjinnIlluminatus.class)); cards.add(new SetCardInfo("Douse in Gloom", 49, Rarity.COMMON, mage.cards.d.DouseInGloom.class)); - cards.add(new SetCardInfo("Droning Bureaucrats", 4, Rarity.UNCOMMON, mage.cards.d.DroningBureaucrats.class)); + cards.add(new SetCardInfo("Droning Bureaucrats", 4, Rarity.UNCOMMON, mage.cards.d.DroningBureaucrats.class)); cards.add(new SetCardInfo("Drowned Rusalka", 24, Rarity.UNCOMMON, mage.cards.d.DrownedRusalka.class)); cards.add(new SetCardInfo("Dryad Sophisticate", 83, Rarity.UNCOMMON, mage.cards.d.DryadSophisticate.class)); cards.add(new SetCardInfo("Dune-Brood Nephilim", 110, Rarity.RARE, mage.cards.d.DuneBroodNephilim.class)); @@ -121,7 +122,7 @@ public class Guildpact extends ExpansionSet { cards.add(new SetCardInfo("Izzet Chronarch", 119, Rarity.COMMON, mage.cards.i.IzzetChronarch.class)); cards.add(new SetCardInfo("Izzet Guildmage", 145, Rarity.UNCOMMON, mage.cards.i.IzzetGuildmage.class)); cards.add(new SetCardInfo("Izzet Signet", 152, Rarity.COMMON, mage.cards.i.IzzetSignet.class)); - cards.add(new SetCardInfo("Killer Instinct", 120, Rarity.RARE, mage.cards.k.KillerInstinct.class)); + cards.add(new SetCardInfo("Killer Instinct", 120, Rarity.RARE, mage.cards.k.KillerInstinct.class)); cards.add(new SetCardInfo("Leap of Flame", 121, Rarity.COMMON, mage.cards.l.LeapOfFlame.class)); cards.add(new SetCardInfo("Leyline of Lifeforce", 90, Rarity.RARE, mage.cards.l.LeylineOfLifeforce.class)); cards.add(new SetCardInfo("Leyline of Lightning", 68, Rarity.RARE, mage.cards.l.LeylineOfLightning.class)); @@ -129,10 +130,11 @@ public class Guildpact extends ExpansionSet { cards.add(new SetCardInfo("Leyline of the Meek", 10, Rarity.RARE, mage.cards.l.LeylineOfTheMeek.class)); cards.add(new SetCardInfo("Leyline of the Void", 52, Rarity.RARE, mage.cards.l.LeylineOfTheVoid.class)); cards.add(new SetCardInfo("Lionheart Maverick", 11, Rarity.COMMON, mage.cards.l.LionheartMaverick.class)); + cards.add(new SetCardInfo("Living Inferno", 69, Rarity.RARE, mage.cards.l.LivingInferno.class)); cards.add(new SetCardInfo("Martyred Rusalka", 12, Rarity.UNCOMMON, mage.cards.m.MartyredRusalka.class)); cards.add(new SetCardInfo("Mimeofacture", 30, Rarity.RARE, mage.cards.m.Mimeofacture.class)); cards.add(new SetCardInfo("Mizzium Transreliquat", 153, Rarity.RARE, mage.cards.m.MizziumTransreliquat.class)); - cards.add(new SetCardInfo("Moratorium Stone", 154, Rarity.RARE, mage.cards.m.MoratoriumStone.class)); + cards.add(new SetCardInfo("Moratorium Stone", 154, Rarity.RARE, mage.cards.m.MoratoriumStone.class)); cards.add(new SetCardInfo("Mortify", 122, Rarity.UNCOMMON, mage.cards.m.Mortify.class)); cards.add(new SetCardInfo("Mourning Thrull", 146, Rarity.COMMON, mage.cards.m.MourningThrull.class)); cards.add(new SetCardInfo("Necromancer's Magemark", 53, Rarity.COMMON, mage.cards.n.NecromancersMagemark.class)); @@ -166,14 +168,14 @@ public class Guildpact extends ExpansionSet { cards.add(new SetCardInfo("Scab-Clan Mauler", 128, Rarity.COMMON, mage.cards.s.ScabClanMauler.class)); cards.add(new SetCardInfo("Schismotivate", 129, Rarity.UNCOMMON, mage.cards.s.Schismotivate.class)); cards.add(new SetCardInfo("Scorched Rusalka", 74, Rarity.UNCOMMON, mage.cards.s.ScorchedRusalka.class)); - cards.add(new SetCardInfo("Seize the Soul", 61, Rarity.RARE, mage.cards.s.SeizeTheSoul.class)); + cards.add(new SetCardInfo("Seize the Soul", 61, Rarity.RARE, mage.cards.s.SeizeTheSoul.class)); cards.add(new SetCardInfo("Shadow Lance", 14, Rarity.UNCOMMON, mage.cards.s.ShadowLance.class)); cards.add(new SetCardInfo("Shattering Spree", 75, Rarity.UNCOMMON, mage.cards.s.ShatteringSpree.class)); cards.add(new SetCardInfo("Shrieking Grotesque", 15, Rarity.COMMON, mage.cards.s.ShriekingGrotesque.class)); cards.add(new SetCardInfo("Siege of Towers", 76, Rarity.RARE, mage.cards.s.SiegeOfTowers.class)); cards.add(new SetCardInfo("Silhana Ledgewalker", 94, Rarity.COMMON, mage.cards.s.SilhanaLedgewalker.class)); cards.add(new SetCardInfo("Silhana Starfletcher", 95, Rarity.COMMON, mage.cards.s.SilhanaStarfletcher.class)); - cards.add(new SetCardInfo("Sinstriker's Will", 16, Rarity.UNCOMMON, mage.cards.s.SinstrikersWill.class)); + cards.add(new SetCardInfo("Sinstriker's Will", 16, Rarity.UNCOMMON, mage.cards.s.SinstrikersWill.class)); cards.add(new SetCardInfo("Skarrgan Firebird", 77, Rarity.RARE, mage.cards.s.SkarrganFirebird.class)); cards.add(new SetCardInfo("Skarrgan Pit-Skulk", 96, Rarity.COMMON, mage.cards.s.SkarrganPitSkulk.class)); cards.add(new SetCardInfo("Skarrgan Skybreaker", 130, Rarity.UNCOMMON, mage.cards.s.SkarrganSkybreaker.class)); From ffec70f1afab6282f5559c52acfc583288b7161b Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 10 Nov 2017 10:56:00 +0100 Subject: [PATCH 50/52] Implemented Pedantic Learning --- .../src/mage/cards/p/PedanticLearning.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/p/PedanticLearning.java diff --git a/Mage.Sets/src/mage/cards/p/PedanticLearning.java b/Mage.Sets/src/mage/cards/p/PedanticLearning.java new file mode 100644 index 00000000000..89001b48bd9 --- /dev/null +++ b/Mage.Sets/src/mage/cards/p/PedanticLearning.java @@ -0,0 +1,111 @@ +/* + * 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.p; + +import java.util.Set; +import java.util.UUID; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.DoIfCostPaid; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; + +/** + * + * @author LevelX2 & L_J + */ +public class PedanticLearning extends CardImpl { + + public PedanticLearning(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}"); + + // Whenever a land card is put into your graveyard from your library, you may pay {1}. If you do, draw a card. + this.addAbility(new PedanticLearningTriggeredAbility()); + } + + public PedanticLearning(final PedanticLearning card) { + super(card); + } + + @Override + public PedanticLearning copy() { + return new PedanticLearning(this); + } +} + +class PedanticLearningTriggeredAbility extends TriggeredAbilityImpl { + + public PedanticLearningTriggeredAbility() { + super(Zone.BATTLEFIELD, new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new ManaCostsImpl("{1}")), false); + } + + public PedanticLearningTriggeredAbility(final PedanticLearningTriggeredAbility 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 != null && zEvent.getFromZone() == Zone.LIBRARY && zEvent.getToZone() == Zone.GRAVEYARD) { + Card card = game.getCard(event.getTargetId()); + if (card != null) { + UUID cardOwnerId = card.getOwnerId(); + Set cardType = card.getCardType(); + if (cardOwnerId != null + && card.getOwnerId().equals(getControllerId()) + && cardType != null + && card.isLand()) { + return true; + } + } + } + return false; + } + + @Override + public PedanticLearningTriggeredAbility copy() { + return new PedanticLearningTriggeredAbility(this); + } + + @Override + public String getRule() { + return "Whenever a land card is put into your graveyard from your library, you may pay {1}. If you do, draw a card."; + } +} From 0aab3a9bca113a1d22cd8be71105ef7af6c0f1e9 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 10 Nov 2017 10:57:25 +0100 Subject: [PATCH 51/52] Moved Risky Move --- Mage.Sets/src/mage/cards/{ => r}/RiskyMove.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Mage.Sets/src/mage/cards/{ => r}/RiskyMove.java (100%) diff --git a/Mage.Sets/src/mage/cards/RiskyMove.java b/Mage.Sets/src/mage/cards/r/RiskyMove.java similarity index 100% rename from Mage.Sets/src/mage/cards/RiskyMove.java rename to Mage.Sets/src/mage/cards/r/RiskyMove.java From 7216d3f519518418a4e8a339fc949b638883e776 Mon Sep 17 00:00:00 2001 From: Zzooouhh Date: Fri, 10 Nov 2017 10:58:46 +0100 Subject: [PATCH 52/52] Implemented Pedantic Learning --- Mage.Sets/src/mage/sets/Odyssey.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Mage.Sets/src/mage/sets/Odyssey.java b/Mage.Sets/src/mage/sets/Odyssey.java index 25397550b9e..7900768d2b5 100644 --- a/Mage.Sets/src/mage/sets/Odyssey.java +++ b/Mage.Sets/src/mage/sets/Odyssey.java @@ -263,6 +263,7 @@ public class Odyssey extends ExpansionSet { cards.add(new SetCardInfo("Patriarch's Desire", 156, Rarity.COMMON, mage.cards.p.PatriarchsDesire.class)); cards.add(new SetCardInfo("Patrol Hound", 38, Rarity.COMMON, mage.cards.p.PatrolHound.class)); cards.add(new SetCardInfo("Patron Wizard", 89, Rarity.RARE, mage.cards.p.PatronWizard.class)); + cards.add(new SetCardInfo("Pedantic Learning", 90, Rarity.RARE, mage.cards.p.PedanticLearning.class)); cards.add(new SetCardInfo("Peek", 91, Rarity.COMMON, mage.cards.p.Peek.class)); cards.add(new SetCardInfo("Persuasion", 92, Rarity.RARE, mage.cards.p.Persuasion.class)); cards.add(new SetCardInfo("Petrified Field", 323, Rarity.RARE, mage.cards.p.PetrifiedField.class));