* Redirection effect - Added possibility to last for one applyEffect cycle instead of only one absolute use.

This commit is contained in:
LevelX2 2018-04-28 13:21:58 +02:00
parent b3d62865d9
commit 29605bc5ae
26 changed files with 149 additions and 99 deletions

View file

@ -37,20 +37,19 @@ import mage.abilities.effects.RedirectionEffect;
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.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.TargetSource;
/**
*
*
* @author L_J
*/
public class BeaconOfDestiny extends CardImpl {
@ -81,7 +80,7 @@ class BeaconOfDestinyEffect extends RedirectionEffect {
private final TargetSource damageSource;
public BeaconOfDestinyEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, true);
super(Duration.EndOfTurn, Integer.MAX_VALUE, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next time a source of your choice would deal damage to you this turn, that damage is dealt to {this} instead";
this.damageSource = new TargetSource();
}

View file

@ -49,22 +49,22 @@ import mage.target.common.TargetCreaturePermanent;
public class Carom extends CardImpl {
public Carom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{W}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// The next 1 damage that would be dealt to target creature this turn is dealt to another target creature instead.
// Draw a card.
this.getSpellAbility().addEffect(new CaromEffect(Duration.EndOfTurn, 1));
TargetCreaturePermanent target = new TargetCreaturePermanent();
target.setTargetTag(1);
this.getSpellAbility().addTarget(target);
FilterCreaturePermanent filter = new FilterCreaturePermanent("another creature (damage is redirected to)");
filter.add(new AnotherTargetPredicate(2));
TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter);
target2.setTargetTag(2);
this.getSpellAbility().addTarget(target2);
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
}
@ -79,29 +79,29 @@ public class Carom extends CardImpl {
}
class CaromEffect extends RedirectionEffect {
protected MageObjectReference redirectToObject;
public CaromEffect(Duration duration, int amount) {
super(duration, amount, true);
super(duration, amount, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next " + amount + " damage that would be dealt to target creature this turn is dealt to another target creature instead";
}
public CaromEffect(final CaromEffect effect) {
super(effect);
}
@Override
public CaromEffect copy() {
return new CaromEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
redirectToObject = new MageObjectReference(source.getTargets().get(1).getFirstTarget(), game);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getTargetId().equals(getTargetPointer().getFirst(game, source))) {

View file

@ -37,8 +37,8 @@ import mage.abilities.effects.RedirectionEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
@ -90,7 +90,7 @@ class DaughterOfAutumnPreventDamageTargetEffect extends RedirectionEffect {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
public DaughterOfAutumnPreventDamageTargetEffect(Duration duration, int amount) {
super(duration, amount, true);
super(duration, amount, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next " + amount + " damage that would be dealt to target white creature this turn is dealt to {this} instead";
}

View file

@ -41,20 +41,19 @@ import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.TargetSource;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
*
* @author L_J
*/
public class GeneralsRegalia extends CardImpl {
public GeneralsRegalia(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// {3}: The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature you control instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GeneralsRegaliaEffect(), new GenericManaCost(3));
@ -77,7 +76,7 @@ class GeneralsRegaliaEffect extends RedirectionEffect {
private final TargetSource damageSource;
public GeneralsRegaliaEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, true);
super(Duration.EndOfTurn, Integer.MAX_VALUE, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature you control instead";
this.damageSource = new TargetSource();
}

View file

@ -50,7 +50,7 @@ import mage.target.common.TargetAnyTarget;
public class HarmsWay extends CardImpl {
public HarmsWay(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{W}");
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
// The next 2 damage that a source of your choice would deal to you and/or permanents you control this turn is dealt to any target instead.
this.getSpellAbility().addEffect(new HarmsWayPreventDamageTargetEffect());
@ -72,7 +72,7 @@ class HarmsWayPreventDamageTargetEffect extends RedirectionEffect {
private final TargetSource damageSource;
public HarmsWayPreventDamageTargetEffect() {
super(Duration.EndOfTurn, 2, true);
super(Duration.EndOfTurn, 2, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next 2 damage that a source of your choice would deal to you and/or permanents you control this turn is dealt to any target instead";
this.damageSource = new TargetSource();
}

View file

@ -38,8 +38,8 @@ import mage.abilities.effects.RedirectionEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
@ -92,14 +92,14 @@ class HazduhrTheAbbotRedirectDamageEffect extends RedirectionEffect {
private static FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
public HazduhrTheAbbotRedirectDamageEffect(Duration duration) {
super(duration, 0, true);
super(duration, 0, UsageType.ONE_USAGE_ABSOLUTE);
this.staticText = "The next X damage that would be dealt this turn to target white creature you control is dealt to {this} instead";
}
public HazduhrTheAbbotRedirectDamageEffect(final HazduhrTheAbbotRedirectDamageEffect effect) {
super(effect);
}
@Override
public void init(Ability source, Game game) {
amountToRedirect = source.getManaCostsToPay().getX();

View file

@ -32,13 +32,14 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.TurnedFaceUpSourceTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import static mage.abilities.effects.RedirectionEffect.UsageType.ACCORDING_DURATION;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.abilities.keyword.MorphAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
/**
@ -58,7 +59,7 @@ public class KaronasZealot extends CardImpl {
this.addAbility(new MorphAbility(this, new ManaCostsImpl("{3}{W}{W}")));
// When Karona's Zealot is turned face up, all damage that would be dealt to it this turn is dealt to target creature instead.
Ability ability = new TurnedFaceUpSourceTriggeredAbility(new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE, false)
Ability ability = new TurnedFaceUpSourceTriggeredAbility(new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, Integer.MAX_VALUE, ACCORDING_DURATION)
.setText("all damage that would be dealt to it this turn is dealt to target creature instead"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);

View file

@ -32,13 +32,14 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import static mage.abilities.effects.RedirectionEffect.UsageType.ONE_USAGE_ABSOLUTE;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetControlledCreaturePermanent;
@ -49,7 +50,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class LancersEnKor extends CardImpl {
public LancersEnKor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.subtype.add(SubType.KOR);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
@ -57,9 +58,9 @@ public class LancersEnKor extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// {0}: The next 1 damage that would be dealt to Lancers en-Kor this turn is dealt to target creature you control instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new GenericManaCost(0));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, ONE_USAGE_ABSOLUTE), new GenericManaCost(0));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}

View file

@ -48,8 +48,8 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
@ -154,7 +154,7 @@ class MartyrdomRedirectDamageTargetEffect extends RedirectionEffect {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
public MartyrdomRedirectDamageTargetEffect(Duration duration, int amount) {
super(duration, amount, true);
super(duration, amount, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next " + amount + " damage that would be dealt to target creature, planeswalker, or player this turn is dealt to {this} instead";
}

View file

@ -32,12 +32,13 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import static mage.abilities.effects.RedirectionEffect.UsageType.ONE_USAGE_ABSOLUTE;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetControlledCreaturePermanent;
@ -48,7 +49,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class NomadsEnKor extends CardImpl {
public NomadsEnKor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}");
this.subtype.add(SubType.KOR);
this.subtype.add(SubType.NOMAD);
this.subtype.add(SubType.SOLDIER);
@ -57,7 +58,7 @@ public class NomadsEnKor extends CardImpl {
this.toughness = new MageInt(1);
// {0}: The next 1 damage that would be dealt to Nomads en-Kor this turn is dealt to target creature you control instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new GenericManaCost(0));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, ONE_USAGE_ABSOLUTE), new GenericManaCost(0));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}

View file

@ -43,20 +43,19 @@ 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.game.stack.Spell;
import mage.players.Player;
import mage.target.TargetSource;
import mage.target.common.TargetOpponentsChoicePermanent;
/**
*
*
* @author L_J
*/
public class NovaPentacle extends CardImpl {
public NovaPentacle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// {3}, {tap}: The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature of an opponent's choice instead
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new NovaPentacleEffect(), new GenericManaCost(3));
@ -80,7 +79,7 @@ class NovaPentacleEffect extends RedirectionEffect {
private final TargetSource damageSource;
public NovaPentacleEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, true);
super(Duration.EndOfTurn, Integer.MAX_VALUE, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next time a source of your choice would deal damage to you this turn, that damage is dealt to target creature of an opponent's choice instead";
this.damageSource = new TargetSource();
}

View file

@ -32,13 +32,14 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import static mage.abilities.effects.RedirectionEffect.UsageType.ONE_USAGE_ABSOLUTE;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.abilities.keyword.FlankingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetControlledCreaturePermanent;
@ -49,7 +50,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class OutriderEnKor extends CardImpl {
public OutriderEnKor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.KOR);
this.subtype.add(SubType.REBEL);
this.subtype.add(SubType.KNIGHT);
@ -58,9 +59,9 @@ public class OutriderEnKor extends CardImpl {
// Flanking
this.addAbility(new FlankingAbility());
// {0}: The next 1 damage that would be dealt to Outrider en-Kor this turn is dealt to target creature you control instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new GenericManaCost(0));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, ONE_USAGE_ABSOLUTE), new GenericManaCost(0));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}

View file

@ -38,9 +38,9 @@ import mage.abilities.effects.RedirectionEffect;
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.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
@ -56,7 +56,7 @@ public class PersonalIncarnation extends CardImpl {
public PersonalIncarnation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}{W}");
this.subtype.add(SubType.AVATAR);
this.subtype.add(SubType.INCARNATION);
this.power = new MageInt(6);
@ -83,7 +83,7 @@ public class PersonalIncarnation extends CardImpl {
class PersonalIncarnationRedirectEffect extends RedirectionEffect {
public PersonalIncarnationRedirectEffect() {
super(Duration.EndOfTurn, 1, true);
super(Duration.EndOfTurn, 1, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next 1 damage that would be dealt to {this} this turn is dealt to its owner instead.";
}

View file

@ -41,8 +41,8 @@ import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
@ -60,7 +60,7 @@ import mage.target.common.TargetCreaturePermanent;
public class RaziaBorosArchangel extends CardImpl {
public RaziaBorosArchangel(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{R}{R}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}{W}{W}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGEL);
@ -107,7 +107,7 @@ class RaziaBorosArchangelEffect extends RedirectionEffect {
protected MageObjectReference redirectToObject;
public RaziaBorosArchangelEffect(Duration duration, int amount) {
super(duration, 3, true);
super(duration, 3, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next " + amount + " damage that would be dealt to target creature you control this turn is dealt to another target creature instead";
}

View file

@ -35,13 +35,14 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.RedirectionEffect;
import mage.abilities.effects.RedirectionEffect.UsageType;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
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.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
@ -61,7 +62,7 @@ import mage.target.common.TargetCreaturePermanent;
public class ShamanEnKor extends CardImpl {
public ShamanEnKor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.KOR);
this.subtype.add(SubType.CLERIC);
this.subtype.add(SubType.SHAMAN);
@ -71,7 +72,7 @@ public class ShamanEnKor extends CardImpl {
// {0}: The next 1 damage that would be dealt to Shaman en-Kor this turn is dealt to target creature you control instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new GenericManaCost(0));
new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, UsageType.ONE_USAGE_ABSOLUTE), new GenericManaCost(0));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
@ -97,7 +98,7 @@ class ShamanEnKorRedirectFromTargetEffect extends RedirectionEffect {
protected MageObjectReference sourceObject;
ShamanEnKorRedirectFromTargetEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, true);
super(Duration.EndOfTurn, Integer.MAX_VALUE, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next time a source of your choice would deal damage to target creature this turn, that damage is dealt to {this} instead";
}

View file

@ -37,8 +37,8 @@ import mage.abilities.effects.RedirectionEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AttackingPredicate;
@ -88,7 +88,7 @@ class ShimianNightStalkerRedirectDamageEffect extends RedirectionEffect {
private static FilterCreaturePermanent filter = new FilterCreaturePermanent();
public ShimianNightStalkerRedirectDamageEffect() {
super(Duration.EndOfTurn, Integer.MAX_VALUE, true);
super(Duration.EndOfTurn, Integer.MAX_VALUE, UsageType.ONE_USAGE_ABSOLUTE);
this.staticText = "All damage that would be dealt to you this turn by target attacking creature is dealt to {this} instead";
}
@ -107,7 +107,7 @@ class ShimianNightStalkerRedirectDamageEffect extends RedirectionEffect {
if (permanent != null) {
if (filter.match(permanent, permanent.getId(), permanent.getControllerId(), game)) {
if (event.getSourceId() != null && event.getTargetId() != null) {
if (event.getSourceId().equals(getTargetPointer().getFirst(game, source))
if (event.getSourceId().equals(getTargetPointer().getFirst(game, source))
&& event.getTargetId().equals(source.getControllerId())) {
TargetPermanent target = new TargetPermanent();
target.add(source.getSourceId(), game);

View file

@ -50,8 +50,8 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetSource;
import mage.target.common.TargetCardInHand;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCardInHand;
/**
*
@ -90,7 +90,7 @@ class ShiningShoalRedirectDamageTargetEffect extends RedirectDamageFromSourceToT
private final DynamicValue dynamicAmount;
public ShiningShoalRedirectDamageTargetEffect(Duration duration, DynamicValue dynamicAmount) {
super(duration, 0, true);
super(duration, 0, UsageType.ONE_USAGE_AT_THE_SAME_TIME);
this.dynamicAmount = dynamicAmount;
staticText = "The next X damage that a source of your choice would deal to you and/or creatures you control this turn is dealt to any target instead";
}

View file

@ -32,13 +32,14 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import static mage.abilities.effects.RedirectionEffect.UsageType.ONE_USAGE_ABSOLUTE;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetControlledCreaturePermanent;
@ -49,7 +50,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class SpiritEnKor extends CardImpl {
public SpiritEnKor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.KOR);
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(2);
@ -60,7 +61,7 @@ public class SpiritEnKor extends CardImpl {
// {0}: The next 1 damage that would be dealt to Spirit en-Kor this turn is dealt to target creature you control instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new GenericManaCost(0));
new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, ONE_USAGE_ABSOLUTE), new GenericManaCost(0));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}

View file

@ -58,7 +58,7 @@ public class VassalsDuty extends CardImpl {
}
public VassalsDuty(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
// {1}: The next 1 damage that would be dealt to target legendary creature you control this turn is dealt to you instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new VassalsDutyPreventDamageTargetEffect(Duration.EndOfTurn, 1), new GenericManaCost(1));
@ -79,7 +79,7 @@ public class VassalsDuty extends CardImpl {
class VassalsDutyPreventDamageTargetEffect extends RedirectionEffect {
public VassalsDutyPreventDamageTargetEffect(Duration duration, int amount) {
super(duration, amount, true);
super(duration, amount, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next " + amount + " damage that would be dealt to target legendary creature you control this turn is dealt to you instead";
}

View file

@ -38,9 +38,9 @@ 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.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
@ -56,7 +56,7 @@ import mage.target.common.TargetCreaturePermanent;
public class WardOfPiety extends CardImpl {
public WardOfPiety(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{W}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
this.subtype.add(SubType.AURA);
// Enchant creature
@ -87,12 +87,13 @@ class WardOfPietyPreventDamageTargetEffect extends RedirectionEffect {
protected MageObjectReference redirectToObject;
public WardOfPietyPreventDamageTargetEffect() {
super(Duration.EndOfTurn, 1, true);
super(Duration.EndOfTurn, 1, UsageType.ONE_USAGE_ABSOLUTE);
staticText = "The next 1 damage that would be dealt to enchanted creature this turn is dealt to any target instead";
}
public WardOfPietyPreventDamageTargetEffect(final WardOfPietyPreventDamageTargetEffect effect) {
super(effect);
this.redirectToObject = effect.redirectToObject;
}
@Override

View file

@ -32,12 +32,13 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import static mage.abilities.effects.RedirectionEffect.UsageType.ONE_USAGE_ABSOLUTE;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.target.common.TargetControlledCreaturePermanent;
@ -48,7 +49,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class WarriorEnKor extends CardImpl {
public WarriorEnKor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{W}");
this.subtype.add(SubType.KOR);
this.subtype.add(SubType.WARRIOR);
this.subtype.add(SubType.KNIGHT);
@ -57,7 +58,7 @@ public class WarriorEnKor extends CardImpl {
// {0}: The next 1 damage that would be dealt to Warrior en-Kor this turn is dealt to target creature you control instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new GenericManaCost(0));
new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, ONE_USAGE_ABSOLUTE), new GenericManaCost(0));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}

View file

@ -32,6 +32,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import static mage.abilities.effects.RedirectionEffect.UsageType.ONE_USAGE_ABSOLUTE;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -48,13 +49,13 @@ import mage.target.common.TargetCreaturePermanent;
public class ZealousInquisitor extends CardImpl {
public ZealousInquisitor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN, SubType.CLERIC);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// {1}{W}: The next 1 damage that would be dealt to Zealous Inquisitor this turn is dealt to target creature instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new ManaCostsImpl("{1}{W}"));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, ONE_USAGE_ABSOLUTE), new ManaCostsImpl("{1}{W}"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}

View file

@ -32,6 +32,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import static mage.abilities.effects.RedirectionEffect.UsageType.ONE_USAGE_ABSOLUTE;
import mage.abilities.effects.common.RedirectDamageFromSourceToTargetEffect;
import mage.abilities.keyword.FlankingAbility;
import mage.cards.CardImpl;
@ -49,16 +50,16 @@ import mage.target.common.TargetAnyTarget;
public class ZhalfirinCrusader extends CardImpl {
public ZhalfirinCrusader(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{W}");
this.subtype.add(SubType.HUMAN, SubType.KNIGHT);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flanking
this.addAbility(new FlankingAbility());
// {1}{W}: The next 1 damage that would be dealt to Zhalfirin Crusader this turn is dealt to any target instead.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, true), new ManaCostsImpl("{1}{W}"));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new RedirectDamageFromSourceToTargetEffect(Duration.EndOfTurn, 1, ONE_USAGE_ABSOLUTE), new ManaCostsImpl("{1}{W}"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}

View file

@ -27,6 +27,7 @@
*/
package mage.abilities.effects;
import mage.MageObject;
import mage.abilities.Ability;
import mage.constants.Duration;
import mage.constants.EffectType;
@ -44,26 +45,34 @@ import mage.target.Target;
*/
public abstract class RedirectionEffect extends ReplacementEffectImpl {
protected Target redirectTarget;
protected int amountToRedirect;
protected boolean oneUsage;
public RedirectionEffect(Duration duration) {
this(duration, Integer.MAX_VALUE, false);
public enum UsageType {
ACCORDING_DURATION,
ONE_USAGE_ABSOLUTE,
ONE_USAGE_AT_THE_SAME_TIME; // all damage dealt at the same time
}
public RedirectionEffect(Duration duration, int amountToRedirect, boolean oneUsage) {
protected Target redirectTarget;
protected int amountToRedirect;
protected UsageType usageType;
protected int applyEffectsCounter;
public RedirectionEffect(Duration duration) {
this(duration, Integer.MAX_VALUE, UsageType.ACCORDING_DURATION);
applyEffectsCounter = -1;
}
public RedirectionEffect(Duration duration, int amountToRedirect, UsageType usageType) {
super(duration, Outcome.RedirectDamage);
this.effectType = EffectType.REDIRECTION;
this.amountToRedirect = amountToRedirect;
this.oneUsage = oneUsage;
this.usageType = usageType;
}
public RedirectionEffect(final RedirectionEffect effect) {
super(effect);
this.redirectTarget = effect.redirectTarget;
this.amountToRedirect = effect.amountToRedirect;
this.oneUsage = effect.oneUsage;
this.usageType = effect.usageType;
}
@Override
@ -79,26 +88,38 @@ public abstract class RedirectionEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
int damageToRedirect = event.getAmount();
if (damageToRedirect < 1) { // if multiple replacement effect apply, the rest damage can be 0, so the effect is not applied/replaced
return false;
}
String sourceLogName = source != null ? game.getObject(source.getSourceId()).getLogName() + ": " : "";
DamageEvent damageEvent = (DamageEvent) event;
int restDamage = 0;
int damageToRedirect = event.getAmount();
if (damageEvent.getAmount() > amountToRedirect) {
restDamage = damageEvent.getAmount() - amountToRedirect;
damageToRedirect = amountToRedirect;
}
if (damageToRedirect > 0 && oneUsage) {
this.discard();
if (damageToRedirect > 0 && usageType != UsageType.ACCORDING_DURATION) {
if (UsageType.ONE_USAGE_ABSOLUTE == usageType) {
this.discard();
}
if (applyEffectsCounter > 0) {
if (applyEffectsCounter < game.getState().getApplyEffectsCounter()) {
this.discard();
}
} else {
applyEffectsCounter = game.getState().getApplyEffectsCounter();
}
}
Permanent permanent = game.getPermanent(redirectTarget.getFirstTarget());
if (permanent != null) {
permanent.damage(damageToRedirect, event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage to " + permanent.getLogName());
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage" + getRedirectedFromText(event, game) + " to " + permanent.getLogName());
} else {
Player player = game.getPlayer(redirectTarget.getFirstTarget());
if (player != null) {
player.damage(damageToRedirect, event.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), event.getAppliedEffects());
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage to " + player.getLogName());
game.informPlayers(sourceLogName + "Redirected " + damageToRedirect + " damage" + getRedirectedFromText(event, game) + " to " + player.getLogName());
}
}
if (restDamage > 0) {
@ -108,4 +129,16 @@ public abstract class RedirectionEffect extends ReplacementEffectImpl {
return true;
}
private String getRedirectedFromText(GameEvent event, Game game) {
Player player = game.getPlayer(event.getTargetId());
if (player != null) {
return " from " + player.getLogName();
}
MageObject mageObject = game.getObject(event.getTargetId());
if (mageObject != null) {
return " from " + mageObject.getLogName();
}
return "";
}
}

View file

@ -18,8 +18,8 @@ import mage.game.permanent.Permanent;
*/
public class RedirectDamageFromSourceToTargetEffect extends RedirectionEffect {
public RedirectDamageFromSourceToTargetEffect(Duration duration, int amountToRedirect, boolean oneUsage) {
super(duration, amountToRedirect, oneUsage);
public RedirectDamageFromSourceToTargetEffect(Duration duration, int amountToRedirect, UsageType usageType) {
super(duration, amountToRedirect, usageType);
staticText = "The next " + amountToRedirect + " damage that would be dealt to {this} this turn is dealt to target creature you control instead.";
}

View file

@ -30,7 +30,6 @@ package mage.game;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import mage.MageObject;
import mage.abilities.*;
import mage.abilities.effects.ContinuousEffect;
@ -121,6 +120,8 @@ public class GameState implements Serializable, Copyable<GameState> {
private Map<UUID, Card> copiedCards = new HashMap<>();
private int permanentOrderNumber;
private int applyEffectsCounter; // Upcounting number of each applyEffects execution
public GameState() {
players = new Players();
playerList = new PlayerList();
@ -137,6 +138,7 @@ public class GameState implements Serializable, Copyable<GameState> {
combat = new Combat();
turnMods = new TurnMods();
watchers = new Watchers();
applyEffectsCounter = 0;
}
public GameState(final GameState state) {
@ -193,6 +195,7 @@ public class GameState implements Serializable, Copyable<GameState> {
this.zoneChangeCounter.putAll(state.zoneChangeCounter);
this.copiedCards.putAll(state.copiedCards);
this.permanentOrderNumber = state.permanentOrderNumber;
this.applyEffectsCounter = state.applyEffectsCounter;
}
public void restoreForRollBack(GameState state) {
@ -210,7 +213,7 @@ public class GameState implements Serializable, Copyable<GameState> {
this.command = state.command;
this.isPlaneChase = state.isPlaneChase;
this.seenPlanes = state.seenPlanes;
this.designations = state.designations;
this.designations = state.designations;
this.exile = state.exile;
this.battlefield = state.battlefield;
this.turnNum = state.turnNum;
@ -237,6 +240,7 @@ public class GameState implements Serializable, Copyable<GameState> {
this.zoneChangeCounter = state.zoneChangeCounter;
this.copiedCards = state.copiedCards;
this.permanentOrderNumber = state.permanentOrderNumber;
this.applyEffectsCounter = state.applyEffectsCounter;
}
@Override
@ -466,12 +470,12 @@ public class GameState implements Serializable, Copyable<GameState> {
}
}
return null;
}
}
public List<String> getSeenPlanes() {
return seenPlanes;
}
public boolean isPlaneChase() {
return isPlaneChase;
}
@ -574,6 +578,7 @@ public class GameState implements Serializable, Copyable<GameState> {
}
public void applyEffects(Game game) {
applyEffectsCounter++;
for (Player player : players.values()) {
player.reset();
}
@ -881,13 +886,13 @@ public class GameState implements Serializable, Copyable<GameState> {
addAbility(ability, designation.getId(), null);
}
}
public void addSeenPlane(Plane plane, Game game, UUID controllerId) {
if (plane != null) {
getSeenPlanes().add(plane.getName());
}
}
public void resetSeenPlanes() {
getSeenPlanes().clear();
}
@ -1169,4 +1174,9 @@ public class GameState implements Serializable, Copyable<GameState> {
public int getNextPermanentOrderNumber() {
return permanentOrderNumber++;
}
public int getApplyEffectsCounter() {
return applyEffectsCounter;
}
}