forked from External/mage
refactor: consistent logic for delayed triggers that sacrifice/exile tokens
single trigger for multiple tokens
This commit is contained in:
parent
457a5303f3
commit
f92af2b9cd
7 changed files with 50 additions and 72 deletions
|
|
@ -9,10 +9,7 @@ import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.abilities.keyword.HexproofAbility;
|
import mage.abilities.keyword.HexproofAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.*;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.SuperType;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.token.AngelToken;
|
import mage.game.permanent.token.AngelToken;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
@ -65,7 +62,7 @@ class GeistOfSaintTraftEffect extends OneShotEffect {
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
|
|
||||||
if (controller != null && effect.apply(game, source)) {
|
if (controller != null && effect.apply(game, source)) {
|
||||||
effect.exileTokensCreatedAtEndOfCombat(game, source);
|
effect.removeTokensCreatedAt(game, source, true, PhaseStep.END_COMBAT, TargetController.ANY);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,7 @@ import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||||
import mage.abilities.keyword.EnchantAbility;
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.AttachmentType;
|
import mage.constants.*;
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.Zone;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.token.AngelToken;
|
import mage.game.permanent.token.AngelToken;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
@ -72,7 +68,7 @@ class InvocationOfSaintTraftEffect extends OneShotEffect {
|
||||||
CreateTokenEffect effect = new CreateTokenEffect(new AngelToken(), 1, true, true);
|
CreateTokenEffect effect = new CreateTokenEffect(new AngelToken(), 1, true, true);
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null && (effect.apply(game, source))) {
|
if (controller != null && (effect.apply(game, source))) {
|
||||||
effect.exileTokensCreatedAtEndOfCombat(game, source);
|
effect.removeTokensCreatedAt(game, source, true, PhaseStep.END_COMBAT, TargetController.ANY);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@ import mage.abilities.keyword.FirstStrikeAbility;
|
||||||
import mage.abilities.keyword.MenaceAbility;
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.constants.CardType;
|
import mage.constants.*;
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.constants.Outcome;
|
|
||||||
import mage.constants.SuperType;
|
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.token.RagavanToken;
|
import mage.game.permanent.token.RagavanToken;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
@ -70,7 +67,7 @@ class KariZevSkyshipRaiderEffect extends OneShotEffect {
|
||||||
CreateTokenEffect effect = new CreateTokenEffect(new RagavanToken(), 1, true, true);
|
CreateTokenEffect effect = new CreateTokenEffect(new RagavanToken(), 1, true, true);
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (controller != null && effect.apply(game, source)) {
|
if (controller != null && effect.apply(game, source)) {
|
||||||
effect.exileTokensCreatedAtEndOfCombat(game, source);
|
effect.removeTokensCreatedAt(game, source, true, PhaseStep.END_COMBAT, TargetController.ANY);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class MiragePhalanxEffect extends OneShotEffect {
|
||||||
// Create the token(s)
|
// Create the token(s)
|
||||||
tokenCopyEffect.apply(game, source);
|
tokenCopyEffect.apply(game, source);
|
||||||
// Exile it at the end of combat
|
// Exile it at the end of combat
|
||||||
tokenCopyEffect.exileTokensCreatedAtEndOfCombat(game, source);
|
tokenCopyEffect.removeTokensCreatedAt(game, source, true, PhaseStep.END_COMBAT, TargetController.ANY);
|
||||||
|
|
||||||
return !tokenCopyEffect.getAddedPermanents().isEmpty();
|
return !tokenCopyEffect.getAddedPermanents().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -414,41 +414,29 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sacrificeTokensCreatedAtNextEndStep(Game game, Ability source) {
|
public void sacrificeTokensCreatedAtNextEndStep(Game game, Ability source) {
|
||||||
this.removeTokensCreatedAtEndOf(game, source, PhaseStep.END_TURN, false);
|
this.removeTokensCreatedAt(game, source, false, PhaseStep.END_TURN, TargetController.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exileTokensCreatedAtNextEndStep(Game game, Ability source) {
|
public void exileTokensCreatedAtNextEndStep(Game game, Ability source) {
|
||||||
this.removeTokensCreatedAtEndOf(game, source, PhaseStep.END_TURN, true);
|
this.removeTokensCreatedAt(game, source, true, PhaseStep.END_TURN, TargetController.ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sacrificeTokensCreatedAtEndOfCombat(Game game, Ability source) {
|
public void removeTokensCreatedAt(Game game, Ability source, boolean exile, PhaseStep phaseStep, TargetController targetController) {
|
||||||
this.removeTokensCreatedAtEndOf(game, source, PhaseStep.END_COMBAT, false);
|
Effect effect = exile
|
||||||
}
|
? new ExileTargetEffect(null, "", Zone.BATTLEFIELD).setText("exile the token copies")
|
||||||
|
: new SacrificeTargetEffect("sacrifice the token copies", source.getControllerId());
|
||||||
public void exileTokensCreatedAtEndOfCombat(Game game, Ability source) {
|
|
||||||
this.removeTokensCreatedAtEndOf(game, source, PhaseStep.END_COMBAT, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeTokensCreatedAtEndOf(Game game, Ability source, PhaseStep phaseStepToExileCards, boolean exile) {
|
|
||||||
Effect effect;
|
|
||||||
if (exile) {
|
|
||||||
effect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD).setText("exile the token copies");
|
|
||||||
} else {
|
|
||||||
effect = new SacrificeTargetEffect("sacrifice the token copies", source.getControllerId());
|
|
||||||
}
|
|
||||||
effect.setTargetPointer(new FixedTargets(new ArrayList<>(addedTokenPermanents), game));
|
effect.setTargetPointer(new FixedTargets(new ArrayList<>(addedTokenPermanents), game));
|
||||||
|
|
||||||
DelayedTriggeredAbility exileAbility;
|
DelayedTriggeredAbility exileAbility;
|
||||||
|
switch (phaseStep) {
|
||||||
switch (phaseStepToExileCards) {
|
|
||||||
case END_TURN:
|
case END_TURN:
|
||||||
exileAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect);
|
exileAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect, targetController);
|
||||||
break;
|
break;
|
||||||
case END_COMBAT:
|
case END_COMBAT:
|
||||||
exileAbility = new AtTheEndOfCombatDelayedTriggeredAbility(effect);
|
exileAbility = new AtTheEndOfCombatDelayedTriggeredAbility(effect);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
throw new UnsupportedOperationException("Unsupported PhaseStep in CreateTokenCopyTargetEffect::removeTokensCreatedAt");
|
||||||
}
|
}
|
||||||
|
|
||||||
game.addDelayedTriggeredAbility(exileAbility, source);
|
game.addDelayedTriggeredAbility(exileAbility, source);
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,26 @@
|
||||||
package mage.abilities.effects.common;
|
package mage.abilities.effects.common;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||||
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
|
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
|
||||||
import mage.abilities.dynamicvalue.DynamicValue;
|
import mage.abilities.dynamicvalue.DynamicValue;
|
||||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.TargetController;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.token.Token;
|
import mage.game.permanent.token.Token;
|
||||||
import mage.target.targetpointer.FixedTarget;
|
import mage.target.targetpointer.FixedTargets;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
import java.util.stream.Collectors;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
|
@ -121,37 +123,34 @@ public class CreateTokenEffect extends OneShotEffect {
|
||||||
return lastAddedTokenIds;
|
return lastAddedTokenIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sacrificeTokensCreatedAtNextEndStep(Game game, Ability source) {
|
|
||||||
for (UUID tokenId : this.getLastAddedTokenIds()) {
|
|
||||||
Permanent tokenPermanent = game.getPermanent(tokenId);
|
|
||||||
if (tokenPermanent != null) {
|
|
||||||
SacrificeTargetEffect sacrificeEffect = new SacrificeTargetEffect();
|
|
||||||
sacrificeEffect.setTargetPointer(new FixedTarget(tokenPermanent, game));
|
|
||||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(sacrificeEffect), source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void exileTokensCreatedAtNextEndStep(Game game, Ability source) {
|
public void exileTokensCreatedAtNextEndStep(Game game, Ability source) {
|
||||||
for (UUID tokenId : this.getLastAddedTokenIds()) {
|
removeTokensCreatedAt(game, source, true, PhaseStep.END_TURN, TargetController.ANY);
|
||||||
Permanent tokenPermanent = game.getPermanent(tokenId);
|
|
||||||
if (tokenPermanent != null) {
|
|
||||||
ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD);
|
|
||||||
exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game));
|
|
||||||
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(exileEffect), source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exileTokensCreatedAtEndOfCombat(Game game, Ability source) {
|
public void removeTokensCreatedAt(Game game, Ability source, boolean exile, PhaseStep phaseStep, TargetController targetController) {
|
||||||
for (UUID tokenId : this.getLastAddedTokenIds()) {
|
List<Permanent> permanents = this.getLastAddedTokenIds()
|
||||||
Permanent tokenPermanent = game.getPermanent(tokenId);
|
.stream()
|
||||||
if (tokenPermanent != null) {
|
.map(game::getPermanent)
|
||||||
ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD);
|
.filter(Objects::nonNull)
|
||||||
exileEffect.setTargetPointer(new FixedTarget(tokenPermanent, game));
|
.collect(Collectors.toList());
|
||||||
game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source);
|
Effect effect = exile
|
||||||
}
|
? new ExileTargetEffect(null, "", Zone.BATTLEFIELD).setText("exile those tokens")
|
||||||
|
: new SacrificeTargetEffect("sacrifice those tokens", source.getControllerId());
|
||||||
|
effect.setTargetPointer(new FixedTargets(permanents, game));
|
||||||
|
|
||||||
|
DelayedTriggeredAbility exileAbility;
|
||||||
|
switch (phaseStep) {
|
||||||
|
case END_TURN:
|
||||||
|
exileAbility = new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect, targetController);
|
||||||
|
break;
|
||||||
|
case END_COMBAT:
|
||||||
|
exileAbility = new AtTheEndOfCombatDelayedTriggeredAbility(effect);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unsupported PhaseStep in CreateTokenEffect::removeTokensCreatedAt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game.addDelayedTriggeredAbility(exileAbility, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import mage.abilities.dynamicvalue.common.StaticValue;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.CreateTokenEffect;
|
import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.TargetController;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.token.RedWarriorToken;
|
import mage.game.permanent.token.RedWarriorToken;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
@ -34,7 +36,6 @@ public class MobilizeAbility extends AttacksTriggeredAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String makeText(DynamicValue amount) {
|
private static String makeText(DynamicValue amount) {
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
String message;
|
String message;
|
||||||
String numToText;
|
String numToText;
|
||||||
boolean plural;
|
boolean plural;
|
||||||
|
|
@ -77,7 +78,7 @@ class MobilizeEffect extends OneShotEffect {
|
||||||
public boolean apply(Game game, Ability source) {
|
public boolean apply(Game game, Ability source) {
|
||||||
CreateTokenEffect effect = new CreateTokenEffect(new RedWarriorToken(), this.count, true, true);
|
CreateTokenEffect effect = new CreateTokenEffect(new RedWarriorToken(), this.count, true, true);
|
||||||
effect.apply(game, source);
|
effect.apply(game, source);
|
||||||
effect.sacrificeTokensCreatedAtNextEndStep(game, source);
|
effect.removeTokensCreatedAt(game, source, false, PhaseStep.END_TURN, TargetController.ANY);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue