Merge pull request #4139 from Zzooouhh/master

Implemented a whole bunch of cards + fixes for #4131, #4137, #4138 and #4090
This commit is contained in:
LevelX2 2017-11-02 14:08:26 +01:00 committed by GitHub
commit 583033ff3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 2235 additions and 42 deletions

View file

@ -31,16 +31,22 @@ import java.util.UUID;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseColorEffect;
import mage.abilities.effects.common.continuous.GainProtectionFromColorTargetEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.AbilityWord;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.filter.FilterObject;
import mage.filter.StaticFilters;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -49,7 +55,7 @@ import mage.target.targetpointer.FixedTarget;
/**
*
* @author LevelX2
* @author LevelX2 & L_J
*/
public class BatheInLight extends CardImpl {
@ -57,7 +63,6 @@ public class BatheInLight extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// Radiance - Choose a color. Target creature and each other creature that shares a color with it gain protection from the chosen color until end of turn.
this.getSpellAbility().addEffect(new ChooseColorEffect(Outcome.Benefit));
this.getSpellAbility().addEffect(new BatheInLightEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().setAbilityWord(AbilityWord.RADIANCE);
@ -95,19 +100,71 @@ class BatheInLightEffect extends OneShotEffect {
if (controller != null) {
Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
if (target != null) {
ObjectColor protectColor = (ObjectColor) game.getState().getValue(target.getId() + "_color");
if (protectColor != null) {
ObjectColor color = target.getColor(game);
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
if (permanent.getColor(game).shares(color)) {
ContinuousEffect effect = new GainProtectionFromColorTargetEffect(Duration.EndOfTurn, protectColor);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
ChoiceColor colorChoice = new ChoiceColor();
if (controller.choose(Outcome.Benefit, colorChoice, game)) {
game.informPlayers(target.getName() + ": " + controller.getLogName() + " has chosen " + colorChoice.getChoice());
game.getState().setValue(target.getId() + "_color", colorChoice.getColor());
ObjectColor protectColor = (ObjectColor) game.getState().getValue(target.getId() + "_color");
if (protectColor != null) {
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
game.addEffect(effect, source);
ObjectColor color = target.getColor(game);
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
if (permanent != target && permanent.getColor(game).shares(color)) {
game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
}
}
}
}
}
return true;
}
}
return false;
}
}
class ProtectionChosenColorTargetEffect extends ContinuousEffectImpl {
protected ObjectColor chosenColor;
protected ProtectionAbility protectionAbility;
public ProtectionChosenColorTargetEffect() {
super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
}
public ProtectionChosenColorTargetEffect(final ProtectionChosenColorTargetEffect effect) {
super(effect);
if (effect.chosenColor != null) {
this.chosenColor = effect.chosenColor.copy();
}
if (effect.protectionAbility != null) {
this.protectionAbility = effect.protectionAbility.copy();
}
}
@Override
public ProtectionChosenColorTargetEffect copy() {
return new ProtectionChosenColorTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
ObjectColor color = (ObjectColor) game.getState().getValue(permanent.getId() + "_color");
if (color != null && (protectionAbility == null || !color.equals(chosenColor))) {
chosenColor = color;
FilterObject protectionFilter = new FilterObject(chosenColor.getDescription());
protectionFilter.add(new ColorPredicate(chosenColor));
protectionAbility = new ProtectionAbility(protectionFilter);
}
if (protectionAbility != null) {
permanent.addAbility(protectionAbility, source.getSourceId(), game);
return true;
}
}
return false;
}

View file

@ -45,6 +45,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
@ -71,7 +72,6 @@ public class DaughterOfAutumn extends CardImpl {
// {W}: The next 1 damage that would be dealt to target white creature this turn is dealt to Daughter of Autumn instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DaughterOfAutumnPreventDamageTargetEffect(Duration.EndOfTurn, 1), new ManaCostsImpl("{W}"));
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}
public DaughterOfAutumn(final DaughterOfAutumn card) {
@ -86,6 +86,8 @@ public class DaughterOfAutumn extends CardImpl {
class DaughterOfAutumnPreventDamageTargetEffect extends RedirectionEffect {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
public DaughterOfAutumnPreventDamageTargetEffect(Duration duration, int amount) {
super(duration, amount, true);
staticText = "The next " + amount + " damage that would be dealt to target white creature this turn is dealt to {this} instead";
@ -102,13 +104,19 @@ class DaughterOfAutumnPreventDamageTargetEffect extends RedirectionEffect {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(getTargetPointer().getFirst(game, source))) {
TargetPermanent target = new TargetPermanent();
target.add(source.getSourceId(), game);
redirectTarget = target;
return true;
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null) {
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
if (event.getTargetId().equals(getTargetPointer().getFirst(game, source))) {
if (event.getTargetId() != null) {
TargetPermanent target = new TargetPermanent();
target.add(source.getSourceId(), game);
redirectTarget = target;
return true;
}
}
}
}
return false;
}
}

View file

@ -0,0 +1,231 @@
/*
* 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.d;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventDamageBySourceEffect;
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.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.filter.FilterObject;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.players.Player;
import mage.target.TargetSource;
/**
*
* @author L_J
*/
public class DesperateGambit extends CardImpl {
public DesperateGambit(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");
// Choose a source you control and flip a coin. If you win the flip, the next time that source would deal damage this turn, it deals double that damage instead. If you lose the flip, the next time it would deal damage this turn, prevent that damage.
this.getSpellAbility().addEffect(new DesperateGambitEffect());
}
public DesperateGambit(final DesperateGambit card) {
super(card);
}
@Override
public DesperateGambit copy() {
return new DesperateGambit(this);
}
}
class DesperateGambitEffect extends PreventionEffectImpl {
private final TargetSource target;
private boolean wonFlip;
public DesperateGambitEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, false);
staticText = "Choose a source you control and flip a coin. If you win the flip, the next time that source would deal damage this turn, it deals double that damage instead. If you lose the flip, the next time it would deal damage this turn, prevent that damage";
this.target = new TargetControlledSource();
}
public DesperateGambitEffect(final DesperateGambitEffect effect) {
super(effect);
this.target = effect.target.copy();
}
@Override
public void init(Ability source, Game game) {
this.target.choose(Outcome.Benefit, source.getControllerId(), source.getSourceId(), game);
this.wonFlip = game.getPlayer(source.getControllerId()).flipCoin(game);
super.init(source, game);
}
@Override
public DesperateGambitEffect copy() {
return new DesperateGambitEffect(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) {
if (event.getSourceId().equals(target.getFirstTarget())) {
// check source
MageObject object = game.getObject(event.getSourceId());
if (object == null) {
game.informPlayers("Couldn't find source of damage");
return false;
}
return true;
}
return false;
}
@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 (super.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {
if (wonFlip) {
event.setAmount(event.getAmount() * 2);
this.discard();
} else {
preventDamageAction(event, source, game);
this.discard();
return true;
}
}
}
return false;
}
}
class TargetControlledSource extends TargetSource {
public TargetControlledSource() {
super(1, 1, new FilterObject("source you control"));
}
public TargetControlledSource(final TargetControlledSource target) {
super(target);
}
@Override
public boolean canChoose(UUID sourceControllerId, Game game) {
int count = 0;
for (StackObject stackObject: game.getStack()) {
if (game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
&& stackObject.getControllerId() == sourceControllerId) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(sourceControllerId, game)) {
if (permanent.getControllerId() == sourceControllerId) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
for (Player player : game.getPlayers().values()) {
if (player == game.getPlayer(sourceControllerId)) {
for (Card card : player.getGraveyard().getCards(game)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
// 108.4a If anything asks for the controller of a card that doesnt have one (because its not a permanent or spell), use its owner instead.
for (Card card : game.getExile().getAllCards(game)) {
if (card.getOwnerId() == sourceControllerId) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
}
}
}
}
}
return false;
}
@Override
public Set<UUID> possibleTargets(UUID sourceControllerId, Game game) {
Set<UUID> possibleTargets = new HashSet<>();
for (StackObject stackObject: game.getStack()) {
if (game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
&& stackObject.getControllerId() == sourceControllerId) {
possibleTargets.add(stackObject.getId());
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(sourceControllerId, game)) {
if (permanent.getControllerId() == sourceControllerId) {
possibleTargets.add(permanent.getId());
}
}
for (Player player : game.getPlayers().values()) {
if (player == game.getPlayer(sourceControllerId)) {
for (Card card : player.getGraveyard().getCards(game)) {
possibleTargets.add(card.getId());
}
// 108.4a If anything asks for the controller of a card that doesnt have one (because its not a permanent or spell), use its owner instead.
for (Card card : game.getExile().getAllCards(game)) {
if (card.getOwnerId() == sourceControllerId) {
possibleTargets.add(card.getId());
}
}
}
}
return possibleTargets;
}
@Override
public TargetControlledSource copy() {
return new TargetControlledSource(this);
}
}

View file

@ -0,0 +1,69 @@
/*
* 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.e;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetCardInGraveyard;
/**
*
* @author L_J
*/
public class EndbringersRevel extends CardImpl {
public EndbringersRevel(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}");
// {4}: Return target creature card from a graveyard to its owner's hand. Any player may activate this ability but only any time he or she could cast a sorcery.
ActivateAsSorceryActivatedAbility ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{4}"));
ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")));
ability.setMayActivate(TargetController.ANY);
ability.addEffect(new InfoEffect("Any player may activate this ability"));
this.addAbility(ability);
}
public EndbringersRevel(final EndbringersRevel card) {
super(card);
}
@Override
public EndbringersRevel copy() {
return new EndbringersRevel(this);
}
}

