mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
@@ -118,6 +118,7 @@ public enum AbilityKey {
|
||||
ScryBottom("ScryBottom"),
|
||||
ScryNum("ScryNum"),
|
||||
Sides("Sides"),
|
||||
SimultaneousETB("SimultaneousETB"),
|
||||
Source("Source"),
|
||||
Sources("Sources"),
|
||||
SourceSA("SourceSA"),
|
||||
|
||||
@@ -107,8 +107,6 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
cards = (CardCollection)AbilityUtils.filterListByType(cards, sa.getParam("ChangeType"), sa);
|
||||
|
||||
if (sa.hasParam("Optional")) {
|
||||
final String targets = Lang.joinHomogenous(cards);
|
||||
final String message;
|
||||
@@ -123,6 +121,12 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
cards = (CardCollection)AbilityUtils.filterListByType(cards, sa.getParam("ChangeType"), sa);
|
||||
|
||||
if (sa.hasParam("TypeLimit")) {
|
||||
cards = new CardCollection(Iterables.limit(cards, AbilityUtils.calculateAmount(source, sa.getParam("TypeLimit"), sa)));
|
||||
}
|
||||
|
||||
if (sa.hasParam("ForgetOtherRemembered")) {
|
||||
source.clearRemembered();
|
||||
}
|
||||
@@ -171,6 +175,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
|
||||
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
|
||||
|
||||
if (destination == ZoneType.Battlefield) {
|
||||
moveParams.put(AbilityKey.SimultaneousETB, cards);
|
||||
if (sa.hasAdditionalAbility("AnimateSubAbility")) {
|
||||
// need LKI before Animate does apply
|
||||
moveParams.put(AbilityKey.CardLKI, CardUtil.getLKICopy(c));
|
||||
|
||||
@@ -573,195 +573,194 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
movedCard = game.getAction().moveToLibrary(gameCard, libraryPosition, sa);
|
||||
} else {
|
||||
if (destination.equals(ZoneType.Battlefield)) {
|
||||
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
|
||||
moveParams.put(AbilityKey.LastStateBattlefield, lastStateBattlefield);
|
||||
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
|
||||
if (sa.isReplacementAbility()) {
|
||||
ReplacementEffect re = sa.getReplacementEffect();
|
||||
moveParams.put(AbilityKey.ReplacementEffect, re);
|
||||
if (ReplacementType.Moved.equals(re.getMode()) && sa.getReplacingObject(AbilityKey.CardLKI) != null) {
|
||||
moveParams.put(AbilityKey.CardLKI, sa.getReplacingObject(AbilityKey.CardLKI));
|
||||
}
|
||||
} else if (destination.equals(ZoneType.Battlefield)) {
|
||||
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
|
||||
moveParams.put(AbilityKey.LastStateBattlefield, lastStateBattlefield);
|
||||
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
|
||||
moveParams.put(AbilityKey.SimultaneousETB, tgtCards);
|
||||
if (sa.isReplacementAbility()) {
|
||||
ReplacementEffect re = sa.getReplacementEffect();
|
||||
moveParams.put(AbilityKey.ReplacementEffect, re);
|
||||
if (ReplacementType.Moved.equals(re.getMode()) && sa.getReplacingObject(AbilityKey.CardLKI) != null) {
|
||||
moveParams.put(AbilityKey.CardLKI, sa.getReplacingObject(AbilityKey.CardLKI));
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("Tapped") || sa.isNinjutsu()) {
|
||||
gameCard.setTapped(true);
|
||||
}
|
||||
if (sa.hasParam("Transformed")) {
|
||||
if (gameCard.isTransformable()) {
|
||||
// need LKI before Animate does apply
|
||||
if (!moveParams.containsKey(AbilityKey.CardLKI)) {
|
||||
moveParams.put(AbilityKey.CardLKI, CardUtil.getLKICopy(gameCard));
|
||||
}
|
||||
gameCard.changeCardState("Transform", null, sa);
|
||||
} else {
|
||||
// If it can't Transform, don't change zones.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("WithCountersType")) {
|
||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
||||
gameCard.addEtbCounter(cType, cAmount, player);
|
||||
}
|
||||
if (sa.hasParam("GainControl")) {
|
||||
final String g = sa.getParam("GainControl");
|
||||
Player newController = g.equals("True") ? player :
|
||||
AbilityUtils.getDefinedPlayers(hostCard, g, sa).get(0);
|
||||
if (newController != null) {
|
||||
if (newController != gameCard.getController()) {
|
||||
gameCard.runChangeControllerCommands();
|
||||
}
|
||||
gameCard.setController(newController, game.getNextTimestamp());
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("AttachedTo")) {
|
||||
CardCollection list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachedTo"), sa);
|
||||
if (list.isEmpty()) {
|
||||
list = CardLists.getValidCards(lastStateBattlefield, sa.getParam("AttachedTo"), hostCard.getController(), hostCard, sa);
|
||||
}
|
||||
|
||||
// only valid choices are when they could be attached
|
||||
// TODO for multiple Auras entering attached this way, need to use LKI info
|
||||
if (!list.isEmpty()) {
|
||||
list = CardLists.filter(list, CardPredicates.canBeAttached(gameCard, sa));
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("Attach", gameCard);
|
||||
Card attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", gameCard.toString()), params);
|
||||
|
||||
// TODO can't attach later or moveToPlay would attach indirectly
|
||||
// bypass canBeAttached to skip Protection checks when trying to attach multiple auras that would grant protection
|
||||
gameCard.attachToEntity(game.getCardState(attachedTo), sa, true);
|
||||
} else { // When it should enter the battlefield attached to an illegal permanent it fails
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("AttachedToPlayer")) {
|
||||
FCollectionView<Player> list = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("AttachedToPlayer"), sa);
|
||||
if (!list.isEmpty()) {
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("Attach", gameCard);
|
||||
Player attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectAPlayerAttachSourceTo", gameCard.toString()), params);
|
||||
gameCard.attachToEntity(attachedTo, sa);
|
||||
}
|
||||
else { // When it should enter the battlefield attached to an illegal player it fails
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasAdditionalAbility("AnimateSubAbility")) {
|
||||
if (sa.hasParam("Tapped") || sa.isNinjutsu()) {
|
||||
gameCard.setTapped(true);
|
||||
}
|
||||
if (sa.hasParam("Transformed")) {
|
||||
if (gameCard.isTransformable()) {
|
||||
// need LKI before Animate does apply
|
||||
if (!moveParams.containsKey(AbilityKey.CardLKI)) {
|
||||
moveParams.put(AbilityKey.CardLKI, CardUtil.getLKICopy(gameCard));
|
||||
}
|
||||
|
||||
final SpellAbility animate = sa.getAdditionalAbility("AnimateSubAbility");
|
||||
hostCard.addRemembered(gameCard);
|
||||
AbilityUtils.resolve(animate);
|
||||
hostCard.removeRemembered(gameCard);
|
||||
animate.setSVar("unanimateTimestamp", String.valueOf(game.getTimestamp()));
|
||||
}
|
||||
|
||||
// need to be facedown before it hits the battlefield in case of Replacement Effects or Trigger
|
||||
if (sa.hasParam("FaceDown")) {
|
||||
gameCard.turnFaceDown(true);
|
||||
CardFactoryUtil.setFaceDownState(gameCard, sa);
|
||||
}
|
||||
|
||||
movedCard = game.getAction().moveTo(gameCard.getController().getZone(destination), gameCard, sa, moveParams);
|
||||
// below stuff only if it changed zones
|
||||
if (movedCard.getZone().equals(originZone)) {
|
||||
gameCard.changeCardState("Transform", null, sa);
|
||||
} else {
|
||||
// If it can't Transform, don't change zones.
|
||||
continue;
|
||||
}
|
||||
if (sa.hasParam("Unearth") && movedCard.isInPlay()) {
|
||||
movedCard.setUnearthed(true);
|
||||
movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false,
|
||||
game.getNextTimestamp(), 0, true);
|
||||
registerDelayedTrigger(sa, "Exile", Lists.newArrayList(movedCard));
|
||||
addLeaveBattlefieldReplacement(movedCard, sa, "Exile");
|
||||
}
|
||||
if (sa.hasParam("LeaveBattlefield")) {
|
||||
addLeaveBattlefieldReplacement(movedCard, sa, sa.getParam("LeaveBattlefield"));
|
||||
}
|
||||
if (addToCombat(movedCard, movedCard.getController(), sa, "Attacking", "Blocking")) {
|
||||
combatChanged = true;
|
||||
}
|
||||
if (sa.isNinjutsu()) {
|
||||
// Ninjutsu need to get the Defender of the Returned Creature
|
||||
final Card returned = sa.getPaidList("Returned", true).getFirst();
|
||||
final GameEntity defender = game.getCombat().getDefenderByAttacker(returned);
|
||||
game.getCombat().addAttacker(movedCard, defender);
|
||||
game.getCombat().getBandOfAttacker(movedCard).setBlocked(false);
|
||||
combatChanged = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("AttachAfter") && movedCard.isAttachment()) {
|
||||
CardCollection list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachAfter"), sa);
|
||||
if (list.isEmpty()) {
|
||||
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AttachAfter"), hostCard.getController(), hostCard, sa);
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
String title = Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", CardTranslation.getTranslatedName(gameCard.getName()));
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("Attach", gameCard);
|
||||
Card attachedTo = chooser.getController().chooseSingleEntityForEffect(list, sa, title, params);
|
||||
movedCard.attachToEntity(attachedTo, sa);
|
||||
}
|
||||
if (sa.hasParam("WithCountersType")) {
|
||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
||||
gameCard.addEtbCounter(cType, cAmount, player);
|
||||
}
|
||||
if (sa.hasParam("GainControl")) {
|
||||
final String g = sa.getParam("GainControl");
|
||||
Player newController = g.equals("True") ? player :
|
||||
AbilityUtils.getDefinedPlayers(hostCard, g, sa).get(0);
|
||||
if (newController != null) {
|
||||
if (newController != gameCard.getController()) {
|
||||
gameCard.runChangeControllerCommands();
|
||||
}
|
||||
gameCard.setController(newController, game.getNextTimestamp());
|
||||
}
|
||||
} else {
|
||||
// might set before card is moved only for nontoken
|
||||
if (destination.equals(ZoneType.Exile)) {
|
||||
handleExiledWith(gameCard, sa);
|
||||
}
|
||||
if (sa.hasParam("AttachedTo")) {
|
||||
CardCollection list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachedTo"), sa);
|
||||
if (list.isEmpty()) {
|
||||
list = CardLists.getValidCards(lastStateBattlefield, sa.getParam("AttachedTo"), hostCard.getController(), hostCard, sa);
|
||||
}
|
||||
|
||||
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
|
||||
moveParams.put(AbilityKey.LastStateBattlefield, lastStateBattlefield);
|
||||
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
|
||||
movedCard = game.getAction().moveTo(destination, gameCard, sa, moveParams);
|
||||
// only valid choices are when they could be attached
|
||||
// TODO for multiple Auras entering attached this way, need to use LKI info
|
||||
if (!list.isEmpty()) {
|
||||
list = CardLists.filter(list, CardPredicates.canBeAttached(gameCard, sa));
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("Attach", gameCard);
|
||||
Card attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", gameCard.toString()), params);
|
||||
|
||||
if (ZoneType.Hand.equals(destination) && ZoneType.Command.equals(originZone.getZoneType())) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(movedCard.getName()).append(" has moved from Command Zone to ").append(player).append("'s hand.");
|
||||
game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
|
||||
commandCards.add(movedCard); //add to list to reveal the commandzone cards
|
||||
// TODO can't attach later or moveToPlay would attach indirectly
|
||||
// bypass canBeAttached to skip Protection checks when trying to attach multiple auras that would grant protection
|
||||
gameCard.attachToEntity(game.getCardState(attachedTo), sa, true);
|
||||
} else { // When it should enter the battlefield attached to an illegal permanent it fails
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("AttachedToPlayer")) {
|
||||
FCollectionView<Player> list = AbilityUtils.getDefinedPlayers(hostCard, sa.getParam("AttachedToPlayer"), sa);
|
||||
if (!list.isEmpty()) {
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("Attach", gameCard);
|
||||
Player attachedTo = player.getController().chooseSingleEntityForEffect(list, sa, Localizer.getInstance().getMessage("lblSelectAPlayerAttachSourceTo", gameCard.toString()), params);
|
||||
gameCard.attachToEntity(attachedTo, sa);
|
||||
}
|
||||
else { // When it should enter the battlefield attached to an illegal player it fails
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasAdditionalAbility("AnimateSubAbility")) {
|
||||
// need LKI before Animate does apply
|
||||
if (!moveParams.containsKey(AbilityKey.CardLKI)) {
|
||||
moveParams.put(AbilityKey.CardLKI, CardUtil.getLKICopy(gameCard));
|
||||
}
|
||||
|
||||
// If a card is Exiled from the stack, remove its spells from the stack
|
||||
if (sa.hasParam("Fizzle")) {
|
||||
if (gameCard.isInZone(ZoneType.Exile) || gameCard.isInZone(ZoneType.Hand)
|
||||
|| gameCard.isInZone(ZoneType.Stack) || gameCard.isInZone(ZoneType.Command)) {
|
||||
// This only fizzles spells, not anything else.
|
||||
game.getStack().remove(gameCard);
|
||||
}
|
||||
}
|
||||
final SpellAbility animate = sa.getAdditionalAbility("AnimateSubAbility");
|
||||
hostCard.addRemembered(gameCard);
|
||||
AbilityUtils.resolve(animate);
|
||||
hostCard.removeRemembered(gameCard);
|
||||
animate.setSVar("unanimateTimestamp", String.valueOf(game.getTimestamp()));
|
||||
}
|
||||
|
||||
if (sa.hasParam("WithCountersType")) {
|
||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
||||
movedCard.addCounter(cType, cAmount, player, counterTable);
|
||||
}
|
||||
// need to be facedown before it hits the battlefield in case of Replacement Effects or Trigger
|
||||
if (sa.hasParam("FaceDown")) {
|
||||
gameCard.turnFaceDown(true);
|
||||
CardFactoryUtil.setFaceDownState(gameCard, sa);
|
||||
}
|
||||
|
||||
if (sa.hasParam("ExileFaceDown") || sa.hasParam("FaceDown")) {
|
||||
movedCard.turnFaceDown(true);
|
||||
}
|
||||
if (sa.hasParam("Foretold")) {
|
||||
movedCard.setForetold(true);
|
||||
movedCard.setForetoldThisTurn(true);
|
||||
if (sa.hasParam("ForetoldCost")) {
|
||||
movedCard.setForetoldCostByEffect(true);
|
||||
}
|
||||
// look at the exiled card
|
||||
movedCard.addMayLookTemp(player);
|
||||
}
|
||||
movedCard = game.getAction().moveTo(gameCard.getController().getZone(destination), gameCard, sa, moveParams);
|
||||
// below stuff only if it changed zones
|
||||
if (movedCard.getZone().equals(originZone)) {
|
||||
continue;
|
||||
}
|
||||
if (sa.hasParam("Unearth") && movedCard.isInPlay()) {
|
||||
movedCard.setUnearthed(true);
|
||||
movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false,
|
||||
game.getNextTimestamp(), 0, true);
|
||||
registerDelayedTrigger(sa, "Exile", Lists.newArrayList(movedCard));
|
||||
addLeaveBattlefieldReplacement(movedCard, sa, "Exile");
|
||||
}
|
||||
if (sa.hasParam("LeaveBattlefield")) {
|
||||
addLeaveBattlefieldReplacement(movedCard, sa, sa.getParam("LeaveBattlefield"));
|
||||
}
|
||||
if (addToCombat(movedCard, movedCard.getController(), sa, "Attacking", "Blocking")) {
|
||||
combatChanged = true;
|
||||
}
|
||||
if (sa.isNinjutsu()) {
|
||||
// Ninjutsu need to get the Defender of the Returned Creature
|
||||
final Card returned = sa.getPaidList("Returned", true).getFirst();
|
||||
final GameEntity defender = game.getCombat().getDefenderByAttacker(returned);
|
||||
game.getCombat().addAttacker(movedCard, defender);
|
||||
game.getCombat().getBandOfAttacker(movedCard).setBlocked(false);
|
||||
combatChanged = true;
|
||||
}
|
||||
|
||||
if (sa.hasParam("TrackDiscarded")) {
|
||||
movedCard.setDiscarded(true);
|
||||
if (sa.hasParam("AttachAfter") && movedCard.isAttachment()) {
|
||||
CardCollection list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("AttachAfter"), sa);
|
||||
if (list.isEmpty()) {
|
||||
list = CardLists.getValidCards(game.getCardsIn(ZoneType.Battlefield), sa.getParam("AttachAfter"), hostCard.getController(), hostCard, sa);
|
||||
}
|
||||
if (!list.isEmpty()) {
|
||||
String title = Localizer.getInstance().getMessage("lblSelectACardAttachSourceTo", CardTranslation.getTranslatedName(gameCard.getName()));
|
||||
Map<String, Object> params = Maps.newHashMap();
|
||||
params.put("Attach", gameCard);
|
||||
Card attachedTo = chooser.getController().chooseSingleEntityForEffect(list, sa, title, params);
|
||||
movedCard.attachToEntity(attachedTo, sa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// might set before card is moved only for nontoken
|
||||
if (destination.equals(ZoneType.Exile)) {
|
||||
handleExiledWith(gameCard, sa);
|
||||
}
|
||||
|
||||
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
|
||||
moveParams.put(AbilityKey.LastStateBattlefield, lastStateBattlefield);
|
||||
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
|
||||
movedCard = game.getAction().moveTo(destination, gameCard, sa, moveParams);
|
||||
|
||||
if (ZoneType.Hand.equals(destination) && ZoneType.Command.equals(originZone.getZoneType())) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(movedCard.getName()).append(" has moved from Command Zone to ").append(player).append("'s hand.");
|
||||
game.getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
|
||||
commandCards.add(movedCard); //add to list to reveal the commandzone cards
|
||||
}
|
||||
|
||||
// If a card is Exiled from the stack, remove its spells from the stack
|
||||
if (sa.hasParam("Fizzle")) {
|
||||
if (gameCard.isInZone(ZoneType.Exile) || gameCard.isInZone(ZoneType.Hand)
|
||||
|| gameCard.isInZone(ZoneType.Stack) || gameCard.isInZone(ZoneType.Command)) {
|
||||
// This only fizzles spells, not anything else.
|
||||
game.getStack().remove(gameCard);
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("WithCountersType")) {
|
||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
||||
movedCard.addCounter(cType, cAmount, player, counterTable);
|
||||
}
|
||||
|
||||
if (sa.hasParam("ExileFaceDown") || sa.hasParam("FaceDown")) {
|
||||
movedCard.turnFaceDown(true);
|
||||
}
|
||||
if (sa.hasParam("Foretold")) {
|
||||
movedCard.setForetold(true);
|
||||
movedCard.setForetoldThisTurn(true);
|
||||
if (sa.hasParam("ForetoldCost")) {
|
||||
movedCard.setForetoldCostByEffect(true);
|
||||
}
|
||||
// look at the exiled card
|
||||
movedCard.addMayLookTemp(player);
|
||||
}
|
||||
|
||||
if (sa.hasParam("TrackDiscarded")) {
|
||||
movedCard.setDiscarded(true);
|
||||
}
|
||||
}
|
||||
if (!movedCard.getZone().equals(originZone)) {
|
||||
@@ -1305,6 +1304,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
movedCard = game.getAction().moveToLibrary(c, libraryPos, sa, moveParams);
|
||||
}
|
||||
else if (destination.equals(ZoneType.Battlefield)) {
|
||||
moveParams.put(AbilityKey.SimultaneousETB, chosenCards);
|
||||
if (sa.hasParam("Tapped")) {
|
||||
c.setTapped(true);
|
||||
}
|
||||
|
||||
@@ -398,10 +398,13 @@ public class DigEffect extends SpellAbilityEffect {
|
||||
if (sa.hasParam("Tapped")) {
|
||||
c.setTapped(true);
|
||||
}
|
||||
if (destZone1.equals(ZoneType.Battlefield) && sa.hasParam("WithCounter")) {
|
||||
final int numCtr = AbilityUtils.calculateAmount(host,
|
||||
sa.getParamOrDefault("WithCounterNum", "1"), sa);
|
||||
c.addEtbCounter(CounterType.getType(sa.getParam("WithCounter")), numCtr, player);
|
||||
if (destZone1.equals(ZoneType.Battlefield)) {
|
||||
moveParams.put(AbilityKey.SimultaneousETB, movedCards);
|
||||
if (sa.hasParam("WithCounter")) {
|
||||
final int numCtr = AbilityUtils.calculateAmount(host,
|
||||
sa.getParamOrDefault("WithCounterNum", "1"), sa);
|
||||
c.addEtbCounter(CounterType.getType(sa.getParam("WithCounter")), numCtr, player);
|
||||
}
|
||||
}
|
||||
if (sa.hasAdditionalAbility("AnimateSubAbility")) {
|
||||
// need LKI before Animate does apply
|
||||
@@ -477,8 +480,7 @@ public class DigEffect extends SpellAbilityEffect {
|
||||
}
|
||||
} else {
|
||||
// just move them randomly
|
||||
for (int i = 0; i < rest.size(); i++) {
|
||||
Card c = rest.get(i);
|
||||
for (Card c : rest) {
|
||||
final ZoneType origin = c.getZone().getZoneType();
|
||||
final PlayerZone toZone = c.getOwner().getZone(destZone2);
|
||||
c = game.getAction().moveTo(toZone, c, sa);
|
||||
|
||||
@@ -99,11 +99,6 @@ public class DigUntilEffect extends SpellAbilityEffect {
|
||||
final Card host = sa.getHostCard();
|
||||
final Game game = host.getGame();
|
||||
|
||||
String[] type = new String[]{"Card"};
|
||||
if (sa.hasParam("Valid")) {
|
||||
type = sa.getParam("Valid").split(",");
|
||||
}
|
||||
|
||||
int untilAmount = 1;
|
||||
if (sa.hasParam("Amount")) {
|
||||
untilAmount = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa);
|
||||
@@ -115,6 +110,11 @@ public class DigUntilEffect extends SpellAbilityEffect {
|
||||
maxRevealed = AbilityUtils.calculateAmount(host, sa.getParam("MaxRevealed"), sa);
|
||||
}
|
||||
|
||||
String[] type = new String[]{"Card"};
|
||||
if (sa.hasParam("Valid")) {
|
||||
type = sa.getParam("Valid").split(",");
|
||||
}
|
||||
|
||||
final boolean remember = sa.hasParam("RememberFound");
|
||||
final boolean imprint = sa.hasParam("ImprintFound");
|
||||
|
||||
@@ -210,6 +210,7 @@ public class DigUntilEffect extends SpellAbilityEffect {
|
||||
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
|
||||
Card m = null;
|
||||
if (foundDest.equals(ZoneType.Battlefield)) {
|
||||
moveParams.put(AbilityKey.SimultaneousETB, new CardCollection(c));
|
||||
if (sa.hasParam("GainControl")) {
|
||||
c.setController(sa.getActivatingPlayer(), game.getNextTimestamp());
|
||||
}
|
||||
|
||||
@@ -312,6 +312,7 @@ public class ReplacementHandler {
|
||||
replacementEffect.setReplacingObjects(runParams, tailend);
|
||||
//set original Params to update them later
|
||||
tailend.setReplacingObject(AbilityKey.OriginalParams, runParams);
|
||||
tailend.setReplacingObjectsFrom(runParams, AbilityKey.SimultaneousETB);
|
||||
tailend = tailend.getSubAbility();
|
||||
} while(tailend != null);
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ ManaCost:3 B B
|
||||
Types:Legendary Planeswalker Ashiok
|
||||
Loyalty:5
|
||||
R:Event$ PayLife | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ ExileTop | Amount$ LEY | Description$ If you would pay life while your library has at least that many cards in it, exile that many cards from the top of your library instead.
|
||||
SVar:ExileTop:DB$ Dig | DigNum$ X | ChangeNum$ All | DestinationZone$ Exile
|
||||
SVar:ExileTop:DB$ ChangeZoneAll | TypeLimit$ X | ChangeType$ Card.NotDefinedReplacedSimultaneousETB | Defined$ You | Origin$ Library | Destination$ Exile
|
||||
SVar:X:ReplaceCount$Amount
|
||||
SVar:Y:Count$ValidLibrary Card
|
||||
SVar:Y:Count$ValidLibrary Card.YouOwn
|
||||
A:AB$ Dig | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | DigNum$ 2 | ChangeNum$ 1 | DestinationZone2$ Exile | NoReveal$ True | SpellDescription$ Look at the top two cards of your library. Exile one of them and put the other into your hand.
|
||||
A:AB$ Token | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | TokenAmount$ 2 | TokenScript$ b_1_1_nightmare_exile_counter | TokenOwner$ You | SpellDescription$ Create two 1/1 black Nightmare creature tokens with "At the beginning of combat on your turn, if a card was put into exile this turn, put a +1/+1 counter on this creature."
|
||||
A:AB$ Discard | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Player | NumCards$ Z | Mode$ TgtChoose | SpellDescription$ Target player exiles the top X cards of their library, where X is the total mana value of cards you own in exile.
|
||||
A:AB$ Dig | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Player | DigNum$ Z | ChangeNum$ All | DestinationZone$ Exile | SpellDescription$ Target player exiles the top X cards of their library, where X is the total mana value of cards you own in exile.
|
||||
SVar:Z:Count$ValidExile Card.YouOwn$SumCMC
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:If you would pay life while your library has at least that many cards in it, exile that many cards from the top of your library instead.\n+1: Look at the top two cards of your library. Exile one of them and put the other into your hand.\n−2: Create two 1/1 black Nightmare creature tokens with "At the beginning of combat on your turn, if a card was put into exile this turn, put a +1/+1 counter on this creature."\n−7: Target player exiles the top X cards of their library, where X is the total mana value of cards you own in exile.
|
||||
|
||||
Reference in New Issue
Block a user