mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
TriggerChangesZone: add NewCard for leave the battlefield trigger
This commit is contained in:
committed by
Michael Kamensky
parent
7b18fc4474
commit
f0ed3f095d
@@ -127,6 +127,13 @@ public class GameAction {
|
||||
// get the LKI from above like ChangeZoneEffect
|
||||
if (params != null && params.containsKey(AbilityKey.CardLKI)) {
|
||||
lastKnownInfo = (Card) params.get(AbilityKey.CardLKI);
|
||||
} else if (toBattlefield && cause != null && cause.isReplacementAbility()) {
|
||||
// if to Battlefield and it is caused by an replacement effect,
|
||||
// try to get previous LKI if able
|
||||
ReplacementEffect re = cause.getReplacementEffect();
|
||||
if (ReplacementType.Moved.equals(re.getMode())) {
|
||||
lastKnownInfo = (Card) cause.getReplacingObject(AbilityKey.CardLKI);
|
||||
}
|
||||
}
|
||||
|
||||
if (c.isSplitCard()) {
|
||||
@@ -165,17 +172,6 @@ public class GameAction {
|
||||
if (suppress || (!fromBattlefield && !toHand)) {
|
||||
copied = c;
|
||||
|
||||
// if to Battlefield and it is caused by an replacement effect,
|
||||
// try to get previous LKI if able
|
||||
if (toBattlefield) {
|
||||
if (cause != null && cause.isReplacementAbility()) {
|
||||
ReplacementEffect re = cause.getReplacementEffect();
|
||||
if (ReplacementType.Moved.equals(re.getMode())) {
|
||||
lastKnownInfo = (Card) cause.getReplacingObject(AbilityKey.CardLKI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastKnownInfo == null) {
|
||||
lastKnownInfo = CardUtil.getLKICopy(c);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ public enum AbilityKey {
|
||||
LifeGained("LifeGained"),
|
||||
Mana("Mana"),
|
||||
MonstrosityAmount("MonstrosityAmount"),
|
||||
NewCard("NewCard"),
|
||||
NewCounterAmount("NewCounterAmount"),
|
||||
NoPreventDamage("NoPreventDamage"),
|
||||
Num("Num"), // TODO confirm that this and NumThisTurn can be merged
|
||||
@@ -94,6 +95,7 @@ public enum AbilityKey {
|
||||
Prevention("Prevention"),
|
||||
Produced("Produced"),
|
||||
Regeneration("Regeneration"),
|
||||
ReplacementEffect("ReplacementEffect"),
|
||||
ReplacementResult("ReplacementResult"),
|
||||
Result("Result"),
|
||||
Scheme("Scheme"),
|
||||
|
||||
@@ -1969,7 +1969,20 @@ public class AbilityUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SpellAbility getCause(SpellAbility sa) {
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
SpellAbility cause = sa;
|
||||
if (root.isReplacementAbility()) {
|
||||
SpellAbility replacingObject = (SpellAbility) root.getReplacingObject(AbilityKey.Cause);
|
||||
if (replacingObject != null) {
|
||||
cause = replacingObject;
|
||||
}
|
||||
}
|
||||
return cause;
|
||||
}
|
||||
|
||||
|
||||
public static SpellAbility addSpliceEffects(final SpellAbility sa) {
|
||||
final Card source = sa.getHostCard();
|
||||
final Player player = sa.getActivatingPlayer();
|
||||
|
||||
@@ -21,6 +21,8 @@ import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.player.PlayerCollection;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.replacement.ReplacementType;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
@@ -430,6 +432,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
final Game game = player.getGame();
|
||||
final CardCollection commandCards = new CardCollection();
|
||||
|
||||
SpellAbility cause = AbilityUtils.getCause(sa);
|
||||
|
||||
ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
||||
final List<ZoneType> origin = Lists.newArrayList();
|
||||
if (sa.hasParam("Origin")) {
|
||||
@@ -527,7 +531,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
movedCard = game.getAction().moveToLibrary(gameCard, libraryPosition, sa);
|
||||
movedCard = game.getAction().moveToLibrary(gameCard, libraryPosition, cause);
|
||||
|
||||
} else {
|
||||
if (destination.equals(ZoneType.Battlefield)) {
|
||||
@@ -585,10 +589,19 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
Map<AbilityKey, Object> moveParams = Maps.newEnumMap(AbilityKey.class);
|
||||
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.hasAdditionalAbility("AnimateSubAbility")) {
|
||||
// need LKI before Animate does apply
|
||||
moveParams.put(AbilityKey.CardLKI, CardUtil.getLKICopy(gameCard));
|
||||
if (!moveParams.containsKey(AbilityKey.CardLKI)) {
|
||||
moveParams.put(AbilityKey.CardLKI, CardUtil.getLKICopy(gameCard));
|
||||
}
|
||||
|
||||
hostCard.addRemembered(gameCard);
|
||||
AbilityUtils.resolve(sa.getAdditionalAbility("AnimateSubAbility"));
|
||||
@@ -610,7 +623,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
movedCard = game.getAction().moveTo(gameCard.getController().getZone(destination), gameCard, sa, moveParams);
|
||||
movedCard = game.getAction().moveTo(gameCard.getController().getZone(destination), gameCard, cause, moveParams);
|
||||
if (sa.hasParam("Unearth")) {
|
||||
movedCard.setUnearthed(true);
|
||||
movedCard.addChangedCardKeywords(Lists.newArrayList("Haste"), null, false, false,
|
||||
@@ -649,7 +662,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
gameCard.setExiledWith(host);
|
||||
}
|
||||
movedCard = game.getAction().moveTo(destination, gameCard, sa);
|
||||
movedCard = game.getAction().moveTo(destination, gameCard, cause);
|
||||
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.");
|
||||
@@ -782,6 +795,16 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
|
||||
SpellAbility cause = sa;
|
||||
if (root.isReplacementAbility()) {
|
||||
SpellAbility replacingObject = (SpellAbility) root.getReplacingObject(AbilityKey.Cause);
|
||||
if (replacingObject != null) {
|
||||
cause = replacingObject;
|
||||
}
|
||||
}
|
||||
|
||||
List<ZoneType> origin = Lists.newArrayList();
|
||||
if (sa.hasParam("Origin")) {
|
||||
origin = ZoneType.listValueOf(sa.getParam("Origin"));
|
||||
@@ -1049,7 +1072,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
Card movedCard = null;
|
||||
final Zone originZone = game.getZoneOf(c);
|
||||
if (destination.equals(ZoneType.Library)) {
|
||||
movedCard = game.getAction().moveToLibrary(c, libraryPos, sa);
|
||||
movedCard = game.getAction().moveToLibrary(c, libraryPos, cause);
|
||||
}
|
||||
else if (destination.equals(ZoneType.Battlefield)) {
|
||||
if (sa.hasParam("Tapped")) {
|
||||
@@ -1163,7 +1186,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
c.addFaceupCommand(unanimate);
|
||||
}
|
||||
}
|
||||
movedCard = game.getAction().moveTo(c.getController().getZone(destination), c, sa, moveParams);
|
||||
movedCard = game.getAction().moveTo(c.getController().getZone(destination), c, cause, moveParams);
|
||||
if (sa.hasParam("Tapped")) {
|
||||
movedCard.setTapped(true);
|
||||
}
|
||||
@@ -1188,7 +1211,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
else {
|
||||
movedCard = game.getAction().moveTo(destination, c, sa);
|
||||
movedCard = game.getAction().moveTo(destination, c, cause);
|
||||
}
|
||||
|
||||
movedCards.add(movedCard);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -12,6 +15,10 @@ import forge.game.spellability.SpellAbility;
|
||||
public class ETBReplacementEffect extends SpellAbilityEffect {
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
sa.getActivatingPlayer().getGame().getAction().moveToPlay(((Card) sa.getReplacingObject(AbilityKey.Card)), sa);
|
||||
final Card card = (Card) sa.getReplacingObject(AbilityKey.Card);
|
||||
Map<AbilityKey, Object> params = AbilityKey.newMap();
|
||||
params.put(AbilityKey.CardLKI, sa.getReplacingObject(AbilityKey.CardLKI));
|
||||
params.put(AbilityKey.ReplacementEffect, sa.getReplacementEffect());
|
||||
sa.getActivatingPlayer().getGame().getAction().moveToPlay(card, card.getController(), AbilityUtils.getCause(sa), params);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package forge.game.ability.effects;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.token.TokenInfo;
|
||||
|
||||
import forge.game.Game;
|
||||
@@ -56,7 +55,6 @@ public class TokenEffect extends TokenEffectBase {
|
||||
public void resolve(SpellAbility sa) {
|
||||
final Card host = sa.getHostCard();
|
||||
final Game game = host.getGame();
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
|
||||
// linked Abilities, if it needs chosen values, but nothing is chosen, no token can be created
|
||||
if (sa.hasParam("TokenTypes")) {
|
||||
@@ -72,13 +70,7 @@ public class TokenEffect extends TokenEffectBase {
|
||||
|
||||
// Cause of the Token Effect, in general it should be this
|
||||
// but if its a Replacement Effect, it might be something else or null
|
||||
SpellAbility cause = sa;
|
||||
if (root.isReplacementAbility()) {
|
||||
SpellAbility replacingObject = (SpellAbility) root.getReplacingObject(AbilityKey.Cause);
|
||||
if (replacingObject != null) {
|
||||
cause = replacingObject;
|
||||
}
|
||||
}
|
||||
SpellAbility cause = AbilityUtils.getCause(sa);
|
||||
|
||||
Card prototype = loadTokenPrototype(sa);
|
||||
|
||||
|
||||
@@ -188,11 +188,6 @@ public class TokenInfo {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<Card> makeTokenWithMultiplier(final Player controller, int amount, final boolean applyMultiplier) {
|
||||
return makeToken(makeOneToken(controller), controller, applyMultiplier, amount);
|
||||
}
|
||||
|
||||
static public List<Card> makeTokensFromPrototype(Card prototype, final Player owner, int amount, final boolean applyMultiplier) {
|
||||
return makeToken(prototype, owner, applyMultiplier, amount);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class CostPutCounter extends CostPartWithList {
|
||||
@Override
|
||||
protected Card doPayment(SpellAbility ability, Card targetCard){
|
||||
final Integer i = this.convertAmount();
|
||||
targetCard.addCounter(this.getCounter(), i, ability.getActivatingPlayer(), false, counterTable);
|
||||
targetCard.addCounter(this.getCounter(), i, ability.getActivatingPlayer(), ability.getRootAbility().isTrigger(), counterTable);
|
||||
return targetCard;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,13 +70,12 @@ public class ReplacementHandler {
|
||||
if (ReplacementType.Moved.equals(event) && ZoneType.Battlefield.equals(runParams.get(AbilityKey.Destination))) {
|
||||
// if it was caused by an replacement effect, use the already calculated RE list
|
||||
// otherwise the RIOT card would cause a StackError
|
||||
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||
if (cause != null && cause.isReplacementAbility()) {
|
||||
final ReplacementEffect re = cause.getReplacementEffect();
|
||||
final ReplacementEffect causeRE = (ReplacementEffect) runParams.get(AbilityKey.ReplacementEffect);
|
||||
if (causeRE != null) {
|
||||
// only return for same layer
|
||||
if (ReplacementType.Moved.equals(re.getMode()) && layer.equals(re.getLayer())) {
|
||||
if (!re.getOtherChoices().isEmpty())
|
||||
return re.getOtherChoices();
|
||||
if (ReplacementType.Moved.equals(causeRE.getMode()) && layer.equals(causeRE.getLayer())) {
|
||||
if (!causeRE.getOtherChoices().isEmpty())
|
||||
return causeRE.getOtherChoices();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public class TriggerChangesZone extends Trigger {
|
||||
}
|
||||
|
||||
if (hasParam("ValidCause")) {
|
||||
if (!runParams.containsKey(AbilityKey.Cause) ) {
|
||||
if (!runParams.containsKey(AbilityKey.Cause)) {
|
||||
return false;
|
||||
}
|
||||
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||
@@ -159,6 +159,15 @@ public class TriggerChangesZone extends Trigger {
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam("NotThisAbility")) {
|
||||
if (runParams.containsKey(AbilityKey.Cause)) {
|
||||
SpellAbility cause = (SpellAbility) runParams.get(AbilityKey.Cause);
|
||||
if (cause != null && this.equals(cause.getRootAbility().getTrigger())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this trigger can only be activated once per turn, verify it hasn't already run */
|
||||
if (hasParam("ActivationLimit")) {
|
||||
return this.getActivationsThisTurn() < Integer.parseInt(getParam("ActivationLimit"));
|
||||
@@ -170,8 +179,10 @@ public class TriggerChangesZone extends Trigger {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||
// TODO use better way to always copy both Card and CardLKI
|
||||
if ("Battlefield".equals(getParam("Origin"))) {
|
||||
sa.setTriggeringObject(AbilityKey.Card, runParams.get(AbilityKey.CardLKI));
|
||||
sa.setTriggeringObject(AbilityKey.NewCard, runParams.get(AbilityKey.Card));
|
||||
} else {
|
||||
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Card);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user