View file

@ -0,0 +1,137 @@
/*
* 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.e;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.SacrificeTargetCost;
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.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetCard;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author L_J
*/
public class EyeOfYawgmoth extends CardImpl {
public EyeOfYawgmoth(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
// {3}, {T}, Sacrifice a creature: Reveal a number of cards from the top of your library equal to the sacrificed creature's power. Put one into your hand and exile the rest.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EyeOfYawgmothEffect(), new GenericManaCost(3));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, new FilterControlledCreaturePermanent("a creature"), true)));
this.addAbility(ability);
}
public EyeOfYawgmoth(final EyeOfYawgmoth card) {
super(card);
}
@Override
public EyeOfYawgmoth copy() {
return new EyeOfYawgmoth(this);
}
}
class EyeOfYawgmothEffect extends OneShotEffect {
EyeOfYawgmothEffect() {
super(Outcome.Benefit);
this.staticText = "Reveal a number of cards from the top of your library equal to the sacrificed creature's power. Put one into your hand and exile the rest";
}
EyeOfYawgmothEffect(final EyeOfYawgmothEffect effect) {
super(effect);
}
@Override
public EyeOfYawgmothEffect copy() {
return new EyeOfYawgmothEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
int power = 0;
for (Cost cost: source.getCosts()) {
if (cost instanceof SacrificeTargetCost && !((SacrificeTargetCost) cost).getPermanents().isEmpty()) {
power = ((SacrificeTargetCost)cost).getPermanents().get(0).getPower().getValue();
break;
}
}
if (power > 0) {
Cards cards = new CardsImpl();
int count = Math.min(controller.getLibrary().size(), power);
for (int i = 0; i < count; i++) {
Card card = controller.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
}
}
controller.revealCards(source.getSourceObject(game).getIdName(), cards, game);
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put into your hand"));
if (controller.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
game.informPlayers(source.getSourceObject(game).getIdName() + ": " + controller.getLogName() + " puts " + card.getIdName() + " into his or her hand");
}
}
for (UUID cardId : cards) {
Card card = game.getCard(cardId);
card.moveToExile(null, "", source.getSourceId(), game);
}
}
return true;
}
}

View file

@ -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.i;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAllTriggeredAbility;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventDamageBySourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SetTargetPointer;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.players.Player;
/**
*
* @author L_J
*/
public class ImpulsiveManeuvers extends CardImpl {
public ImpulsiveManeuvers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}{R}");
// Whenever a creature attacks, flip a coin. If you win the flip, the next time that creature would deal combat damage this turn, it deals double that damage instead. If you lose the flip, the next time that creature would deal combat damage this turn, prevent that damage.
this.addAbility(new AttacksAllTriggeredAbility(new ImpulsiveManeuversEffect(), false, StaticFilters.FILTER_PERMANENT_CREATURE,
SetTargetPointer.PERMANENT, false));
}
public ImpulsiveManeuvers(final ImpulsiveManeuvers card) {
super(card);
}
@Override
public ImpulsiveManeuvers copy() {
return new ImpulsiveManeuvers(this);
}
}
class ImpulsiveManeuversEffect extends PreventionEffectImpl {
private boolean wonFlip;
public ImpulsiveManeuversEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, false);
staticText = "flip a coin. If you win the flip, the next time that creature would deal combat damage this turn, it deals double that damage instead. If you lose the flip, the next time that creature would deal combat damage this turn, prevent that damage";
}
public ImpulsiveManeuversEffect(final ImpulsiveManeuversEffect 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 ImpulsiveManeuversEffect copy() {
return new ImpulsiveManeuversEffect(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(this.getTargetPointer().getFirst(game, source));
}
@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 (super.applies(event, source, game) && event instanceof DamageEvent && event.getAmount() > 0) {
DamageEvent damageEvent = (DamageEvent) event;
if (damageEvent.isCombatDamage()) {
if (wonFlip) {
event.setAmount(event.getAmount() * 2);
this.discard();
} else {
preventDamageAction(event, source, game);
this.discard();
return true;
}
}
}
}
return false;
}
}

View file

