mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
cleanup of AbilityUtils.calculateAmount - if amount is pure integer, it's returned right away (that means no svars may be named after valid numbers)
former parseMath renamed and no longer returns an array of one string (just return the string)
This commit is contained in:
@@ -290,250 +290,18 @@ public class AbilityUtils {
|
|||||||
* @return a int.
|
* @return a int.
|
||||||
*/
|
*/
|
||||||
public static int calculateAmount(final Card card, String amount, final SpellAbility ability) {
|
public static int calculateAmount(final Card card, String amount, final SpellAbility ability) {
|
||||||
// amount can be anything, not just 'X' as long as sVar exists
|
// return empty strings and constants
|
||||||
|
if (StringUtils.isBlank(amount)) return 0;
|
||||||
|
if (StringUtils.isNumeric(amount)) return Integer.parseInt(amount);
|
||||||
|
|
||||||
if (amount == null || amount.isEmpty()) {
|
// Strip and save sign for calculations
|
||||||
return 0;
|
boolean startsWithPlus = amount.charAt(0) == '+';
|
||||||
}
|
boolean startsWithMinus = amount.charAt(0) == '-';
|
||||||
|
int multiplier = startsWithMinus ? -1 : 1;
|
||||||
// If Amount is -X, strip the minus sign before looking for an SVar of
|
if(startsWithMinus || startsWithPlus )
|
||||||
// that kind
|
|
||||||
int multiplier = 1;
|
|
||||||
if (amount.startsWith("-")) {
|
|
||||||
multiplier = -1;
|
|
||||||
amount = amount.substring(1);
|
amount = amount.substring(1);
|
||||||
} else if (amount.startsWith("+")) {
|
|
||||||
amount = amount.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
String svarval;
|
// These are some special cases - who is implementing them?
|
||||||
if (ability != null) {
|
|
||||||
|
|
||||||
svarval = ability.getSVar(amount);
|
|
||||||
if (svarval.equals("")) {
|
|
||||||
try {
|
|
||||||
Integer.parseInt(amount);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException ignored) {
|
|
||||||
//If this is reached, amount wasn't an integer
|
|
||||||
//Print a warning to console to help debug if an ability is not stolen properly.
|
|
||||||
StringBuilder sb = new StringBuilder("WARNING:SVar fallback to Card (");
|
|
||||||
sb.append(card.getName()).append(") and Ability(").append(ability.toString()).append(")");
|
|
||||||
System.out.println(sb.toString());
|
|
||||||
svarval = card.getSVar(amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
svarval = card.getSVar(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!svarval.equals("")) {
|
|
||||||
final String[] calcX = svarval.split("\\$");
|
|
||||||
if ((calcX.length == 1) || calcX[1].equals("none")) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (calcX[0].startsWith("Count")) {
|
|
||||||
return AbilityUtils.xCount(card, calcX[1], ability) * multiplier;
|
|
||||||
} else if (calcX[0].startsWith("Number")) {
|
|
||||||
return CardFactoryUtil.xCount(card, svarval) * multiplier;
|
|
||||||
} else if (calcX[0].startsWith("SVar")) {
|
|
||||||
final String[] l = calcX[1].split("/");
|
|
||||||
final String[] m = CardFactoryUtil.parseMath(l);
|
|
||||||
return CardFactoryUtil.doXMath(AbilityUtils.calculateAmount(card, l[0], ability), m, card)
|
|
||||||
* multiplier;
|
|
||||||
} else if (calcX[0].startsWith("PlayerCount")) {
|
|
||||||
final String hType = calcX[0].substring(11);
|
|
||||||
final ArrayList<Player> players = new ArrayList<Player>();
|
|
||||||
if (hType.equals("Players") || hType.equals("")) {
|
|
||||||
players.addAll(Singletons.getModel().getGame().getPlayers());
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
} else if (hType.equals("Opponents")) {
|
|
||||||
players.addAll(card.getController().getOpponents());
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
} else if (hType.equals("Other")) {
|
|
||||||
players.addAll(card.getController().getAllOtherPlayers());
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
} else if (hType.equals("Remembered")) {
|
|
||||||
for (final Object o : card.getRemembered()) {
|
|
||||||
if (o instanceof Player) {
|
|
||||||
players.add((Player) o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
} else if (hType.equals("NonActive")) {
|
|
||||||
players.addAll(Singletons.getModel().getGame().getPlayers());
|
|
||||||
players.remove(Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn());
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
}
|
|
||||||
} else if (calcX[0].startsWith("Remembered")) {
|
|
||||||
// Add whole Remembered list to handlePaid
|
|
||||||
final List<Card> list = new ArrayList<Card>();
|
|
||||||
if (card.getRemembered().isEmpty()) {
|
|
||||||
final Card newCard = Singletons.getModel().getGame().getCardState(card);
|
|
||||||
for (final Object o : newCard.getRemembered()) {
|
|
||||||
if (o instanceof Card) {
|
|
||||||
list.add(Singletons.getModel().getGame().getCardState((Card) o));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (calcX[0].endsWith("LKI")) { // last known information
|
|
||||||
for (final Object o : card.getRemembered()) {
|
|
||||||
if (o instanceof Card) {
|
|
||||||
list.add((Card) o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (final Object o : card.getRemembered()) {
|
|
||||||
if (o instanceof Card) {
|
|
||||||
list.add(Singletons.getModel().getGame().getCardState((Card) o));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
|
||||||
} else if (calcX[0].startsWith("Imprinted")) {
|
|
||||||
// Add whole Imprinted list to handlePaid
|
|
||||||
final List<Card> list = new ArrayList<Card>();
|
|
||||||
for (final Card c : card.getImprinted()) {
|
|
||||||
list.add(Singletons.getModel().getGame().getCardState(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
|
||||||
} else if (calcX[0].matches("Enchanted")) {
|
|
||||||
// Add whole Enchanted list to handlePaid
|
|
||||||
final List<Card> list = new ArrayList<Card>();
|
|
||||||
if (card.isEnchanting()) {
|
|
||||||
Object o = card.getEnchanting();
|
|
||||||
if (o instanceof Card) {
|
|
||||||
list.add(Singletons.getModel().getGame().getCardState((Card) o));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
|
||||||
} else if (ability != null) {
|
|
||||||
// Player attribute counting
|
|
||||||
if (calcX[0].startsWith("TargetedPlayer")) {
|
|
||||||
final ArrayList<Player> players = new ArrayList<Player>();
|
|
||||||
final SpellAbility saTargeting = ability.getSATargetingPlayer();
|
|
||||||
if (null != saTargeting) {
|
|
||||||
players.addAll(saTargeting.getTarget().getTargetPlayers());
|
|
||||||
}
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
}
|
|
||||||
if (calcX[0].startsWith("TargetedObjects")) {
|
|
||||||
final ArrayList<Object> objects = new ArrayList<Object>();
|
|
||||||
// Make list of all targeted objects starting with the root SpellAbility
|
|
||||||
SpellAbility loopSA = ability.getRootAbility();
|
|
||||||
while (loopSA != null) {
|
|
||||||
if (loopSA.getTarget() != null) {
|
|
||||||
objects.addAll(loopSA.getTarget().getTargets());
|
|
||||||
}
|
|
||||||
loopSA = loopSA.getSubAbility();
|
|
||||||
}
|
|
||||||
return CardFactoryUtil.objectXCount(objects, calcX[1], card) * multiplier;
|
|
||||||
}
|
|
||||||
if (calcX[0].startsWith("TargetedController")) {
|
|
||||||
final ArrayList<Player> players = new ArrayList<Player>();
|
|
||||||
final List<Card> list = getDefinedCards(card, "Targeted", ability);
|
|
||||||
final List<SpellAbility> sas = AbilityUtils.getDefinedSpellAbilities(card, "Targeted",
|
|
||||||
ability);
|
|
||||||
|
|
||||||
for (final Card c : list) {
|
|
||||||
final Player p = c.getController();
|
|
||||||
if (!players.contains(p)) {
|
|
||||||
players.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final SpellAbility s : sas) {
|
|
||||||
final Player p = s.getSourceCard().getController();
|
|
||||||
if (!players.contains(p)) {
|
|
||||||
players.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
}
|
|
||||||
if (calcX[0].startsWith("TargetedByTarget")) {
|
|
||||||
final List<Card> tgtList = new ArrayList<Card>();
|
|
||||||
final List<SpellAbility> saList = getDefinedSpellAbilities(card, "Targeted", ability);
|
|
||||||
|
|
||||||
for (final SpellAbility s : saList) {
|
|
||||||
tgtList.addAll(getDefinedCards(s.getSourceCard(), "Targeted", s));
|
|
||||||
}
|
|
||||||
return CardFactoryUtil.handlePaid(tgtList, calcX[1], card) * multiplier;
|
|
||||||
}
|
|
||||||
if (calcX[0].startsWith("TriggeredPlayer") || calcX[0].startsWith("TriggeredTarget")) {
|
|
||||||
final SpellAbility root = ability.getRootAbility();
|
|
||||||
Object o = root.getTriggeringObject(calcX[0].substring(9));
|
|
||||||
final List<Player> players = new ArrayList<Player>();
|
|
||||||
if (o instanceof Player) {
|
|
||||||
players.add((Player) o);
|
|
||||||
}
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
}
|
|
||||||
// Added on 9/30/12 (ArsenalNut) - Ended up not using but might be useful in future
|
|
||||||
/*
|
|
||||||
if (calcX[0].startsWith("EnchantedController")) {
|
|
||||||
final ArrayList<Player> players = new ArrayList<Player>();
|
|
||||||
players.addAll(AbilityFactory.getDefinedPlayers(card, "EnchantedController", ability));
|
|
||||||
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
List<Card> list = new ArrayList<Card>();
|
|
||||||
if (calcX[0].startsWith("Sacrificed")) {
|
|
||||||
list = ability.getRootAbility().getPaidList("Sacrificed");
|
|
||||||
} else if (calcX[0].startsWith("Discarded")) {
|
|
||||||
final SpellAbility root = ability.getRootAbility();
|
|
||||||
list = root.getPaidList("Discarded");
|
|
||||||
if ((null == list) && root.isTrigger()) {
|
|
||||||
list = root.getSourceCard().getSpellPermanent().getPaidList("Discarded");
|
|
||||||
}
|
|
||||||
} else if (calcX[0].startsWith("Exiled")) {
|
|
||||||
list = ability.getRootAbility().getPaidList("Exiled");
|
|
||||||
} else if (calcX[0].startsWith("Tapped")) {
|
|
||||||
list = ability.getRootAbility().getPaidList("Tapped");
|
|
||||||
} else if (calcX[0].startsWith("Revealed")) {
|
|
||||||
list = ability.getRootAbility().getPaidList("Revealed");
|
|
||||||
} else if (calcX[0].startsWith("Targeted")) {
|
|
||||||
list = ability.findTargetedCards();
|
|
||||||
} else if (calcX[0].startsWith("Triggered")) {
|
|
||||||
final SpellAbility root = ability.getRootAbility();
|
|
||||||
list = new ArrayList<Card>();
|
|
||||||
list.add((Card) root.getTriggeringObject(calcX[0].substring(9)));
|
|
||||||
} else if (calcX[0].startsWith("TriggerCount")) {
|
|
||||||
// TriggerCount is similar to a regular Count, but just
|
|
||||||
// pulls Integer Values from Trigger objects
|
|
||||||
final SpellAbility root = ability.getRootAbility();
|
|
||||||
final String[] l = calcX[1].split("/");
|
|
||||||
final String[] m = CardFactoryUtil.parseMath(l);
|
|
||||||
final int count = (Integer) root.getTriggeringObject(l[0]);
|
|
||||||
|
|
||||||
return CardFactoryUtil.doXMath(count, m, card) * multiplier;
|
|
||||||
} else if (calcX[0].startsWith("Replaced")) {
|
|
||||||
final SpellAbility root = ability.getRootAbility();
|
|
||||||
list = new ArrayList<Card>();
|
|
||||||
list.add((Card) root.getReplacingObject(calcX[0].substring(8)));
|
|
||||||
} else if (calcX[0].startsWith("ReplaceCount")) {
|
|
||||||
// ReplaceCount is similar to a regular Count, but just
|
|
||||||
// pulls Integer Values from Replacement objects
|
|
||||||
final SpellAbility root = ability.getRootAbility();
|
|
||||||
final String[] l = calcX[1].split("/");
|
|
||||||
final String[] m = CardFactoryUtil.parseMath(l);
|
|
||||||
final int count = (Integer) root.getReplacingObject(l[0]);
|
|
||||||
|
|
||||||
return CardFactoryUtil.doXMath(count, m, card) * multiplier;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (amount.equals("ChosenX") || amount.equals("ChosenY")) {
|
if (amount.equals("ChosenX") || amount.equals("ChosenY")) {
|
||||||
// isn't made yet
|
// isn't made yet
|
||||||
return 0;
|
return 0;
|
||||||
@@ -543,7 +311,244 @@ public class AbilityUtils {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Integer.parseInt(amount) * multiplier;
|
// Try to fetch variable, try ability first, then card.
|
||||||
|
String svarval = null;
|
||||||
|
if (ability != null) {
|
||||||
|
svarval = ability.getSVar(amount);
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(svarval)) {
|
||||||
|
if( ability != null) {
|
||||||
|
System.err.printf("SVar '%s' not found in ability, fallback to Card (%s). Ability is (%s)%n", amount, card.getName(), ability);
|
||||||
|
}
|
||||||
|
svarval = card.getSVar(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing to do here if value is missing or blank
|
||||||
|
if (StringUtils.isBlank(svarval)) {
|
||||||
|
System.err.printf("SVar '%s' not defined in Card (%s)%n", amount, card.getName());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle numeric constant coming in svar value
|
||||||
|
if( StringUtils.isNumeric(svarval) )
|
||||||
|
return multiplier * Integer.parseInt(svarval);
|
||||||
|
|
||||||
|
// Parse Object$Property string
|
||||||
|
final String[] calcX = svarval.split("\\$");
|
||||||
|
|
||||||
|
// Incorrect parses mean zero.
|
||||||
|
if ((calcX.length == 1) || calcX[1].equals("none"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (calcX[0].startsWith("Count"))
|
||||||
|
return AbilityUtils.xCount(card, calcX[1], ability) * multiplier;
|
||||||
|
|
||||||
|
if (calcX[0].startsWith("Number"))
|
||||||
|
return CardFactoryUtil.xCount(card, svarval) * multiplier;
|
||||||
|
|
||||||
|
if (calcX[0].startsWith("SVar")) {
|
||||||
|
final String[] l = calcX[1].split("/");
|
||||||
|
final String m = CardFactoryUtil.extractOperators(calcX[1]);
|
||||||
|
return CardFactoryUtil.doXMath(AbilityUtils.calculateAmount(card, l[0], ability), m, card) * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calcX[0].startsWith("PlayerCount")) {
|
||||||
|
final String hType = calcX[0].substring(11);
|
||||||
|
final ArrayList<Player> players = new ArrayList<Player>();
|
||||||
|
if (hType.equals("Players") || hType.equals("")) {
|
||||||
|
players.addAll(Singletons.getModel().getGame().getPlayers());
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
} else if (hType.equals("Opponents")) {
|
||||||
|
players.addAll(card.getController().getOpponents());
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
} else if (hType.equals("Other")) {
|
||||||
|
players.addAll(card.getController().getAllOtherPlayers());
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
} else if (hType.equals("Remembered")) {
|
||||||
|
for (final Object o : card.getRemembered()) {
|
||||||
|
if (o instanceof Player) {
|
||||||
|
players.add((Player) o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
} else if (hType.equals("NonActive")) {
|
||||||
|
players.addAll(Singletons.getModel().getGame().getPlayers());
|
||||||
|
players.remove(Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn());
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calcX[0].startsWith("Remembered")) {
|
||||||
|
// Add whole Remembered list to handlePaid
|
||||||
|
final List<Card> list = new ArrayList<Card>();
|
||||||
|
if (card.getRemembered().isEmpty()) {
|
||||||
|
final Card newCard = Singletons.getModel().getGame().getCardState(card);
|
||||||
|
for (final Object o : newCard.getRemembered()) {
|
||||||
|
if (o instanceof Card) {
|
||||||
|
list.add(Singletons.getModel().getGame().getCardState((Card) o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calcX[0].endsWith("LKI")) { // last known information
|
||||||
|
for (final Object o : card.getRemembered()) {
|
||||||
|
if (o instanceof Card) {
|
||||||
|
list.add((Card) o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (final Object o : card.getRemembered()) {
|
||||||
|
if (o instanceof Card) {
|
||||||
|
list.add(Singletons.getModel().getGame().getCardState((Card) o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calcX[0].startsWith("Imprinted")) {
|
||||||
|
// Add whole Imprinted list to handlePaid
|
||||||
|
final List<Card> list = new ArrayList<Card>();
|
||||||
|
for (final Card c : card.getImprinted()) {
|
||||||
|
list.add(Singletons.getModel().getGame().getCardState(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calcX[0].matches("Enchanted")) {
|
||||||
|
// Add whole Enchanted list to handlePaid
|
||||||
|
final List<Card> list = new ArrayList<Card>();
|
||||||
|
if (card.isEnchanting()) {
|
||||||
|
Object o = card.getEnchanting();
|
||||||
|
if (o instanceof Card) {
|
||||||
|
list.add(Singletons.getModel().getGame().getCardState((Card) o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ability == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Player attribute counting
|
||||||
|
if (calcX[0].startsWith("TargetedPlayer")) {
|
||||||
|
final ArrayList<Player> players = new ArrayList<Player>();
|
||||||
|
final SpellAbility saTargeting = ability.getSATargetingPlayer();
|
||||||
|
if (null != saTargeting) {
|
||||||
|
players.addAll(saTargeting.getTarget().getTargetPlayers());
|
||||||
|
}
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
if (calcX[0].startsWith("TargetedObjects")) {
|
||||||
|
final ArrayList<Object> objects = new ArrayList<Object>();
|
||||||
|
// Make list of all targeted objects starting with the root SpellAbility
|
||||||
|
SpellAbility loopSA = ability.getRootAbility();
|
||||||
|
while (loopSA != null) {
|
||||||
|
if (loopSA.getTarget() != null) {
|
||||||
|
objects.addAll(loopSA.getTarget().getTargets());
|
||||||
|
}
|
||||||
|
loopSA = loopSA.getSubAbility();
|
||||||
|
}
|
||||||
|
return CardFactoryUtil.objectXCount(objects, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
if (calcX[0].startsWith("TargetedController")) {
|
||||||
|
final ArrayList<Player> players = new ArrayList<Player>();
|
||||||
|
final List<Card> list = getDefinedCards(card, "Targeted", ability);
|
||||||
|
final List<SpellAbility> sas = AbilityUtils.getDefinedSpellAbilities(card, "Targeted",
|
||||||
|
ability);
|
||||||
|
|
||||||
|
for (final Card c : list) {
|
||||||
|
final Player p = c.getController();
|
||||||
|
if (!players.contains(p)) {
|
||||||
|
players.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final SpellAbility s : sas) {
|
||||||
|
final Player p = s.getSourceCard().getController();
|
||||||
|
if (!players.contains(p)) {
|
||||||
|
players.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
if (calcX[0].startsWith("TargetedByTarget")) {
|
||||||
|
final List<Card> tgtList = new ArrayList<Card>();
|
||||||
|
final List<SpellAbility> saList = getDefinedSpellAbilities(card, "Targeted", ability);
|
||||||
|
|
||||||
|
for (final SpellAbility s : saList) {
|
||||||
|
tgtList.addAll(getDefinedCards(s.getSourceCard(), "Targeted", s));
|
||||||
|
}
|
||||||
|
return CardFactoryUtil.handlePaid(tgtList, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
if (calcX[0].startsWith("TriggeredPlayer") || calcX[0].startsWith("TriggeredTarget")) {
|
||||||
|
final SpellAbility root = ability.getRootAbility();
|
||||||
|
Object o = root.getTriggeringObject(calcX[0].substring(9));
|
||||||
|
final List<Player> players = new ArrayList<Player>();
|
||||||
|
if (o instanceof Player) {
|
||||||
|
players.add((Player) o);
|
||||||
|
}
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
// Added on 9/30/12 (ArsenalNut) - Ended up not using but might be useful in future
|
||||||
|
/*
|
||||||
|
if (calcX[0].startsWith("EnchantedController")) {
|
||||||
|
final ArrayList<Player> players = new ArrayList<Player>();
|
||||||
|
players.addAll(AbilityFactory.getDefinedPlayers(card, "EnchantedController", ability));
|
||||||
|
return CardFactoryUtil.playerXCount(players, calcX[1], card) * multiplier;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
List<Card> list = new ArrayList<Card>();
|
||||||
|
if (calcX[0].startsWith("Sacrificed")) {
|
||||||
|
list = ability.getRootAbility().getPaidList("Sacrificed");
|
||||||
|
} else if (calcX[0].startsWith("Discarded")) {
|
||||||
|
final SpellAbility root = ability.getRootAbility();
|
||||||
|
list = root.getPaidList("Discarded");
|
||||||
|
if ((null == list) && root.isTrigger()) {
|
||||||
|
list = root.getSourceCard().getSpellPermanent().getPaidList("Discarded");
|
||||||
|
}
|
||||||
|
} else if (calcX[0].startsWith("Exiled")) {
|
||||||
|
list = ability.getRootAbility().getPaidList("Exiled");
|
||||||
|
} else if (calcX[0].startsWith("Tapped")) {
|
||||||
|
list = ability.getRootAbility().getPaidList("Tapped");
|
||||||
|
} else if (calcX[0].startsWith("Revealed")) {
|
||||||
|
list = ability.getRootAbility().getPaidList("Revealed");
|
||||||
|
} else if (calcX[0].startsWith("Targeted")) {
|
||||||
|
list = ability.findTargetedCards();
|
||||||
|
} else if (calcX[0].startsWith("Triggered")) {
|
||||||
|
final SpellAbility root = ability.getRootAbility();
|
||||||
|
list = new ArrayList<Card>();
|
||||||
|
list.add((Card) root.getTriggeringObject(calcX[0].substring(9)));
|
||||||
|
} else if (calcX[0].startsWith("TriggerCount")) {
|
||||||
|
// TriggerCount is similar to a regular Count, but just
|
||||||
|
// pulls Integer Values from Trigger objects
|
||||||
|
final SpellAbility root = ability.getRootAbility();
|
||||||
|
final String[] l = calcX[1].split("/");
|
||||||
|
final String m = CardFactoryUtil.extractOperators(calcX[1]);
|
||||||
|
final int count = (Integer) root.getTriggeringObject(l[0]);
|
||||||
|
|
||||||
|
return CardFactoryUtil.doXMath(count, m, card) * multiplier;
|
||||||
|
} else if (calcX[0].startsWith("Replaced")) {
|
||||||
|
final SpellAbility root = ability.getRootAbility();
|
||||||
|
list = new ArrayList<Card>();
|
||||||
|
list.add((Card) root.getReplacingObject(calcX[0].substring(8)));
|
||||||
|
} else if (calcX[0].startsWith("ReplaceCount")) {
|
||||||
|
// ReplaceCount is similar to a regular Count, but just
|
||||||
|
// pulls Integer Values from Replacement objects
|
||||||
|
final SpellAbility root = ability.getRootAbility();
|
||||||
|
final String[] l = calcX[1].split("/");
|
||||||
|
final String m = CardFactoryUtil.extractOperators(calcX[1]);
|
||||||
|
final int count = (Integer) root.getReplacingObject(l[0]);
|
||||||
|
|
||||||
|
return CardFactoryUtil.doXMath(count, m, card) * multiplier;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CardFactoryUtil.handlePaid(list, calcX[1], card) * multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1231,7 +1236,7 @@ public class AbilityUtils {
|
|||||||
public static int xCount(final Card c, final String s, final SpellAbility sa) {
|
public static int xCount(final Card c, final String s, final SpellAbility sa) {
|
||||||
|
|
||||||
final String[] l = s.split("/");
|
final String[] l = s.split("/");
|
||||||
final String[] m = CardFactoryUtil.parseMath(l);
|
final String expr = CardFactoryUtil.extractOperators(s);
|
||||||
|
|
||||||
final String[] sq;
|
final String[] sq;
|
||||||
sq = l[0].split("\\.");
|
sq = l[0].split("\\.");
|
||||||
@@ -1240,9 +1245,9 @@ public class AbilityUtils {
|
|||||||
// Count$Kicked.<numHB>.<numNotHB>
|
// Count$Kicked.<numHB>.<numNotHB>
|
||||||
if (sq[0].startsWith("Kicked")) {
|
if (sq[0].startsWith("Kicked")) {
|
||||||
if (sa.isKicked()) {
|
if (sa.isKicked()) {
|
||||||
return CardFactoryUtil.doXMath(Integer.parseInt(sq[1]), m, c); // Kicked
|
return CardFactoryUtil.doXMath(Integer.parseInt(sq[1]), expr, c); // Kicked
|
||||||
} else {
|
} else {
|
||||||
return CardFactoryUtil.doXMath(Integer.parseInt(sq[2]), m, c); // not Kicked
|
return CardFactoryUtil.doXMath(Integer.parseInt(sq[2]), expr, c); // not Kicked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1252,9 +1257,9 @@ public class AbilityUtils {
|
|||||||
final int lhs = calculateAmount(c, compString[1], sa);
|
final int lhs = calculateAmount(c, compString[1], sa);
|
||||||
final int rhs = calculateAmount(c, compString[2].substring(2), sa);
|
final int rhs = calculateAmount(c, compString[2].substring(2), sa);
|
||||||
if (Expressions.compare(lhs, compString[2], rhs)) {
|
if (Expressions.compare(lhs, compString[2], rhs)) {
|
||||||
return CardFactoryUtil.doXMath(Integer.parseInt(sq[1]), m, c);
|
return CardFactoryUtil.doXMath(Integer.parseInt(sq[1]), expr, c);
|
||||||
} else {
|
} else {
|
||||||
return CardFactoryUtil.doXMath(Integer.parseInt(sq[2]), m, c);
|
return CardFactoryUtil.doXMath(Integer.parseInt(sq[2]), expr, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -866,13 +866,9 @@ public class CardFactoryUtil {
|
|||||||
* an array of {@link java.lang.String} objects.
|
* an array of {@link java.lang.String} objects.
|
||||||
* @return an array of {@link java.lang.String} objects.
|
* @return an array of {@link java.lang.String} objects.
|
||||||
*/
|
*/
|
||||||
public static String[] parseMath(final String[] l) {
|
public static String extractOperators(final String expression) {
|
||||||
final String[] m = { "none" };
|
String[] l = expression.split("/");
|
||||||
if (l.length > 1) {
|
return l.length > 1 ? l[1] : null;
|
||||||
m[0] = l[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -889,20 +885,12 @@ public class CardFactoryUtil {
|
|||||||
* @return a int.
|
* @return a int.
|
||||||
*/
|
*/
|
||||||
public static int objectXCount(final ArrayList<Object> objects, final String s, final Card source) {
|
public static int objectXCount(final ArrayList<Object> objects, final String s, final Card source) {
|
||||||
if (objects.size() == 0) {
|
if (objects.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] l = s.split("/");
|
int n = s.startsWith("Amount") ? objects.size() : 0;
|
||||||
final String[] m = CardFactoryUtil.parseMath(l);
|
return CardFactoryUtil.doXMath(n, CardFactoryUtil.extractOperators(s), source);
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
if (s.startsWith("Amount")) {
|
|
||||||
n = objects.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardFactoryUtil.doXMath(n, m, source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -924,7 +912,7 @@ public class CardFactoryUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String[] l = s.split("/");
|
final String[] l = s.split("/");
|
||||||
final String[] m = CardFactoryUtil.parseMath(l);
|
final String m = CardFactoryUtil.extractOperators(s);
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
@@ -1115,19 +1103,19 @@ public class CardFactoryUtil {
|
|||||||
*
|
*
|
||||||
* @param c
|
* @param c
|
||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
* @param s
|
* @param expression
|
||||||
* a {@link java.lang.String} object.
|
* a {@link java.lang.String} object.
|
||||||
* @return a int.
|
* @return a int.
|
||||||
*/
|
*/
|
||||||
public static int xCount(final Card c, final String s) {
|
public static int xCount(final Card c, final String expression) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
final Player cardController = c.getController();
|
final Player cardController = c.getController();
|
||||||
final Player oppController = cardController.getOpponent();
|
final Player oppController = cardController.getOpponent();
|
||||||
final Player activePlayer = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
final Player activePlayer = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn();
|
||||||
|
|
||||||
final String[] l = s.split("/");
|
final String[] l = expression.split("/");
|
||||||
final String[] m = CardFactoryUtil.parseMath(l);
|
final String m = CardFactoryUtil.extractOperators(expression);
|
||||||
|
|
||||||
// accept straight numbers
|
// accept straight numbers
|
||||||
if (l[0].startsWith("Number$")) {
|
if (l[0].startsWith("Number$")) {
|
||||||
@@ -2028,12 +2016,12 @@ public class CardFactoryUtil {
|
|||||||
return CardFactoryUtil.doXMath(n, m, c);
|
return CardFactoryUtil.doXMath(n, m, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int doXMath(final int num, final String m, final Card c) {
|
public static int doXMath(final int num, final String operators, final Card c) {
|
||||||
if (m.equals("none")) {
|
if (operators == null || operators.equals("none")) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] s = m.split("\\.");
|
final String[] s = operators.split("\\.");
|
||||||
int secondaryNum = 0;
|
int secondaryNum = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -2092,27 +2080,6 @@ public class CardFactoryUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* doXMath.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param num
|
|
||||||
* a int.
|
|
||||||
* @param m
|
|
||||||
* an array of {@link java.lang.String} objects.
|
|
||||||
* @param c
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
* @return a int.
|
|
||||||
*/
|
|
||||||
public static int doXMath(final int num, final String[] m, final Card c) {
|
|
||||||
if (m.length == 0) {
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CardFactoryUtil.doXMath(num, m[0], c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* handlePaid.
|
* handlePaid.
|
||||||
@@ -2145,17 +2112,9 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (string.startsWith("Valid")) {
|
if (string.startsWith("Valid")) {
|
||||||
final String[] m = { "none" };
|
|
||||||
|
|
||||||
String valid = string.substring(6);
|
String valid = string.substring(6);
|
||||||
final String[] l;
|
|
||||||
l = valid.split("/"); // separate the specification from any math
|
|
||||||
valid = l[0];
|
|
||||||
if (l.length > 1) {
|
|
||||||
m[0] = l[1];
|
|
||||||
}
|
|
||||||
final List<Card> list = CardLists.getValidCards(paidList, valid, source.getController(), source);
|
final List<Card> list = CardLists.getValidCards(paidList, valid, source.getController(), source);
|
||||||
return CardFactoryUtil.doXMath(list.size(), m, source);
|
return CardFactoryUtil.doXMath(list.size(), CardFactoryUtil.extractOperators(valid), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tot = 0;
|
int tot = 0;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
package forge.card.cost;
|
package forge.card.cost;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
@@ -120,12 +122,7 @@ public abstract class CostPart {
|
|||||||
* @return the integer
|
* @return the integer
|
||||||
*/
|
*/
|
||||||
public final Integer convertAmount() {
|
public final Integer convertAmount() {
|
||||||
Integer i = null;
|
return StringUtils.isNumeric(amount) ? Integer.parseInt(amount) : null;
|
||||||
try {
|
|
||||||
i = Integer.parseInt(this.getAmount());
|
|
||||||
} catch (final NumberFormatException e) {
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ public class CostPartMana extends CostPart {
|
|||||||
// if X cost is a defined value, other than xPaid
|
// if X cost is a defined value, other than xPaid
|
||||||
if (!ability.getSVar("X").equals("Count$xPaid")) {
|
if (!ability.getSVar("X").equals("Count$xPaid")) {
|
||||||
// this currently only works for things about Targeted object
|
// this currently only works for things about Targeted object
|
||||||
manaToAdd = AbilityUtils.calculateAmount(source, "X", ability) * this.getAmountOfX();
|
manaToAdd += AbilityUtils.calculateAmount(source, "X", ability) * this.getAmountOfX();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,16 +221,15 @@ public class CostPartMana extends CostPart {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.getAmountOfX() > 0) {
|
if (this.getAmountOfX() > 0) {
|
||||||
if( !"X".equals(ability.getParam("Announce")) ) {
|
if( !ability.isAnnouncing("X") ) {
|
||||||
source.setXManaCostPaid(0);
|
source.setXManaCostPaid(0);
|
||||||
InputPayment inpPayment = new InputPayManaX(ability, this.getAmountOfX(), this.canXbe0());
|
InputPayment inpPayment = new InputPayManaX(ability, this.getAmountOfX(), this.canXbe0());
|
||||||
FThreads.setInputAndWait(inpPayment);
|
FThreads.setInputAndWait(inpPayment);
|
||||||
if(!inpPayment.isPaid())
|
if(!inpPayment.isPaid())
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
String xVar = ability.getSVar("X");
|
int x = AbilityUtils.calculateAmount(source, ability.getSVar("X"), ability);
|
||||||
String xVal = xVar.split("\\$")[1];
|
source.setXManaCostPaid(x);
|
||||||
source.setXManaCostPaid(Integer.parseInt(xVal));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -158,8 +158,8 @@ public class HumanPlaySpellAbility {
|
|||||||
Integer value = ability.getActivatingPlayer().getController().announceRequirements(ability, aVar, ability.getPayCosts().getCostMana().canXbe0());
|
Integer value = ability.getActivatingPlayer().getController().announceRequirements(ability, aVar, ability.getPayCosts().getCostMana().canXbe0());
|
||||||
if ( null == value )
|
if ( null == value )
|
||||||
return false;
|
return false;
|
||||||
ability.setSVar(aVar, "Number$" + value);
|
ability.setSVar(aVar, value.toString());
|
||||||
ability.getSourceCard().setSVar(aVar, "Number$" + value);
|
ability.getSourceCard().setSVar(aVar, value.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
@@ -35,6 +37,7 @@ import forge.card.mana.Mana;
|
|||||||
import forge.card.mana.ManaCost;
|
import forge.card.mana.ManaCost;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.util.TextUtil;
|
||||||
|
|
||||||
//only SpellAbility can go on the stack
|
//only SpellAbility can go on the stack
|
||||||
//override any methods as needed
|
//override any methods as needed
|
||||||
@@ -1741,4 +1744,18 @@ public abstract class SpellAbility implements ISpellAbility {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether variable was present in the announce list.
|
||||||
|
*/
|
||||||
|
public boolean isAnnouncing(String variable) {
|
||||||
|
String announce = getParam("Announce");
|
||||||
|
if (StringUtils.isBlank(announce)) return false;
|
||||||
|
String[] announcedOnes = TextUtil.split(announce, ',');
|
||||||
|
for(String a : announcedOnes) {
|
||||||
|
if( a.trim().equalsIgnoreCase(variable))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ public class Target {
|
|||||||
*
|
*
|
||||||
* @return the max targets
|
* @return the max targets
|
||||||
*/
|
*/
|
||||||
public final String getMaxTargets() {
|
private final String getMaxTargets() {
|
||||||
return this.maxTargets;
|
return this.maxTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user