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