@ -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.l;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BecomesBlockedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
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.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class LaccolithGrunt extends CardImpl {
public LaccolithGrunt(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Laccolith Grunt becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Grunt assigns no combat damage this turn.
Ability ability = new BecomesBlockedTriggeredAbility(new LaccolithEffect().setText("you may have it deal damage equal to its power to target creature"), true);
ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public LaccolithGrunt(final LaccolithGrunt card) {
super(card);
}
@Override
public LaccolithGrunt copy() {
return new LaccolithGrunt(this);
}
class LaccolithEffect extends OneShotEffect {
public LaccolithEffect() {
super(Outcome.Damage);
staticText = "{this} deals damage equal to its power to target creature";
}
public LaccolithEffect(final LaccolithEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent == null) {
sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
if (sourcePermanent == null) {
return false;
}
int damage = sourcePermanent.getPower().getValue();
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
permanent.damage(damage, sourcePermanent.getId(), game, false, true);
return true;
}
return false;
}
@Override
public LaccolithEffect copy() {
return new LaccolithEffect(this);
}
}
}

View file

@ -0,0 +1,161 @@
/*
* 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.BecomesBlockedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.EnchantAbility;
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.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author L_J
*/
public class LaccolithRig extends CardImpl {
public LaccolithRig(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Whenever enchanted creature becomes blocked, you may have it deal damage equal to its power to target creature. If you do, the first creature assigns no combat damage this turn.
Ability ability2 = new LaccolithRigTriggeredAbility(new LaccolithRigEffect(), true);
ability2.addTarget(new TargetCreaturePermanent());
Effect effect = new GainAbilityTargetEffect(new SimpleStaticAbility(Zone.BATTLEFIELD, new AssignNoCombatDamageSourceEffect(Duration.Custom, true).setText("")), Duration.EndOfTurn, "If you do, the first creature assigns no combat damage this turn");
ability2.addEffect(effect);
this.addAbility(ability2);
}
public LaccolithRig(final LaccolithRig card) {
super(card);
}
@Override
public LaccolithRig copy() {
return new LaccolithRig(this);
}
}
class LaccolithRigTriggeredAbility extends TriggeredAbilityImpl {
public LaccolithRigTriggeredAbility(Effect effect, boolean optional) {
super(Zone.BATTLEFIELD, effect, optional);
}
public LaccolithRigTriggeredAbility(final LaccolithRigTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.CREATURE_BLOCKED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent equipment = game.getPermanent(sourceId);
if (equipment != null && equipment.getAttachedTo() != null) {
Permanent equipped = game.getPermanent(equipment.getAttachedTo());
if (equipped.getId().equals(event.getTargetId())) {
getEffects().get(1).setTargetPointer(new FixedTarget(equipped.getId()));
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever enchanted creature becomes blocked by a creature, " + super.getRule();
}
@Override
public LaccolithRigTriggeredAbility copy() {
return new LaccolithRigTriggeredAbility(this);
}
}
class LaccolithRigEffect extends OneShotEffect {
public LaccolithRigEffect() {
super(Outcome.Damage);
this.staticText = "you may have it deal damage equal to its power to target creature";
}
public LaccolithRigEffect(final LaccolithRigEffect effect) {
super(effect);
}
@Override
public LaccolithRigEffect copy() {
return new LaccolithRigEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
Permanent ownCreature = game.getPermanent(enchantment.getAttachedTo());
if (ownCreature != null) {
int damage = ownCreature.getPower().getValue();
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
if (targetCreature != null) {
targetCreature.damage(damage, ownCreature.getId(), game, false, true);
return true;
}
}
return false;
}
}

View file

@ -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.l;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BecomesBlockedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
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.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class LaccolithTitan extends CardImpl {
public LaccolithTitan(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}{R}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Whenever Laccolith Grunt becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Grunt assigns no combat damage this turn.
Ability ability = new BecomesBlockedTriggeredAbility(new LaccolithEffect().setText("you may have it deal damage equal to its power to target creature"), true);
ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public LaccolithTitan(final LaccolithTitan card) {
super(card);
}
@Override
public LaccolithTitan copy() {
return new LaccolithTitan(this);
}
class LaccolithEffect extends OneShotEffect {
public LaccolithEffect() {
super(Outcome.Damage);
staticText = "{this} deals damage equal to its power to target creature";
}
public LaccolithEffect(final LaccolithEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent == null) {
sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
if (sourcePermanent == null) {
return false;
}
int damage = sourcePermanent.getPower().getValue();
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
permanent.damage(damage, sourcePermanent.getId(), game, false, true);
return true;
}
return false;
}
@Override
public LaccolithEffect copy() {
return new LaccolithEffect(this);
}
}
}

View file

@ -0,0 +1,113 @@
/*
* 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.BecomesBlockedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
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.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class LaccolithWarrior extends CardImpl {
public LaccolithWarrior(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.subtype.add(SubType.BEAST);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Laccolith Grunt becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Grunt assigns no combat damage this turn.
Ability ability = new BecomesBlockedTriggeredAbility(new LaccolithEffect().setText("you may have it deal damage equal to its power to target creature"), true);
ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public LaccolithWarrior(final LaccolithWarrior card) {
super(card);
}
@Override
public LaccolithWarrior copy() {
return new LaccolithWarrior(this);
}
class LaccolithEffect extends OneShotEffect {
public LaccolithEffect() {
super(Outcome.Damage);
staticText = "{this} deals damage equal to its power to target creature";
}
public LaccolithEffect(final LaccolithEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent == null) {
sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
if (sourcePermanent == null) {
return false;
}
int damage = sourcePermanent.getPower().getValue();
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
permanent.damage(damage, sourcePermanent.getId(), game, false, true);
return true;
}
return false;
}
@Override
public LaccolithEffect copy() {
return new LaccolithEffect(this);
}
}
}

View file

@ -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.l;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BecomesBlockedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.AssignNoCombatDamageSourceEffect;
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.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class LaccolithWhelp extends CardImpl {
public LaccolithWhelp(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Whenever Laccolith Grunt becomes blocked, you may have it deal damage equal to its power to target creature. If you do, Laccolith Grunt assigns no combat damage this turn.
Ability ability = new BecomesBlockedTriggeredAbility(new LaccolithEffect().setText("you may have it deal damage equal to its power to target creature"), true);
ability.addEffect(new AssignNoCombatDamageSourceEffect(Duration.EndOfTurn, true));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public LaccolithWhelp(final LaccolithWhelp card) {
super(card);
}
@Override
public LaccolithWhelp copy() {
return new LaccolithWhelp(this);
}
class LaccolithEffect extends OneShotEffect {
public LaccolithEffect() {
super(Outcome.Damage);
staticText = "{this} deals damage equal to its power to target creature";
}
public LaccolithEffect(final LaccolithEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent == null) {
sourcePermanent = (Permanent) game.getLastKnownInformation(source.getSourceId(), Zone.BATTLEFIELD);
}
if (sourcePermanent == null) {
return false;
}
int damage = sourcePermanent.getPower().getValue();
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
permanent.damage(damage, sourcePermanent.getId(), game, false, true);
return true;
}
return false;
}
@Override
public LaccolithEffect copy() {
return new LaccolithEffect(this);
}
}
}

View file

@ -0,0 +1,129 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.l;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FlashAbility;
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.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class LatullasOrders extends CardImpl {
public LatullasOrders(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}");
this.subtype.add(SubType.AURA);
// Flash
this.addAbility(FlashAbility.getInstance());
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Protect));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// Whenever enchanted creature deals combat damage to defending player, you may destroy target artifact that player controls.
this.addAbility(new LatullasOrdersTriggeredAbility());
}
public LatullasOrders(final LatullasOrders card) {
super(card);
}
@Override
public LatullasOrders copy() {
return new LatullasOrders(this);
}
}
class LatullasOrdersTriggeredAbility extends TriggeredAbilityImpl {
public LatullasOrdersTriggeredAbility() {
super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true);
}
public LatullasOrdersTriggeredAbility(final LatullasOrdersTriggeredAbility ability) {
super(ability);
}
@Override
public LatullasOrdersTriggeredAbility copy() {
return new LatullasOrdersTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DAMAGED_PLAYER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(this.getSourceId());
if (event.getSourceId().equals(enchantment.getAttachedTo()) && ((DamagedPlayerEvent) event).isCombatDamage()) {
Player player = game.getPlayer(event.getTargetId());
if (player != null) {
FilterPermanent filter = new FilterPermanent("an artifact controlled by " + player.getLogName());
filter.add(new CardTypePredicate(CardType.ARTIFACT));
filter.add(new ControllerIdPredicate(event.getTargetId()));
this.getTargets().clear();
this.addTarget(new TargetPermanent(filter));
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever enchanted creature deals combat damage to defending player, you may destroy target artifact that player controls.";
}
}

View file

@ -0,0 +1,192 @@
/*
* 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.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.effects.RedirectionEffect;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.EffectType;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author L_J
*/
public class Martyrdom extends CardImpl {
public Martyrdom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}{W}");
// Until end of turn, target creature you control gains "{0}: The next 1 damage that would be dealt to target creature or player this turn is dealt to this creature instead." Only you may activate this ability.
this.getSpellAbility().addEffect(new MartyrdomGainAbilityTargetEffect());
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
}
public Martyrdom(final Martyrdom card) {
super(card);
}
@Override
public Martyrdom copy() {
return new Martyrdom(this);
}
}
class MartyrdomGainAbilityTargetEffect extends ContinuousEffectImpl {
public MartyrdomGainAbilityTargetEffect() {
super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.staticText = "Until end of turn, target creature you control gains \"{0}: The next 1 damage that would be dealt to target creature or player this turn is dealt to this creature instead.\" Only you may activate this ability";
}
public MartyrdomGainAbilityTargetEffect(final MartyrdomGainAbilityTargetEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
ActivatedAbilityImpl ability = new MartyrdomActivatedAbility(source.getControllerId());
ability.setMayActivate(TargetController.ANY);
permanent.addAbility(ability, source.getSourceId(), game, false);
return true;
}
return false;
}
@Override
public MartyrdomGainAbilityTargetEffect copy() {
return new MartyrdomGainAbilityTargetEffect(this);
}
}
class MartyrdomActivatedAbility extends ActivatedAbilityImpl {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
private UUID caster;
public MartyrdomActivatedAbility(UUID caster) {
super(Zone.BATTLEFIELD, new MartyrdomRedirectDamageTargetEffect(Duration.EndOfTurn, 1), new GenericManaCost(0));
this.addTarget(new TargetCreatureOrPlayer());
this.caster = caster;
}
private MartyrdomActivatedAbility(final MartyrdomActivatedAbility ability) {
super(ability);
this.caster = ability.caster;
}
@Override
public Effects getEffects(Game game, EffectType effectType) {
return super.getEffects(game, effectType);
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if (playerId == caster) {
Permanent permanent = game.getBattlefield().getPermanent(this.getSourceId());
if (permanent != null) {
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
return super.canActivate(playerId, game);
}
}
}
return false;
}
@Override
public MartyrdomActivatedAbility copy() {
return new MartyrdomActivatedAbility(this);
}
@Override
public String getRule() {
return "{0}: The next 1 damage that would be dealt to target creature or player this turn is dealt to {this} instead.";
}
}
class MartyrdomRedirectDamageTargetEffect extends RedirectionEffect {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
public MartyrdomRedirectDamageTargetEffect(Duration duration, int amount) {
super(duration, amount, true);
staticText = "The next " + amount + " damage that would be dealt to target creature or player this turn is dealt to {this} instead";
}
public MartyrdomRedirectDamageTargetEffect(final MartyrdomRedirectDamageTargetEffect effect) {
super(effect);
}
@Override
public MartyrdomRedirectDamageTargetEffect copy() {
return new MartyrdomRedirectDamageTargetEffect(this);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null) {
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
if (event.getTargetId().equals(getTargetPointer().getFirst(game, source))) {
if (event.getTargetId() != null) {
TargetCreatureOrPlayer target = new TargetCreatureOrPlayer();
target.add(source.getSourceId(), game);
redirectTarget = target;
return true;
}
}
}
}
return false;
}
}

