mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
@@ -29,7 +29,6 @@ public enum AbilityKey {
|
||||
Blockers("Blockers"),
|
||||
CanReveal("CanReveal"),
|
||||
CastSA("CastSA"),
|
||||
CastSACMC("CastSACMC"),
|
||||
Card("Card"),
|
||||
Cards("Cards"),
|
||||
CardLKI("CardLKI"),
|
||||
|
||||
@@ -283,7 +283,7 @@ public class AbilityUtils {
|
||||
System.err.println("Warning: couldn't find trigger SA in the chain of SpellAbility " + sa);
|
||||
}
|
||||
} else if (defined.equals("FirstRemembered")) {
|
||||
Object o = Iterables.getFirst(hostCard.getRemembered(), null);
|
||||
Object o = hostCard.getFirstRemembered();
|
||||
if (o != null && o instanceof Card) {
|
||||
cards.add(game.getCardState((Card) o));
|
||||
}
|
||||
@@ -542,6 +542,9 @@ public class AbilityUtils {
|
||||
}
|
||||
} else if (calcX[0].equals("OriginalHost")) {
|
||||
val = xCount(ability.getOriginalHost(), calcX[1], ability);
|
||||
} else if (calcX[0].equals("LastStateBattlefield") && ability instanceof SpellAbility) {
|
||||
Card c = ((SpellAbility) ability).getLastStateBattlefield().get(card);
|
||||
val = c == null ? 0 : xCount(c, calcX[1], ability);
|
||||
} else if (calcX[0].startsWith("Remembered")) {
|
||||
// Add whole Remembered list to handlePaid
|
||||
final CardCollection list = new CardCollection();
|
||||
@@ -685,10 +688,9 @@ public class AbilityUtils {
|
||||
Object o = root.getTriggeringObject(AbilityKey.fromString(calcX[0].substring(9)));
|
||||
val = o instanceof Player ? playerXProperty((Player) o, calcX[1], card, ability) : 0;
|
||||
}
|
||||
else if (calcX[0].equals("TriggeredSpellAbility")) {
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
SpellAbility sat = (SpellAbility) root.getTriggeringObject(AbilityKey.SpellAbility);
|
||||
val = calculateAmount(sat.getHostCard(), calcX[1], sat);
|
||||
else if (calcX[0].equals("TriggeredSpellAbility") || calcX[0].equals("TriggeredStackInstance") || calcX[0].equals("SpellTargeted")) {
|
||||
final SpellAbility sat = getDefinedSpellAbilities(card, calcX[0], sa).get(0);
|
||||
val = xCount(sat.getHostCard(), calcX[1], sat);
|
||||
}
|
||||
else if (calcX[0].startsWith("TriggerCount")) {
|
||||
// TriggerCount is similar to a regular Count, but just
|
||||
@@ -728,7 +730,7 @@ public class AbilityUtils {
|
||||
else if (calcX[0].startsWith("Discarded")) {
|
||||
final SpellAbility root = sa.getRootAbility();
|
||||
list = root.getPaidList("Discarded");
|
||||
if ((null == list) && root.isTrigger()) {
|
||||
if (null == list && root.isTrigger()) {
|
||||
list = root.getHostCard().getSpellPermanent().getPaidList("Discarded");
|
||||
}
|
||||
}
|
||||
@@ -1847,7 +1849,7 @@ public class AbilityUtils {
|
||||
return doXMath(0, expr, c, ctb);
|
||||
}
|
||||
}
|
||||
list = CardLists.getValidCards(list, k[1], sa.getActivatingPlayer(), c, sa);
|
||||
list = CardLists.getValidCards(list, k[1], player, c, sa);
|
||||
return doXMath(list.size(), expr, c, ctb);
|
||||
}
|
||||
|
||||
@@ -1871,7 +1873,7 @@ public class AbilityUtils {
|
||||
return doXMath(0, expr, c, ctb);
|
||||
}
|
||||
}
|
||||
list = CardLists.getValidCards(list, k[1], sa.getActivatingPlayer(), c, sa);
|
||||
list = CardLists.getValidCards(list, k[1], player, c, sa);
|
||||
return doXMath(list.size(), expr, c, ctb);
|
||||
}
|
||||
|
||||
@@ -1899,14 +1901,14 @@ public class AbilityUtils {
|
||||
// fallback if ctb isn't a spellability
|
||||
if (sq[0].startsWith("LastStateBattlefield")) {
|
||||
final String[] k = l[0].split(" ");
|
||||
CardCollection list = new CardCollection(game.getLastStateBattlefield());
|
||||
CardCollectionView list = game.getLastStateBattlefield();
|
||||
list = CardLists.getValidCards(list, k[1], player, c, ctb);
|
||||
return doXMath(list.size(), expr, c, ctb);
|
||||
}
|
||||
|
||||
if (sq[0].startsWith("LastStateGraveyard")) {
|
||||
final String[] k = l[0].split(" ");
|
||||
CardCollection list = new CardCollection(game.getLastStateGraveyard());
|
||||
CardCollectionView list = game.getLastStateGraveyard();
|
||||
list = CardLists.getValidCards(list, k[1], player, c, ctb);
|
||||
return doXMath(list.size(), expr, c, ctb);
|
||||
}
|
||||
@@ -2165,17 +2167,22 @@ public class AbilityUtils {
|
||||
// Count$CardManaCost
|
||||
if (sq[0].contains("CardManaCost")) {
|
||||
Card ce;
|
||||
if (sq[0].contains("Equipped") && c.isEquipping()) {
|
||||
ce = c.getEquipping();
|
||||
}
|
||||
else if (sq[0].contains("Remembered")) {
|
||||
if (sq[0].contains("Remembered")) {
|
||||
ce = (Card) c.getFirstRemembered();
|
||||
}
|
||||
else {
|
||||
ce = c;
|
||||
}
|
||||
|
||||
return doXMath(ce == null ? 0 : ce.getCMC(), expr, c, ctb);
|
||||
int cmc = ce == null ? 0 : ce.getCMC();
|
||||
|
||||
if (sq[0].contains("LKI") && ctb instanceof SpellAbility && ce != null && !ce.isInZone(ZoneType.Stack) && ce.getManaCost() != null) {
|
||||
if (((SpellAbility) ctb).getXManaCostPaid() != null) {
|
||||
cmc += ((SpellAbility) ctb).getXManaCostPaid() * ce.getManaCost().countX();
|
||||
}
|
||||
}
|
||||
|
||||
return doXMath(cmc, expr, c, ctb);
|
||||
}
|
||||
|
||||
if (sq[0].startsWith("RememberedSize")) {
|
||||
|
||||
@@ -122,8 +122,9 @@ public class CounterEffect extends SpellAbilityEffect {
|
||||
CardZoneTable table = new CardZoneTable();
|
||||
for (final SpellAbility tgtSA : sas) {
|
||||
final Card tgtSACard = tgtSA.getHostCard();
|
||||
// should remember even that spell cannot be countered, e.g. Dovescape
|
||||
// TODO use LKI in case the spell gets countered before (else X amounts would be missing)
|
||||
// should remember even that spell cannot be countered
|
||||
// currently all effects using this are targeted in case the spell gets countered before
|
||||
// so don't need to worry about LKI (else X amounts would be missing)
|
||||
if (sa.hasParam("RememberCounteredCMC")) {
|
||||
sa.getHostCard().addRemembered(Integer.valueOf(tgtSACard.getCMC()));
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.Expressions;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.Lang;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
@@ -89,41 +90,12 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
* @return a {@link java.util.HashMap} object.
|
||||
*/
|
||||
private static Map<String, String> parseParams(final String abString, final Card hostCard) {
|
||||
final Map<String, String> mapParameters = Maps.newHashMap();
|
||||
|
||||
if (!(abString.length() > 0)) {
|
||||
throw new RuntimeException("StaticEffectFactory : getAbility -- abString too short in "
|
||||
+ hostCard.getName() + ": [" + abString + "]");
|
||||
}
|
||||
|
||||
final String[] a = abString.split("\\|");
|
||||
|
||||
for (int aCnt = 0; aCnt < a.length; aCnt++) {
|
||||
a[aCnt] = a[aCnt].trim();
|
||||
}
|
||||
|
||||
if (!(a.length > 0)) {
|
||||
throw new RuntimeException("StaticEffectFactory : getAbility -- a[] too short in " + hostCard.getName());
|
||||
}
|
||||
|
||||
for (final String element : a) {
|
||||
final String[] aa = element.split("\\$");
|
||||
|
||||
for (int aaCnt = 0; aaCnt < aa.length; aaCnt++) {
|
||||
aa[aaCnt] = aa[aaCnt].trim();
|
||||
}
|
||||
|
||||
if (aa.length != 2) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("StaticEffectFactory Parsing Error: Split length of ");
|
||||
sb.append(element).append(" in ").append(hostCard.getName()).append(" is not 2.");
|
||||
throw new RuntimeException(sb.toString());
|
||||
}
|
||||
|
||||
mapParameters.put(aa[0], aa[1]);
|
||||
}
|
||||
|
||||
return mapParameters;
|
||||
return FileSection.parseToMap(abString, FileSection.DOLLAR_SIGN_KV_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -313,8 +313,7 @@ public class TriggerSpellAbilityCastOrCopy extends Trigger {
|
||||
AbilityKey.Player,
|
||||
AbilityKey.Activator,
|
||||
AbilityKey.CurrentStormCount,
|
||||
AbilityKey.CurrentCastSpells,
|
||||
AbilityKey.CastSACMC
|
||||
AbilityKey.CurrentCastSpells
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +308,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
runParams.put(AbilityKey.Cost, sp.getPayCosts());
|
||||
runParams.put(AbilityKey.Activator, sp.getActivatingPlayer());
|
||||
runParams.put(AbilityKey.CastSA, si.getSpellAbility(true));
|
||||
runParams.put(AbilityKey.CastSACMC, si.getSpellAbility(true).getHostCard().getCMC());
|
||||
runParams.put(AbilityKey.CurrentStormCount, thisTurnCast.size());
|
||||
runParams.put(AbilityKey.CurrentCastSpells, Lists.newArrayList(thisTurnCast));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user