AbilityFactory: use CardState instead of Card for the Svar params and the Names

This commit is contained in:
Hanmac
2017-11-13 05:20:04 +00:00
parent 73e0a4d35a
commit ac12412ec3
4 changed files with 63 additions and 39 deletions

View File

@@ -23,6 +23,7 @@ import com.google.common.collect.Maps;
import forge.card.CardStateName; import forge.card.CardStateName;
import forge.game.ability.effects.CharmEffect; import forge.game.ability.effects.CharmEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardState;
import forge.game.cost.Cost; import forge.game.cost.Cost;
import forge.game.spellability.*; import forge.game.spellability.*;
import forge.game.zone.ZoneType; 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);
}
/** /**
* <p> * <p>
* getAbility. * getAbility.
@@ -109,51 +112,59 @@ public final class AbilityFactory {
* a {@link forge.game.card.Card} object. * a {@link forge.game.card.Card} object.
* @return a {@link forge.game.spellability.SpellAbility} object. * @return a {@link forge.game.spellability.SpellAbility} object.
*/ */
public static final SpellAbility getAbility(final String abString, final Card hostCard) { public static final SpellAbility getAbility(final String abString, final CardState state) {
return getAbility(abString, hostCard, null); 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<String, String> mapParams; Map<String, String> mapParams;
try { try {
mapParams = AbilityFactory.getMapParams(abString); mapParams = AbilityFactory.getMapParams(abString);
} }
catch (RuntimeException ex) { catch (RuntimeException ex) {
throw new RuntimeException(hostCard.getName() + ": " + ex.getMessage()); throw new RuntimeException(state.getName() + ": " + ex.getMessage());
} }
// parse universal parameters // parse universal parameters
AbilityRecordType type = AbilityRecordType.getRecordType(mapParams); AbilityRecordType type = AbilityRecordType.getRecordType(mapParams);
if (null == type) { 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); 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) { public static final SpellAbility getAbility(final Card hostCard, final String svar) {
return getAbility(hostCard, svar, null); return getAbility(hostCard.getCurrentState(), svar, null);
} }
private static final SpellAbility getAbility(final Card hostCard, final String svar, final SpellAbility parent) { public static final SpellAbility getAbility(final CardState state, final String svar) {
if (!hostCard.hasSVar(svar)) { return getAbility(state, svar, null);
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); throw new RuntimeException("AbilityFactory : getAbility -- " + source + " has no SVar: " + svar);
} else { } else {
return getAbility(hostCard.getSVar(svar), hostCard, parent); return getAbility(state.getSVar(svar), state, parent);
} }
} }
public static final SpellAbility getAbility(final Map<String, String> mapParams, AbilityRecordType type, final Card hostCard, final SpellAbility parent) { public static final SpellAbility getAbility(final Map<String, String> mapParams, AbilityRecordType type, final Card card, final SpellAbility parent) {
return getAbility(type, type.getApiTypeOf(mapParams), mapParams, parseAbilityCost(hostCard, mapParams, type), hostCard, parent); return getAbility(mapParams, type, card.getCurrentState(), parent);
}
public static final SpellAbility getAbility(final Map<String, String> 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<String, String> mapParams, AbilityRecordType type) { public static Cost parseAbilityCost(final CardState state, Map<String, String> mapParams, AbilityRecordType type) {
Cost abCost = null; Cost abCost = null;
if (type != AbilityRecordType.SubAbility) { if (type != AbilityRecordType.SubAbility) {
String cost = mapParams.get("Cost"); String cost = mapParams.get("Cost");
if (cost == null) { 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); 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<String, String> mapParams, public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map<String, String> 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<String, String> mapParams,
Cost abCost,final CardState state, final SpellAbility parent) {
final Card hostCard = state.getCard();
TargetRestrictions abTgt = mapParams.containsKey("ValidTgts") ? readTarget(mapParams) : null; TargetRestrictions abTgt = mapParams.containsKey("ValidTgts") ? readTarget(mapParams) : null;
if (api == ApiType.CopySpellAbility || api == ApiType.Counter || api == ApiType.ChangeTargets || api == ApiType.ControlSpell) { if (api == ApiType.CopySpellAbility || api == ApiType.Counter || api == ApiType.ChangeTargets || api == ApiType.ControlSpell) {
@@ -188,7 +205,7 @@ public final class AbilityFactory {
if (spellAbility == null) { if (spellAbility == null) {
final StringBuilder msg = new StringBuilder(); final StringBuilder msg = new StringBuilder();
msg.append("AbilityFactory : SpellAbility was not created for "); msg.append("AbilityFactory : SpellAbility was not created for ");
msg.append(hostCard.getName()); msg.append(state.getName());
msg.append(". Looking for API: ").append(api); msg.append(". Looking for API: ").append(api);
throw new RuntimeException(msg.toString()); throw new RuntimeException(msg.toString());
} }
@@ -203,16 +220,16 @@ public final class AbilityFactory {
if (mapParams.containsKey("References")) { if (mapParams.containsKey("References")) {
for (String svar : mapParams.get("References").split(",")) { 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")) { 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")) { 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")) { if (mapParams.containsKey("SubAbility")) {
@@ -227,7 +244,7 @@ public final class AbilityFactory {
p = p.getParent(); p = p.getParent();
} }
if (sub == null) { if (sub == null) {
sub = getSubAbility(hostCard, name, spellAbility); sub = getSubAbility(state, name, spellAbility);
} }
spellAbility.setSubAbility(sub); spellAbility.setSubAbility(sub);
spellAbility.setAdditionalAbility(name, sub); spellAbility.setAdditionalAbility(name, sub);
@@ -235,7 +252,7 @@ public final class AbilityFactory {
for (final String key : additionalAbilityKeys) { for (final String key : additionalAbilityKeys) {
if (mapParams.containsKey(key) && spellAbility.getAdditionalAbility(key) == null) { 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<String, AbilitySub>() { spellAbility.setAdditionalAbilityList(key, Lists.transform(names, new Function<String, AbilitySub>() {
@Override @Override
public AbilitySub apply(String input) { 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. * @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)) { if (state.hasSVar(sSub)) {
return (AbilitySub) AbilityFactory.getAbility(hostCard, sSub, parent); 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; return null;
} }
@@ -434,7 +451,8 @@ public final class AbilityFactory {
if(!card.isSplitCard()) if(!card.isSplitCard())
throw new IllegalStateException("Fuse ability may be built only on split cards"); 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<String, String> leftMap = Maps.newHashMap(leftAbility.getMapParams()); Map<String, String> leftMap = Maps.newHashMap(leftAbility.getMapParams());
AbilityRecordType leftType = AbilityRecordType.getRecordType(leftMap); AbilityRecordType leftType = AbilityRecordType.getRecordType(leftMap);
ApiType leftApi = leftType.getApiTypeOf(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("SpellDescription", "Fuse (you may cast both halves of this card from your hand).");
leftMap.put("ActivationZone", "Hand"); leftMap.put("ActivationZone", "Hand");
SpellAbility rightAbility = card.getState(CardStateName.RightSplit).getFirstAbility(); CardState rightState = card.getState(CardStateName.RightSplit);
SpellAbility rightAbility = rightState.getFirstAbility();
Map<String, String> rightMap = Maps.newHashMap(rightAbility.getMapParams()); Map<String, String> rightMap = Maps.newHashMap(rightAbility.getMapParams());
AbilityRecordType rightType = AbilityRecordType.getRecordType(leftMap); AbilityRecordType rightType = AbilityRecordType.getRecordType(leftMap);
@@ -450,11 +469,11 @@ public final class AbilityFactory {
rightMap.put("StackDecription", rightMap.get("SpellDescription")); rightMap.put("StackDecription", rightMap.get("SpellDescription"));
rightMap.put("SpellDescription", ""); rightMap.put("SpellDescription", "");
Cost totalCost = parseAbilityCost(card, leftMap, leftType); Cost totalCost = parseAbilityCost(leftState, leftMap, leftType);
totalCost.add(parseAbilityCost(card, rightMap, rightType)); totalCost.add(parseAbilityCost(rightState, rightMap, rightType));
final SpellAbility left = getAbility(leftType, leftApi, leftMap, totalCost, card, null); final SpellAbility left = getAbility(leftType, leftApi, leftMap, totalCost, leftState, null);
final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, card, left); final AbilitySub right = (AbilitySub) getAbility(AbilityRecordType.SubAbility, rightApi, rightMap, null, rightState, left);
left.appendSubAbility(right); left.appendSubAbility(right);
return left; return left;
} }

View File

@@ -1836,7 +1836,7 @@ public class Card extends GameEntity implements Comparable<Card> {
// Triggered abilities // Triggered abilities
for (final Trigger trig : state.getTriggers()) { for (final Trigger trig : state.getTriggers()) {
if (!trig.isSecondary()) { 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"); sb.append(trigStr.replaceAll("\\\\r\\\\n", "\r\n")).append("\r\n");
} }
} }
@@ -1950,7 +1950,7 @@ public class Card extends GameEntity implements Comparable<Card> {
// Triggered abilities // Triggered abilities
for (final Trigger trig : state.getTriggers()) { for (final Trigger trig : state.getTriggers()) {
if (!trig.isSecondary()) { if (!trig.isSecondary()) {
sb.append(trig.replaceAbilityText(trig.toString(), null)).append("\r\n"); sb.append(trig.replaceAbilityText(trig.toString(), null, state)).append("\r\n");
} }
} }

View File

@@ -24,6 +24,7 @@ import forge.game.ability.AbilityFactory;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
import forge.game.ability.effects.CharmEffect; import forge.game.ability.effects.CharmEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardState;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; 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; String result = desc;
// this function is for ABILITY // this function is for ABILITY
@@ -188,7 +189,11 @@ public abstract class Trigger extends TriggerReplacementBase {
sa = getOverridingAbility(); sa = getOverridingAbility();
} }
if (sa == null && this.mapParams.containsKey("Execute")) { 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) { if (sa != null) {
String saDesc; String saDesc;

View File

@@ -217,7 +217,7 @@ public class WrappedAbility extends Ability {
@Override @Override
public String getStackDescription() { 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()) { if (usesTargeting()) {
sb.append(" (Targeting "); sb.append(" (Targeting ");
for (final GameObject o : this.getTargets().getTargets()) { for (final GameObject o : this.getTargets().getTargets()) {