View file

@ -29,27 +29,36 @@ package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.UntapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.filter.FilterObject;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author jeffwadsworth
*
* @author jeffwadsworth & L_J
*/
public class PaleWayfarer extends CardImpl {
@ -92,7 +101,7 @@ class PaleWayfarerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetCreature != null) {
Player player = game.getPlayer(targetCreature.getControllerId());
if (player != null) {
@ -100,7 +109,15 @@ class PaleWayfarerEffect extends OneShotEffect {
if (player.choose(Outcome.Neutral, colorChoice, game)) {
game.informPlayers(targetCreature.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice());
game.getState().setValue(targetCreature.getId() + "_color", colorChoice.getColor());
ObjectColor protectColor = (ObjectColor) game.getState().getValue(targetCreature.getId() + "_color");
if (protectColor != null) {
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
effect.setTargetPointer(new FixedTarget(targetCreature, game));
game.addEffect(effect, source);
}
}
return true;
}
}
return false;
@ -110,4 +127,49 @@ class PaleWayfarerEffect extends OneShotEffect {
public PaleWayfarerEffect copy() {
return new PaleWayfarerEffect(this);
}
}
}
class ProtectionChosenColorTargetEffect extends ContinuousEffectImpl {
protected ObjectColor chosenColor;
protected ProtectionAbility protectionAbility;
public ProtectionChosenColorTargetEffect() {
super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
}
public ProtectionChosenColorTargetEffect(final ProtectionChosenColorTargetEffect effect) {
super(effect);
if (effect.chosenColor != null) {
this.chosenColor = effect.chosenColor.copy();
}
if (effect.protectionAbility != null) {
this.protectionAbility = effect.protectionAbility.copy();
}
}
@Override
public ProtectionChosenColorTargetEffect copy() {
return new ProtectionChosenColorTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
ObjectColor color = (ObjectColor) game.getState().getValue(permanent.getId() + "_color");
if (color != null && (protectionAbility == null || !color.equals(chosenColor))) {
chosenColor = color;
FilterObject protectionFilter = new FilterObject(chosenColor.getDescription());
protectionFilter.add(new ColorPredicate(chosenColor));
protectionAbility = new ProtectionAbility(protectionFilter);
}
if (protectionAbility != null) {
permanent.addAbility(protectionAbility, source.getSourceId(), game);
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class Sailmonger extends CardImpl {
public Sailmonger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MONGER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// {2}: Target creature gains flying until end of turn. Any player may activate this ability.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{2}"));
ability.addTarget(new TargetCreaturePermanent());
ability.setMayActivate(TargetController.ANY);
ability.addEffect(new InfoEffect("Any player may activate this ability"));
this.addAbility(ability);
}
public Sailmonger(final Sailmonger card) {
super(card);
}
@Override
public Sailmonger copy() {
return new Sailmonger(this);
}
}

View file

@ -43,9 +43,11 @@ import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.TargetSource;
@ -91,6 +93,7 @@ public class ShamanEnKor extends CardImpl {
class ShamanEnKorRedirectFromTargetEffect extends RedirectionEffect {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
protected MageObjectReference sourceObject;
ShamanEnKorRedirectFromTargetEffect() {
@ -122,10 +125,15 @@ class ShamanEnKorRedirectFromTargetEffect extends RedirectionEffect {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (sourceObject.equals(new MageObjectReference(event.getSourceId(), game))) {
redirectTarget = new TargetPermanent();
redirectTarget.add(source.getSourceId(), game);
return event.getTargetId().equals(getTargetPointer().getFirst(game, source));
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null) {
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
if (sourceObject.equals(new MageObjectReference(event.getSourceId(), game))) {
redirectTarget = new TargetPermanent();
redirectTarget.add(source.getSourceId(), game);
return event.getTargetId().equals(getTargetPointer().getFirst(game, source));
}
}
}
return false;
}

View file

@ -0,0 +1,135 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.SuspendAbility;
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.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetPermanentOrSuspendedCard;
/**
*
* @author L_J
*/
public class ShivanSandMage extends CardImpl {
public ShivanSandMage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}");
this.subtype.add(SubType.VIASHINO);
this.subtype.add(SubType.SHAMAN);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// When Shivan Sand-Mage enters the battlefield, choose one
// Remove two time counters from target permanent or suspended card.
Ability ability = new EntersBattlefieldTriggeredAbility(new ShivanSandMageEffect(false));
ability.addTarget(new TargetPermanentOrSuspendedCard());
// Put two time counters on target permanent with a time counter on it or suspended card.
Mode mode = new Mode();
mode.getEffects().add(new ShivanSandMageEffect(true));
mode.getTargets().add(new TargetPermanentOrSuspendedCard());
ability.addMode(mode);
ability.getModes().addMode(mode);
this.addAbility(ability);
// Suspend 4-{R}
this.addAbility(new SuspendAbility(4, new ManaCostsImpl("{R}"), this));
}
public ShivanSandMage(final ShivanSandMage card) {
super(card);
}
@Override
public ShivanSandMage copy() {
return new ShivanSandMage(this);
}
}
class ShivanSandMageEffect extends OneShotEffect {
private final boolean addCounters;
public ShivanSandMageEffect(boolean addCounters) {
super(Outcome.Benefit);
this.addCounters = addCounters;
if (addCounters) {
this.staticText = "put two time counters on target permanent or suspended card";
} else {
this.staticText = "remove two time counters from target permanent or suspended card";
}
}
public ShivanSandMageEffect(final ShivanSandMageEffect effect) {
super(effect);
this.addCounters = effect.addCounters;
}
@Override
public ShivanSandMageEffect copy() {
return new ShivanSandMageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) {
if (addCounters) {
permanent.addCounters(CounterType.TIME.createInstance(2), source, game);
} else {
permanent.removeCounters(CounterType.TIME.getName(), 2, game);
}
return true;
}
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
if (card != null) {
if (addCounters) {
card.addCounters(CounterType.TIME.createInstance(2), source, game);
} else {
card.removeCounters(CounterType.TIME.getName(), 2, game);
}
return true;
}
return false;
}
}

View file

@ -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.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.MorphAbility;
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.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetPermanentOrSuspendedCard;
/**
*
* @author L_J
*/
public class Timebender extends CardImpl {
public Timebender(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Morph {U}
this.addAbility(new MorphAbility(this, new ManaCostsImpl("{U}")));
// When Timebender is turned face up, choose one
// Remove two time counters from target permanent or suspended card.
Ability ability = new TurnedFaceUpSourceTriggeredAbility(new TimebenderEffect(false));
ability.addTarget(new TargetPermanentOrSuspendedCard());
// Put two time counters on target permanent with a time counter on it or suspended card.
Mode mode = new Mode();
mode.getEffects().add(new TimebenderEffect(true));
mode.getTargets().add(new TargetPermanentOrSuspendedCard());
ability.addMode(mode);
ability.getModes().addMode(mode);
this.addAbility(ability);
}
public Timebender(final Timebender card) {
super(card);
}
@Override
public Timebender copy() {
return new Timebender(this);
}
}
class TimebenderEffect extends OneShotEffect {
private final boolean addCounters;
public TimebenderEffect(boolean addCounters) {
super(Outcome.Benefit);
this.addCounters = addCounters;
if (addCounters) {
this.staticText = "put two time counters on target permanent or suspended card";
} else {
this.staticText = "remove two time counters from target permanent or suspended card";
}
}
public TimebenderEffect(final TimebenderEffect effect) {
super(effect);
this.addCounters = effect.addCounters;
}
@Override
public TimebenderEffect copy() {
return new TimebenderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (permanent != null) {
if (addCounters) {
permanent.addCounters(CounterType.TIME.createInstance(2), source, game);
} else {
permanent.removeCounters(CounterType.TIME.getName(), 2, game);
}
return true;
}
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
if (card != null) {
if (addCounters) {
card.addCounters(CounterType.TIME.createInstance(2), source, game);
} else {
card.removeCounters(CounterType.TIME.getName(), 2, game);
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,175 @@
/*
* 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.w;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterObject;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author jeffwadsworth & L_J
*/
public class Wishmonger extends CardImpl {
public Wishmonger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");
this.subtype.add(SubType.UNICORN);
this.subtype.add(SubType.MONGER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// {2}: Target creature gains protection from the color of its controller's choice until end of turn. Any player may activate this ability.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new WishmongerEffect(), new ManaCostsImpl("{2}"));
ability.addTarget(new TargetCreaturePermanent());
ability.setMayActivate(TargetController.ANY);
ability.addEffect(new InfoEffect("Any player may activate this ability"));
this.addAbility(ability);
}
public Wishmonger(final Wishmonger card) {
super(card);
}
@Override
public Wishmonger copy() {
return new Wishmonger(this);
}
}
class WishmongerEffect extends OneShotEffect {
public WishmongerEffect() {
super(Outcome.BoostCreature);
staticText = "Target creature gains protection from the color of its controller's choice until end of turn";
}
public WishmongerEffect(final WishmongerEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetCreature != null) {
Player player = game.getPlayer(targetCreature.getControllerId());
if (player != null) {
ChoiceColor colorChoice = new ChoiceColor();
if (player.choose(Outcome.Neutral, colorChoice, game)) {
game.informPlayers(targetCreature.getName() + ": " + player.getLogName() + " has chosen " + colorChoice.getChoice());
game.getState().setValue(targetCreature.getId() + "_color", colorChoice.getColor());
ObjectColor protectColor = (ObjectColor) game.getState().getValue(targetCreature.getId() + "_color");
if (protectColor != null) {
ContinuousEffect effect = new ProtectionChosenColorTargetEffect();
effect.setTargetPointer(new FixedTarget(targetCreature, game));
game.addEffect(effect, source);
}
}
return true;
}
}
return false;
}
@Override
public WishmongerEffect copy() {
return new WishmongerEffect(this);
}
}
class ProtectionChosenColorTargetEffect extends ContinuousEffectImpl {
protected ObjectColor chosenColor;
protected ProtectionAbility protectionAbility;
public ProtectionChosenColorTargetEffect() {
super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
}
public ProtectionChosenColorTargetEffect(final ProtectionChosenColorTargetEffect effect) {
super(effect);
if (effect.chosenColor != null) {
this.chosenColor = effect.chosenColor.copy();
}
if (effect.protectionAbility != null) {
this.protectionAbility = effect.protectionAbility.copy();
}
}
@Override
public ProtectionChosenColorTargetEffect copy() {
return new ProtectionChosenColorTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
ObjectColor color = (ObjectColor) game.getState().getValue(permanent.getId() + "_color");
if (color != null && (protectionAbility == null || !color.equals(chosenColor))) {
chosenColor = color;
FilterObject protectionFilter = new FilterObject(chosenColor.getDescription());
protectionFilter.add(new ColorPredicate(chosenColor));
protectionAbility = new ProtectionAbility(protectionFilter);
}
if (protectionAbility != null) {
permanent.addAbility(protectionAbility, source.getSourceId(), game);
return true;
}
}
return false;
}
}

View file

@ -113,6 +113,8 @@ public class Alliances extends ExpansionSet {
cards.add(new SetCardInfo("Lim-Dul's Paladin", 191, Rarity.UNCOMMON, mage.cards.l.LimDulsPaladin.class));
cards.add(new SetCardInfo("Lim-Dul's Vault", 192, Rarity.UNCOMMON, mage.cards.l.LimDulsVault.class));
cards.add(new SetCardInfo("Lord of Tresserhorn", 193, Rarity.RARE, mage.cards.l.LordOfTresserhorn.class));
cards.add(new SetCardInfo("Martyrdom", 138, Rarity.COMMON, mage.cards.m.Martyrdom.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Martyrdom", 139, Rarity.COMMON, mage.cards.m.Martyrdom.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mishra's Groundbreaker", 165, Rarity.UNCOMMON, mage.cards.m.MishrasGroundbreaker.class));
cards.add(new SetCardInfo("Misinformation", 19, Rarity.UNCOMMON, mage.cards.m.Misinformation.class));
cards.add(new SetCardInfo("Mystic Compass", 166, Rarity.UNCOMMON, mage.cards.m.MysticCompass.class));

View file

@ -188,6 +188,7 @@ public class FutureSight extends ExpansionSet {
cards.add(new SetCardInfo("Seht's Tiger", 31, Rarity.RARE, mage.cards.s.SehtsTiger.class));
cards.add(new SetCardInfo("Shapeshifter's Marrow", 58, Rarity.RARE, mage.cards.s.ShapeshiftersMarrow.class));
cards.add(new SetCardInfo("Shimian Specter", 76, Rarity.RARE, mage.cards.s.ShimianSpecter.class));
cards.add(new SetCardInfo("Shivan Sand-Mage", 108, Rarity.UNCOMMON, mage.cards.s.ShivanSandMage.class));
cards.add(new SetCardInfo("Skirk Ridge Exhumer", 77, Rarity.UNCOMMON, mage.cards.s.SkirkRidgeExhumer.class));
cards.add(new SetCardInfo("Skizzik Surger", 120, Rarity.UNCOMMON, mage.cards.s.SkizzikSurger.class));
cards.add(new SetCardInfo("Slaughter Pact", 78, Rarity.RARE, mage.cards.s.SlaughterPact.class));

View file

@ -275,6 +275,7 @@ public class MercadianMasques extends ExpansionSet {
cards.add(new SetCardInfo("Rushwood Legate", 266, Rarity.UNCOMMON, mage.cards.r.RushwoodLegate.class));
cards.add(new SetCardInfo("Saber Ants", 267, Rarity.UNCOMMON, mage.cards.s.SaberAnts.class));
cards.add(new SetCardInfo("Sacred Prey", 268, Rarity.COMMON, mage.cards.s.SacredPrey.class));
cards.add(new SetCardInfo("Sailmonger", 95, Rarity.UNCOMMON, mage.cards.s.Sailmonger.class));
cards.add(new SetCardInfo("Sand Squid", 96, Rarity.RARE, mage.cards.s.SandSquid.class));
cards.add(new SetCardInfo("Sandstone Needle", 326, Rarity.COMMON, mage.cards.s.SandstoneNeedle.class));
cards.add(new SetCardInfo("Saprazzan Cove", 327, Rarity.UNCOMMON, mage.cards.s.SaprazzanCove.class));
@ -353,6 +354,7 @@ public class MercadianMasques extends ExpansionSet {
cards.add(new SetCardInfo("Waterfront Bouncer", 114, Rarity.COMMON, mage.cards.w.WaterfrontBouncer.class));
cards.add(new SetCardInfo("Wave of Reckoning", 56, Rarity.RARE, mage.cards.w.WaveOfReckoning.class));
cards.add(new SetCardInfo("Wild Jhovall", 227, Rarity.COMMON, mage.cards.w.WildJhovall.class));
cards.add(new SetCardInfo("Wishmonger", 57, Rarity.UNCOMMON, mage.cards.w.Wishmonger.class));
cards.add(new SetCardInfo("Word of Blasting", 228, Rarity.UNCOMMON, mage.cards.w.WordOfBlasting.class));
cards.add(new SetCardInfo("Worry Beads", 315, Rarity.RARE, mage.cards.w.WorryBeads.class));
}

View file

@ -85,6 +85,7 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Dominate", 31, Rarity.UNCOMMON, mage.cards.d.Dominate.class));
cards.add(new SetCardInfo("Downhill Charge", 79, Rarity.COMMON, mage.cards.d.DownhillCharge.class));
cards.add(new SetCardInfo("Ensnare", 32, Rarity.UNCOMMON, mage.cards.e.Ensnare.class));
cards.add(new SetCardInfo("Eye of Yawgmoth", 129, Rarity.RARE, mage.cards.e.EyeOfYawgmoth.class));
cards.add(new SetCardInfo("Fanatical Devotion", 8, Rarity.COMMON, mage.cards.f.FanaticalDevotion.class));
cards.add(new SetCardInfo("Flame Rift", 80, Rarity.COMMON, mage.cards.f.FlameRift.class));
cards.add(new SetCardInfo("Flowstone Armor", 131, Rarity.UNCOMMON, mage.cards.f.FlowstoneArmor.class));
@ -99,6 +100,11 @@ public class Nemesis extends ExpansionSet {
cards.add(new SetCardInfo("Jolting Merfolk", 34, Rarity.UNCOMMON, mage.cards.j.JoltingMerfolk.class));
cards.add(new SetCardInfo("Kill Switch", 133, Rarity.RARE, mage.cards.k.KillSwitch.class));
cards.add(new SetCardInfo("Kor Haven", 141, Rarity.RARE, mage.cards.k.KorHaven.class));
cards.add(new SetCardInfo("Laccolith Grunt", 87, Rarity.COMMON, mage.cards.l.LaccolithGrunt.class));
cards.add(new SetCardInfo("Laccolith Rig", 88, Rarity.COMMON, mage.cards.l.LaccolithRig.class));
cards.add(new SetCardInfo("Laccolith Titan", 89, Rarity.RARE, mage.cards.l.LaccolithTitan.class));
cards.add(new SetCardInfo("Laccolith Warrior", 90, Rarity.UNCOMMON, mage.cards.l.LaccolithWarrior.class));
cards.add(new SetCardInfo("Laccolith Whelp", 91, Rarity.COMMON, mage.cards.l.LaccolithWhelp.class));
cards.add(new SetCardInfo("Lashknife", 9, Rarity.COMMON, mage.cards.l.Lashknife.class));
cards.add(new SetCardInfo("Lawbringer", 10, Rarity.COMMON, mage.cards.l.Lawbringer.class));
cards.add(new SetCardInfo("Lightbringer", 11, Rarity.COMMON, mage.cards.l.Lightbringer.class));

View file

@ -186,6 +186,7 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Haunting Echoes", 142, Rarity.RARE, mage.cards.h.HauntingEchoes.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));
cards.add(new SetCardInfo("Infected Vermin", 144, Rarity.UNCOMMON, mage.cards.i.InfectedVermin.class));
cards.add(new SetCardInfo("Innocent Blood", 145, Rarity.COMMON, mage.cards.i.InnocentBlood.class));
cards.add(new SetCardInfo("Iridescent Angel", 288, Rarity.RARE, mage.cards.i.IridescentAngel.class));
@ -194,7 +195,7 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Island", 337, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Island", 338, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ivy Elemental", 245, Rarity.RARE, mage.cards.i.IvyElemental.class));
cards.add(new SetCardInfo("Junk Golem", 300, Rarity.RARE, mage.cards.j.JunkGolem.class));
cards.add(new SetCardInfo("Junk Golem", 300, Rarity.RARE, mage.cards.j.JunkGolem.class));
cards.add(new SetCardInfo("Kamahl, Pit Fighter", 198, Rarity.RARE, mage.cards.k.KamahlPitFighter.class));
cards.add(new SetCardInfo("Kamahl's Desire", 199, Rarity.COMMON, mage.cards.k.KamahlsDesire.class));
cards.add(new SetCardInfo("Karmic Justice", 26, Rarity.RARE, mage.cards.k.KarmicJustice.class));
@ -251,7 +252,7 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Nomad Stadium", 322, Rarity.UNCOMMON, mage.cards.n.NomadStadium.class));
cards.add(new SetCardInfo("Nut Collector", 259, Rarity.RARE, mage.cards.n.NutCollector.class));
cards.add(new SetCardInfo("Obstinate Familiar", 210, Rarity.RARE, mage.cards.o.ObstinateFamiliar.class));
cards.add(new SetCardInfo("Otarian Juggernaut", 305, Rarity.RARE, mage.cards.o.OtarianJuggernaut.class));
cards.add(new SetCardInfo("Otarian Juggernaut", 305, Rarity.RARE, mage.cards.o.OtarianJuggernaut.class));
cards.add(new SetCardInfo("Overeager Apprentice", 154, Rarity.COMMON, mage.cards.o.OvereagerApprentice.class));
cards.add(new SetCardInfo("Overrun", 260, Rarity.UNCOMMON, mage.cards.o.Overrun.class));
cards.add(new SetCardInfo("Pardic Firecat", 211, Rarity.COMMON, mage.cards.p.PardicFirecat.class));
@ -321,11 +322,11 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Soulcatcher", 47, Rarity.UNCOMMON, mage.cards.s.Soulcatcher.class));
cards.add(new SetCardInfo("Spark Mage", 222, Rarity.UNCOMMON, mage.cards.s.SparkMage.class));
cards.add(new SetCardInfo("Spellbane Centaur", 271, Rarity.RARE, mage.cards.s.SpellbaneCentaur.class));
cards.add(new SetCardInfo("Sphere of Duty", 48, Rarity.UNCOMMON, mage.cards.s.SphereOfDuty.class));
cards.add(new SetCardInfo("Sphere of Grace", 49, Rarity.UNCOMMON, mage.cards.s.SphereOfGrace.class));
cards.add(new SetCardInfo("Sphere of Law", 50, Rarity.UNCOMMON, mage.cards.s.SphereOfLaw.class));
cards.add(new SetCardInfo("Sphere of Reason", 51, Rarity.UNCOMMON, mage.cards.s.SphereOfReason.class));
cards.add(new SetCardInfo("Sphere of Truth", 52, Rarity.UNCOMMON, mage.cards.s.SphereOfTruth.class));
cards.add(new SetCardInfo("Sphere of Duty", 48, Rarity.UNCOMMON, mage.cards.s.SphereOfDuty.class));
cards.add(new SetCardInfo("Sphere of Grace", 49, Rarity.UNCOMMON, mage.cards.s.SphereOfGrace.class));
cards.add(new SetCardInfo("Sphere of Law", 50, Rarity.UNCOMMON, mage.cards.s.SphereOfLaw.class));
cards.add(new SetCardInfo("Sphere of Reason", 51, Rarity.UNCOMMON, mage.cards.s.SphereOfReason.class));
cards.add(new SetCardInfo("Sphere of Truth", 52, Rarity.UNCOMMON, mage.cards.s.SphereOfTruth.class));
cards.add(new SetCardInfo("Spiritualize", 53, Rarity.UNCOMMON, mage.cards.s.Spiritualize.class));
cards.add(new SetCardInfo("Springing Tiger", 272, Rarity.COMMON, mage.cards.s.SpringingTiger.class));
cards.add(new SetCardInfo("Squirrel Mob", 273, Rarity.RARE, mage.cards.s.SquirrelMob.class));
@ -361,7 +362,7 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Traumatize", 110, Rarity.RARE, mage.cards.t.Traumatize.class));
cards.add(new SetCardInfo("Treetop Sentinel", 111, Rarity.UNCOMMON, mage.cards.t.TreetopSentinel.class));
cards.add(new SetCardInfo("Tremble", 225, Rarity.COMMON, mage.cards.t.Tremble.class));
cards.add(new SetCardInfo("Twigwalker", 279, Rarity.UNCOMMON, mage.cards.t.Twigwalker.class));
cards.add(new SetCardInfo("Twigwalker", 279, Rarity.UNCOMMON, mage.cards.t.Twigwalker.class));
cards.add(new SetCardInfo("Unifying Theory", 112, Rarity.RARE, mage.cards.u.UnifyingTheory.class));
cards.add(new SetCardInfo("Upheaval", 113, Rarity.RARE, mage.cards.u.Upheaval.class));
cards.add(new SetCardInfo("Vampiric Dragon", 296, Rarity.RARE, mage.cards.v.VampiricDragon.class));

View file

@ -198,6 +198,7 @@ public class PlanarChaos extends ExpansionSet {
cards.add(new SetCardInfo("Teneb, the Harvester", 163, Rarity.RARE, mage.cards.t.TenebTheHarvester.class));
cards.add(new SetCardInfo("Tidewalker", 49, Rarity.UNCOMMON, mage.cards.t.Tidewalker.class));
cards.add(new SetCardInfo("Timbermare", 140, Rarity.RARE, mage.cards.t.Timbermare.class));
cards.add(new SetCardInfo("Timebender", 50, Rarity.UNCOMMON, mage.cards.t.Timebender.class));
cards.add(new SetCardInfo("Timecrafting", 109, Rarity.UNCOMMON, mage.cards.t.Timecrafting.class));
cards.add(new SetCardInfo("Torchling", 110, Rarity.RARE, mage.cards.t.Torchling.class));
cards.add(new SetCardInfo("Treacherous Urge", 82, Rarity.UNCOMMON, mage.cards.t.TreacherousUrge.class));

View file

@ -83,6 +83,7 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Diving Griffin", 6, Rarity.COMMON, mage.cards.d.DivingGriffin.class));
cards.add(new SetCardInfo("Dual Nature", 112, Rarity.RARE, mage.cards.d.DualNature.class));
cards.add(new SetCardInfo("Elephant Resurgence", 113, Rarity.RARE, mage.cards.e.ElephantResurgence.class));
cards.add(new SetCardInfo("Endbringer's Revel", 63, Rarity.UNCOMMON, mage.cards.e.EndbringersRevel.class));
cards.add(new SetCardInfo("Entangler", 7, Rarity.UNCOMMON, mage.cards.e.Entangler.class));
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));
@ -105,6 +106,7 @@ public class Prophecy extends ExpansionSet {
cards.add(new SetCardInfo("Keldon Berserker", 93, Rarity.COMMON, mage.cards.k.KeldonBerserker.class));
cards.add(new SetCardInfo("Keldon Firebombers", 94, Rarity.RARE, mage.cards.k.KeldonFirebombers.class));
cards.add(new SetCardInfo("Latulla, Keldon Overseer", 95, Rarity.RARE, mage.cards.l.LatullaKeldonOverseer.class));
cards.add(new SetCardInfo("Latulla's Orders", 96, Rarity.COMMON, mage.cards.l.LatullasOrders.class));
cards.add(new SetCardInfo("Lesser Gargadon", 97, Rarity.UNCOMMON, mage.cards.l.LesserGargadon.class));
cards.add(new SetCardInfo("Living Terrain", 117, Rarity.UNCOMMON, mage.cards.l.LivingTerrain.class));
cards.add(new SetCardInfo("Mageta's Boon", 14, Rarity.COMMON, mage.cards.m.MagetasBoon.class));

View file

@ -90,6 +90,7 @@ public class Weatherlight extends ExpansionSet {
cards.add(new SetCardInfo("Cone of Flame", 95, Rarity.UNCOMMON, mage.cards.c.ConeOfFlame.class));
cards.add(new SetCardInfo("Debt of Loyalty", 127, Rarity.RARE, mage.cards.d.DebtOfLoyalty.class));
cards.add(new SetCardInfo("Dense Foliage", 66, Rarity.RARE, mage.cards.d.DenseFoliage.class));
cards.add(new SetCardInfo("Desperate Gambit", 96, Rarity.UNCOMMON, mage.cards.d.DesperateGambit.class));
cards.add(new SetCardInfo("Dingus Staff", 149, Rarity.UNCOMMON, mage.cards.d.DingusStaff.class));
cards.add(new SetCardInfo("Disrupt", 37, Rarity.COMMON, mage.cards.d.Disrupt.class));
cards.add(new SetCardInfo("Doomsday", 8, Rarity.RARE, mage.cards.d.Doomsday.class));

View file

@ -10,6 +10,7 @@ import mage.abilities.effects.RedirectionEffect;
import mage.constants.Duration;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
@ -33,9 +34,14 @@ public class RedirectDamageFromSourceToTargetEffect extends RedirectionEffect {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(source.getSourceId())) {
this.redirectTarget = source.getTargets().get(0);
return true;
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null) {
if (event.getTargetId().equals(source.getSourceId())) {
if (getTargetPointer().getFirst(game, source) != null) {
this.redirectTarget = source.getTargets().get(0);
return true;
}
}
}
return false;
}

View file

@ -47,7 +47,7 @@ import mage.watchers.Watcher;
*
* @author emerald000
*/
public class MeleeAbility extends AttacksTriggeredAbility {
public class MeleeAbility extends AttacksTriggeredAbility {
public MeleeAbility() {
super(new BoostSourceEffect(new MeleeDynamicValue(), new MeleeDynamicValue(), Duration.EndOfTurn), false);
@ -71,7 +71,7 @@ public class MeleeAbility extends AttacksTriggeredAbility {
class MeleeWatcher extends Watcher {
private final HashMap<UUID, Set<UUID>> playersAttacked = new HashMap<>(0);
private HashMap<UUID, Set<UUID>> playersAttacked = new HashMap<>(0);
MeleeWatcher() {
super("MeleeWatcher", WatcherScope.GAME);
@ -95,7 +95,10 @@ class MeleeWatcher extends Watcher {
}
public int getNumberOfAttackedPlayers(UUID attackerId) {
return this.playersAttacked.get(attackerId).size();
if (this.playersAttacked.get(attackerId) != null) {
return this.playersAttacked.get(attackerId).size();
}
return 0;
}
@Override
@ -106,11 +109,18 @@ class MeleeWatcher extends Watcher {
class MeleeDynamicValue implements DynamicValue {
private boolean valueChecked = false;
private int lockedInValue;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
MeleeWatcher watcher = (MeleeWatcher) game.getState().getWatchers().get(MeleeWatcher.class.getSimpleName());
if (watcher != null) {
return watcher.getNumberOfAttackedPlayers(sourceAbility.getControllerId());
if (!valueChecked) {
this.lockedInValue = watcher.getNumberOfAttackedPlayers(sourceAbility.getControllerId());
valueChecked = true;
}
return this.lockedInValue;
}
return 0;
}