diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java
index b60c5da858b..e68d8fb454a 100644
--- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java
+++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Maps;
import forge.card.CardStateName;
import forge.game.ability.effects.CharmEffect;
import forge.game.card.Card;
+import forge.game.card.CardState;
import forge.game.cost.Cost;
import forge.game.spellability.*;
import forge.game.zone.ZoneType;
@@ -97,7 +98,9 @@ public final class AbilityFactory {
}
}
-
+ public static final SpellAbility getAbility(final String abString, final Card card) {
+ return getAbility(abString, card.getCurrentState(), null);
+ }
/**
*
* getAbility.
@@ -109,51 +112,59 @@ public final class AbilityFactory {
* a {@link forge.game.card.Card} object.
* @return a {@link forge.game.spellability.SpellAbility} object.
*/
- public static final SpellAbility getAbility(final String abString, final Card hostCard) {
- return getAbility(abString, hostCard, null);
+ public static final SpellAbility getAbility(final String abString, final CardState state) {
+ return getAbility(abString, state, null);
}
- private static final SpellAbility getAbility(final String abString, final Card hostCard, final SpellAbility parent) {
+ private static final SpellAbility getAbility(final String abString, final CardState state, final SpellAbility parent) {
Map mapParams;
try {
mapParams = AbilityFactory.getMapParams(abString);
}
catch (RuntimeException ex) {
- throw new RuntimeException(hostCard.getName() + ": " + ex.getMessage());
+ throw new RuntimeException(state.getName() + ": " + ex.getMessage());
}
// parse universal parameters
AbilityRecordType type = AbilityRecordType.getRecordType(mapParams);
if (null == type) {
- String source = hostCard.getName().isEmpty() ? abString : hostCard.getName();
+ String source = state.getName().isEmpty() ? abString : state.getName();
throw new RuntimeException("AbilityFactory : getAbility -- no API in " + source + ": " + abString);
}
- return getAbility(mapParams, type, hostCard, parent);
+ return getAbility(mapParams, type, state, parent);
}
public static final SpellAbility getAbility(final Card hostCard, final String svar) {
- return getAbility(hostCard, svar, null);
+ return getAbility(hostCard.getCurrentState(), svar, null);
+ }
+
+ public static final SpellAbility getAbility(final CardState state, final String svar) {
+ return getAbility(state, svar, null);
}
- private static final SpellAbility getAbility(final Card hostCard, final String svar, final SpellAbility parent) {
- if (!hostCard.hasSVar(svar)) {
- String source = hostCard.getName();
+ private static final SpellAbility getAbility(final CardState state, final String svar, final SpellAbility parent) {
+ if (!state.hasSVar(svar)) {
+ String source = state.getCard().getName();
throw new RuntimeException("AbilityFactory : getAbility -- " + source + " has no SVar: " + svar);
} else {
- return getAbility(hostCard.getSVar(svar), hostCard, parent);
+ return getAbility(state.getSVar(svar), state, parent);
}
}
- public static final SpellAbility getAbility(final Map mapParams, AbilityRecordType type, final Card hostCard, final SpellAbility parent) {
- return getAbility(type, type.getApiTypeOf(mapParams), mapParams, parseAbilityCost(hostCard, mapParams, type), hostCard, parent);
+ public static final SpellAbility getAbility(final Map mapParams, AbilityRecordType type, final Card card, final SpellAbility parent) {
+ return getAbility(mapParams, type, card.getCurrentState(), parent);
+ }
+
+ public static final SpellAbility getAbility(final Map mapParams, AbilityRecordType type, final CardState state, final SpellAbility parent) {
+ return getAbility(type, type.getApiTypeOf(mapParams), mapParams, parseAbilityCost(state, mapParams, type), state, parent);
}
- public static Cost parseAbilityCost(final Card hostCard, Map mapParams, AbilityRecordType type) {
+ public static Cost parseAbilityCost(final CardState state, Map mapParams, AbilityRecordType type) {
Cost abCost = null;
if (type != AbilityRecordType.SubAbility) {
String cost = mapParams.get("Cost");
if (cost == null) {
- throw new RuntimeException("AbilityFactory : getAbility -- no Cost in " + hostCard.getName());
+ throw new RuntimeException("AbilityFactory : getAbility -- no Cost in " + state.getName());
}
abCost = new Cost(cost, type == AbilityRecordType.Ability);
}
@@ -161,7 +172,13 @@ public final class AbilityFactory {
}
public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map mapParams,
- Cost abCost,final Card hostCard, final SpellAbility parent) {
+ Cost abCost,final Card card, final SpellAbility parent) {
+ return getAbility(type, api, mapParams, abCost, card.getCurrentState(), parent);
+ }
+
+ public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map mapParams,
+ Cost abCost,final CardState state, final SpellAbility parent) {
+ final Card hostCard = state.getCard();
TargetRestrictions abTgt = mapParams.containsKey("ValidTgts") ? readTarget(mapParams) : null;
if (api == ApiType.CopySpellAbility || api == ApiType.Counter || api == ApiType.ChangeTargets || api == ApiType.ControlSpell) {
@@ -188,7 +205,7 @@ public final class AbilityFactory {
if (spellAbility == null) {
final StringBuilder msg = new StringBuilder();
msg.append("AbilityFactory : SpellAbility was not created for ");
- msg.append(hostCard.getName());
+ msg.append(state.getName());
msg.append(". Looking for API: ").append(api);
throw new RuntimeException(msg.toString());
}
@@ -203,16 +220,16 @@ public final class AbilityFactory {
if (mapParams.containsKey("References")) {
for (String svar : mapParams.get("References").split(",")) {
- spellAbility.setSVar(svar, hostCard.getSVar(svar));
+ spellAbility.setSVar(svar, state.getSVar(svar));
}
}
if (api == ApiType.DelayedTrigger && mapParams.containsKey("Execute")) {
- spellAbility.setSVar(mapParams.get("Execute"), hostCard.getSVar(mapParams.get("Execute")));
+ spellAbility.setSVar(mapParams.get("Execute"), state.getSVar(mapParams.get("Execute")));
}
if (mapParams.containsKey("PreventionSubAbility")) {
- spellAbility.setSVar(mapParams.get("PreventionSubAbility"), hostCard.getSVar(mapParams.get("PreventionSubAbility")));
+ spellAbility.setSVar(mapParams.get("PreventionSubAbility"), state.getSVar(mapParams.get("PreventionSubAbility")));
}
if (mapParams.containsKey("SubAbility")) {
@@ -227,7 +244,7 @@ public final class AbilityFactory {
p = p.getParent();
}
if (sub == null) {
- sub = getSubAbility(hostCard, name, spellAbility);
+ sub = getSubAbility(state, name, spellAbility);
}
spellAbility.setSubAbility(sub);
spellAbility.setAdditionalAbility(name, sub);
@@ -235,7 +252,7 @@ public final class AbilityFactory {
for (final String key : additionalAbilityKeys) {
if (mapParams.containsKey(key) && spellAbility.getAdditionalAbility(key) == null) {
- spellAbility.setAdditionalAbility(key, getSubAbility(hostCard, mapParams.get(key), spellAbility));
+ spellAbility.setAdditionalAbility(key, getSubAbility(state, mapParams.get(key), spellAbility));
}
}
@@ -247,7 +264,7 @@ public final class AbilityFactory {
spellAbility.setAdditionalAbilityList(key, Lists.transform(names, new Function() {
@Override
public AbilitySub apply(String input) {
- return getSubAbility(hostCard, input, sap);
+ return getSubAbility(state, input, sap);
}
}));
}
@@ -402,12 +419,12 @@ public final class AbilityFactory {
*
* @return a {@link forge.game.spellability.AbilitySub} object.
*/
- private static final AbilitySub getSubAbility(Card hostCard, String sSub, final SpellAbility parent) {
+ private static final AbilitySub getSubAbility(CardState state, String sSub, final SpellAbility parent) {
- if (hostCard.hasSVar(sSub)) {
- return (AbilitySub) AbilityFactory.getAbility(hostCard, sSub, parent);
+ if (state.hasSVar(sSub)) {
+ return (AbilitySub) AbilityFactory.getAbility(state, sSub, parent);
}
- System.out.println("SubAbility '"+ sSub +"' not found for: " + hostCard);
+ System.out.println("SubAbility '"+ sSub +"' not found for: " + state.getName());
return null;
}
@@ -434,7 +451,8 @@ public final class AbilityFactory {
if(!card.isSplitCard())
throw new IllegalStateException("Fuse ability may be built only on split cards");
- SpellAbility leftAbility = card.getState(CardStateName.LeftSplit).getFirstAbility();
+ CardState leftState = card.getState(CardStateName.LeftSplit);
+ SpellAbility leftAbility = leftState.getFirstAbility();
Map leftMap = Maps.newHashMap(leftAbility.getMapParams());
AbilityRecordType leftType = AbilityRecordType.getRecordType(leftMap);
ApiType leftApi = leftType.getApiTypeOf(leftMap);
@@ -442,7 +460,8 @@ public final class AbilityFactory {
leftMap.put("SpellDescription", "Fuse (you may cast both halves of this card from your hand).");
leftMap.put("ActivationZone", "Hand");
- SpellAbility rightAbility = card.getState(CardStateName.RightSplit).getFirstAbility();
+ CardState rightState = card.getState(CardStateName.RightSplit);
+ SpellAbility rightAbility = rightState.getFirstAbility();
Map rightMap = Maps.newHashMap(rightAbility.getMapParams());
AbilityRecordType rightType = AbilityRecordType.getRecordType(leftMap);
@@ -450,11 +469,11 @@ public final class AbilityFactory {
rightMap.put("StackDecription", rightMap.get("SpellDescription"));
rightMap.put("SpellDescription", "");
- Cost totalCost = parseAbilityCost(card, leftMap, leftType);
- totalCost.add(parseAbilityCost(card, rightMap, rightType));
+ Cost totalCost = parseAbilityCost(leftState, leftMap, leftType);
+ totalCost.add(parseAbilityCost(rightState, rightMap, rightType));
- final SpellAbility left = getAbility(leftType, leftApi, leftMap, totalCost, card, null);
- final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, card, left);
+ final SpellAbility left = getAbility(leftType, leftApi, leftMap, totalCost, leftState, null);
+ final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, rightState, left);
left.appendSubAbility(right);
return left;
}
diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java
index 6f7d736dbee..4409a097f49 100644
--- a/forge-game/src/main/java/forge/game/card/Card.java
+++ b/forge-game/src/main/java/forge/game/card/Card.java
@@ -1836,7 +1836,7 @@ public class Card extends GameEntity implements Comparable {
// Triggered abilities
for (final Trigger trig : state.getTriggers()) {
if (!trig.isSecondary()) {
- String trigStr = trig.replaceAbilityText(trig.toString(), null);
+ String trigStr = trig.replaceAbilityText(trig.toString(), null, state);
sb.append(trigStr.replaceAll("\\\\r\\\\n", "\r\n")).append("\r\n");
}
}
@@ -1950,7 +1950,7 @@ public class Card extends GameEntity implements Comparable {
// Triggered abilities
for (final Trigger trig : state.getTriggers()) {
if (!trig.isSecondary()) {
- sb.append(trig.replaceAbilityText(trig.toString(), null)).append("\r\n");
+ sb.append(trig.replaceAbilityText(trig.toString(), null, state)).append("\r\n");
}
}
diff --git a/forge-game/src/main/java/forge/game/trigger/Trigger.java b/forge-game/src/main/java/forge/game/trigger/Trigger.java
index 3beb859c279..cebf56f0b06 100644
--- a/forge-game/src/main/java/forge/game/trigger/Trigger.java
+++ b/forge-game/src/main/java/forge/game/trigger/Trigger.java
@@ -24,6 +24,7 @@ import forge.game.ability.AbilityFactory;
import forge.game.ability.ApiType;
import forge.game.ability.effects.CharmEffect;
import forge.game.card.Card;
+import forge.game.card.CardState;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
@@ -175,7 +176,7 @@ public abstract class Trigger extends TriggerReplacementBase {
}
}
- public final String replaceAbilityText(final String desc, SpellAbility sa) {
+ public final String replaceAbilityText(final String desc, SpellAbility sa, final CardState state) {
String result = desc;
// this function is for ABILITY
@@ -188,7 +189,11 @@ public abstract class Trigger extends TriggerReplacementBase {
sa = getOverridingAbility();
}
if (sa == null && this.mapParams.containsKey("Execute")) {
- sa = AbilityFactory.getAbility(hostCard, this.mapParams.get("Execute"));
+ if (state != null) {
+ sa = AbilityFactory.getAbility(state, this.mapParams.get("Execute"));
+ } else {
+ sa = AbilityFactory.getAbility(hostCard, this.mapParams.get("Execute"));
+ }
}
if (sa != null) {
String saDesc;
diff --git a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java
index c627cd62b8c..d4fa61fa421 100644
--- a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java
+++ b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java
@@ -217,7 +217,7 @@ public class WrappedAbility extends Ability {
@Override
public String getStackDescription() {
- final StringBuilder sb = new StringBuilder(regtrig.replaceAbilityText(regtrig.toString(true), this));
+ final StringBuilder sb = new StringBuilder(regtrig.replaceAbilityText(regtrig.toString(true), this, null));
if (usesTargeting()) {
sb.append(" (Targeting ");
for (final GameObject o : this.getTargets().getTargets()) {