mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
merged "Produced$ Any" feature branch into trunk (Issue #266)
This commit is contained in:
@@ -2790,11 +2790,10 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (am.isBasic() && !res.contains(am)) {
|
if ((am.isBasic() || am.isReflectedMana()) && !res.contains(am)) {
|
||||||
res.add(am);
|
|
||||||
} else if (am.isReflectedMana() && !res.contains(am)) {
|
|
||||||
res.add(am);
|
res.add(am);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import forge.card.spellability.AbilityMana;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.error.ErrorViewer;
|
import forge.error.ErrorViewer;
|
||||||
|
import forge.gui.input.InputPayManaCostUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -177,6 +178,8 @@ public class ComputerUtil {
|
|||||||
final CostPayment pay = new CostPayment(cost, sa);
|
final CostPayment pay = new CostPayment(cost, sa);
|
||||||
if (pay.payComputerCosts()) {
|
if (pay.payComputerCosts()) {
|
||||||
AllZone.getStack().addAndUnfreeze(sa);
|
AllZone.getStack().addAndUnfreeze(sa);
|
||||||
|
//TODO: solve problems with TapsForMana triggers by adding
|
||||||
|
// sources tapped here if possible (ArsenalNut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -608,122 +611,254 @@ public class ComputerUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<String> colors;
|
|
||||||
|
|
||||||
cost = manapool.subtractMana(sa, cost);
|
cost = manapool.subtractMana(sa, cost);
|
||||||
if (card.getSVar("ManaNeededToAvoidNegativeEffect") != "") {
|
if (card.getSVar("ManaNeededToAvoidNegativeEffect") != "") {
|
||||||
cost.setManaNeededToAvoidNegativeEffect(card.getSVar("ManaNeededToAvoidNegativeEffect").split(","));
|
String[] negEffects = card.getSVar("ManaNeededToAvoidNegativeEffect").split(",");
|
||||||
|
int amountAdded = 0;
|
||||||
|
for (int nStr = 0; nStr < negEffects.length; nStr++) {
|
||||||
|
// convert long color strings to short color strings
|
||||||
|
if (negEffects[nStr].length() > 1) {
|
||||||
|
negEffects[nStr] = InputPayManaCostUtil.getShortColorString(negEffects[nStr]);
|
||||||
|
}
|
||||||
|
// make mana mandatory for AI
|
||||||
|
if (!cost.isColor(negEffects[nStr])) {
|
||||||
|
cost.combineManaCost(negEffects[nStr]);
|
||||||
|
amountAdded++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cost.setManaNeededToAvoidNegativeEffect(negEffects);
|
||||||
|
//TODO: should it be an error condition if amountAdded is greater than the colorless
|
||||||
|
// in the original cost? (ArsenalNut - 120102)
|
||||||
|
// adjust colorless amount to account for added mana
|
||||||
|
cost.decreaseColorlessMana(amountAdded);
|
||||||
}
|
}
|
||||||
|
|
||||||
final CardList manaSources = ComputerUtil.getAvailableMana();
|
// get map of mana abilities
|
||||||
|
HashMap<String, ArrayList<AbilityMana>> manaAbilityMap = mapManaSources(player);
|
||||||
// this is to prevent errors for mana sources that have abilities that
|
// initialize ArrayList list for mana needed
|
||||||
// cost mana.
|
ArrayList<ArrayList<AbilityMana>> partSources =
|
||||||
manaSources.remove(sa.getSourceCard());
|
new ArrayList<ArrayList<AbilityMana>>();
|
||||||
|
ArrayList<Integer> partPriority = new ArrayList<Integer>();
|
||||||
for (int i = 0; i < manaSources.size(); i++) {
|
String[] costParts = cost.toString().replace("X ", "").replace("P", "").split(" ");
|
||||||
final Card sourceCard = manaSources.get(i);
|
Boolean foundAllSources = true;
|
||||||
ArrayList<AbilityMana> manaAbilities = sourceCard.getAIPlayableMana();
|
if (manaAbilityMap.isEmpty()) {
|
||||||
|
foundAllSources = false;
|
||||||
boolean used = false; // this is for testing paying mana only
|
|
||||||
|
|
||||||
manaAbilities = ComputerUtil.sortForNeeded(cost, manaAbilities, player);
|
|
||||||
|
|
||||||
for (final AbilityMana m : manaAbilities) {
|
|
||||||
|
|
||||||
if (used) {
|
|
||||||
break; // mana source already used in the test
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
String[] shortColors = {"W", "U", "B" , "R", "G"};
|
||||||
|
// loop over cost parts
|
||||||
|
for (int nPart = 0; nPart < costParts.length; nPart++) {
|
||||||
|
ArrayList<AbilityMana> srcFound = new ArrayList<AbilityMana>();
|
||||||
|
// Test for:
|
||||||
|
// 1) Colorless
|
||||||
|
// 2) Split e.g. 2/G
|
||||||
|
// 3) Hybrid e.g. UG
|
||||||
|
// defaults to single short color
|
||||||
|
if (costParts[nPart].matches("[0-9]+")) { // Colorless
|
||||||
|
srcFound.addAll(manaAbilityMap.get("1"));
|
||||||
|
}
|
||||||
|
else if (costParts[nPart].contains("/")) { // Split
|
||||||
|
String colorKey = costParts[nPart].replace("2/", "");
|
||||||
|
// add specified color sources first
|
||||||
|
if (manaAbilityMap.containsKey(colorKey)) {
|
||||||
|
srcFound.addAll(manaAbilityMap.get(colorKey));
|
||||||
|
}
|
||||||
|
// add other available colors
|
||||||
|
for (String color : shortColors) {
|
||||||
|
if (!colorKey.contains(color)) {
|
||||||
|
// Is source available?
|
||||||
|
if (manaAbilityMap.containsKey(color)) {
|
||||||
|
srcFound.addAll(manaAbilityMap.get(color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (costParts[nPart].length() > 1) { // Hybrid
|
||||||
|
String firstColor = costParts[nPart].substring(0, 1);
|
||||||
|
String secondColor = costParts[nPart].substring(1);
|
||||||
|
Boolean foundFirst = manaAbilityMap.containsKey(firstColor);
|
||||||
|
Boolean foundSecond = manaAbilityMap.containsKey(secondColor);
|
||||||
|
if (foundFirst || foundSecond) {
|
||||||
|
if (!foundFirst) {
|
||||||
|
srcFound.addAll(manaAbilityMap.get(secondColor));
|
||||||
|
}
|
||||||
|
else if (!foundSecond) {
|
||||||
|
srcFound.addAll(manaAbilityMap.get(firstColor));
|
||||||
|
}
|
||||||
|
else if (manaAbilityMap.get(firstColor).size() > manaAbilityMap.get(secondColor).size()) {
|
||||||
|
srcFound.addAll(manaAbilityMap.get(firstColor));
|
||||||
|
srcFound.addAll(manaAbilityMap.get(secondColor));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
srcFound.addAll(manaAbilityMap.get(secondColor));
|
||||||
|
srcFound.addAll(manaAbilityMap.get(firstColor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // single color
|
||||||
|
if (manaAbilityMap.containsKey(costParts[nPart])) {
|
||||||
|
srcFound.addAll(manaAbilityMap.get(costParts[nPart]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add sources to array lists
|
||||||
|
partSources.add(nPart, srcFound);
|
||||||
|
// add to sorted priority list
|
||||||
|
if (srcFound.size() > 0) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < partPriority.size(); i++) {
|
||||||
|
if (srcFound.size() < partSources.get(i).size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
partPriority.add(i, nPart);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
foundAllSources = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundAllSources) {
|
||||||
|
if (!test) {
|
||||||
|
// real payment should not arrive here
|
||||||
|
throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for " + sa.getSourceCard().getName());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create array to keep track of sources used
|
||||||
|
ArrayList<Card> usedSources = new ArrayList<Card>();
|
||||||
|
//this is to prevent errors for mana sources that have abilities that cost mana.
|
||||||
|
usedSources.add(sa.getSourceCard());
|
||||||
|
// Loop over mana needed
|
||||||
|
int nPriority = 0;
|
||||||
|
while (nPriority < partPriority.size()) {
|
||||||
|
int nPart = partPriority.get(nPriority);
|
||||||
|
ArrayList<AbilityMana> manaAbilities = partSources.get(nPart);
|
||||||
|
ManaCost costPart = new ManaCost(costParts[nPart]);
|
||||||
|
// Loop over mana abilities that can be used to current mana cost part
|
||||||
|
for (AbilityMana m : manaAbilities) {
|
||||||
|
Card sourceCard = m.getSourceCard();
|
||||||
|
|
||||||
|
// Check if source has already been used
|
||||||
|
if (usedSources.contains(sourceCard)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if AI can still play this mana ability
|
||||||
m.setActivatingPlayer(player);
|
m.setActivatingPlayer(player);
|
||||||
// if the AI can't pay the additional costs skip the mana
|
//if the AI can't pay the additional costs skip the mana ability
|
||||||
// ability
|
|
||||||
if (m.getPayCosts() != null) {
|
if (m.getPayCosts() != null) {
|
||||||
if (!ComputerUtil.canPayAdditionalCosts(m, player)) {
|
if (!canPayAdditionalCosts(m, player)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (sourceCard.isTapped()) {
|
} else if (sourceCard.isTapped()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't use abilities with dangerous drawbacks
|
// add source card to used list
|
||||||
if (m.getSubAbility() != null) {
|
usedSources.add(sourceCard);
|
||||||
if (!m.getSubAbility().chkAIDrawback()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
colors = ComputerUtil.getProduceableColors(m, player);
|
// add source card to used list
|
||||||
for (int j = 0; j < colors.size(); j++) {
|
|
||||||
if (used) {
|
|
||||||
break; // mana source already used in the test
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.isNeeded(colors.get(j))) {
|
|
||||||
if (!test) {
|
if (!test) {
|
||||||
// Pay additional costs
|
//Pay additional costs
|
||||||
if (m.getPayCosts() != null) {
|
if (m.getPayCosts() != null) {
|
||||||
final CostPayment pay = new CostPayment(m.getPayCosts(), m);
|
CostPayment pay = new CostPayment(m.getPayCosts(), m);
|
||||||
if (!pay.payComputerCosts()) {
|
if (!pay.payComputerCosts()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
sourceCard.tap();
|
sourceCard.tap();
|
||||||
}
|
}
|
||||||
} else {
|
// resolve mana ability
|
||||||
used = true; // mana source is now used in the test
|
m.resolve();
|
||||||
|
// subtract mana from mana pool
|
||||||
|
cost = manapool.subtractMana(sa, cost, m);
|
||||||
|
String manaProduced;
|
||||||
|
// Check if paying snow mana
|
||||||
|
if ("S".equals(costParts[nPart])) {
|
||||||
|
manaProduced = "S";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
manaProduced = m.getLastProduced();
|
||||||
|
}
|
||||||
|
String color = InputPayManaCostUtil.getLongColorString(manaProduced);
|
||||||
|
costPart.payMana(color);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String manaProduced;
|
||||||
|
// Check if paying snow mana
|
||||||
|
if ("S".equals(costParts[nPart])) {
|
||||||
|
manaProduced = "S";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// check if ability produces any color
|
||||||
|
if (m.isAnyMana()) {
|
||||||
|
String colorChoice = costParts[nPart];
|
||||||
|
ArrayList<String> negEffect = cost.getManaNeededToAvoidNegativeEffect();
|
||||||
|
ArrayList<String> negEffectPaid = cost.getManaPaidToAvoidNegativeEffect();
|
||||||
|
// Check for
|
||||||
|
// 1) Colorless
|
||||||
|
// 2) Split e.g. 2/G
|
||||||
|
// 3) Hybrid e.g. UG
|
||||||
|
if (costParts[nPart].matches("[0-9]+")) {
|
||||||
|
colorChoice = "W";
|
||||||
|
for (int n = 0; n < negEffect.size(); n++) {
|
||||||
|
if (!negEffectPaid.contains(negEffect.get(n))) {
|
||||||
|
colorChoice = negEffect.get(n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (costParts[nPart].contains("/")) {
|
||||||
|
colorChoice = costParts[nPart].replace("2/", "");
|
||||||
|
}
|
||||||
|
else if (costParts[nPart].length() > 1) {
|
||||||
|
colorChoice = costParts[nPart].substring(0, 1);
|
||||||
|
for (int n = 0; n < negEffect.size(); n++) {
|
||||||
|
if (costParts[nPart].contains(negEffect.get(n))
|
||||||
|
&& !negEffectPaid.contains(negEffect.get(n))) {
|
||||||
|
colorChoice = negEffect.get(n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.setAnyChoice(colorChoice);
|
||||||
|
}
|
||||||
|
// get produced mana
|
||||||
|
//TODO: Change this if AI is able use to mana abilities that
|
||||||
|
// produce more than one mana (111230 - ArsenalNut)
|
||||||
|
manaProduced = m.getManaProduced();
|
||||||
|
}
|
||||||
|
// pay cost
|
||||||
|
String color = InputPayManaCostUtil.getLongColorString(manaProduced);
|
||||||
|
cost.payMana(color);
|
||||||
|
costPart.payMana(color);
|
||||||
|
}
|
||||||
|
// check if cost part is paid
|
||||||
|
if (costPart.isPaid()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // end of mana ability loop
|
||||||
|
if (!costPart.isPaid() || cost.isPaid()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nPriority++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cost.payMana(colors.get(j));
|
} // end of cost parts loop
|
||||||
|
|
||||||
if (!test) {
|
// check if paid
|
||||||
// resolve subabilities
|
|
||||||
final AbilityFactory af = m.getAbilityFactory();
|
|
||||||
if (af != null) {
|
|
||||||
AbilityFactory.resolveSubAbilities(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourceCard.getName().equals("Undiscovered Paradise")) {
|
|
||||||
sourceCard.setBounceAtUntap(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourceCard.getName().equals("Rainbow Vale")) {
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("An opponent gains control of CARDNAME ");
|
|
||||||
sb.append("at the beginning of the next end step.");
|
|
||||||
sourceCard.addExtrinsicKeyword(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.println("just subtracted " +
|
|
||||||
// colors.get(j) + ", cost is now: " +
|
|
||||||
// cost.toString());
|
|
||||||
// Run triggers
|
|
||||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
|
||||||
|
|
||||||
runParams.put("Card", sourceCard);
|
|
||||||
runParams.put("Player", player);
|
|
||||||
runParams.put("Produced", colors.get(j)); // can't
|
|
||||||
// tell
|
|
||||||
// what
|
|
||||||
// mana
|
|
||||||
// the
|
|
||||||
// computer
|
|
||||||
// just
|
|
||||||
// paid?
|
|
||||||
AllZone.getTriggerHandler().runTrigger("TapsForMana", runParams);
|
|
||||||
} // not a test
|
|
||||||
}
|
|
||||||
if (cost.isPaid()) {
|
if (cost.isPaid()) {
|
||||||
// if (sa instanceof Spell_Permanent) // should probably
|
//if (sa instanceof Spell_Permanent) // should probably add this
|
||||||
// add this
|
|
||||||
sa.getSourceCard().setColorsPaid(cost.getColorsPaid());
|
sa.getSourceCard().setColorsPaid(cost.getColorsPaid());
|
||||||
sa.getSourceCard().setSunburstValue(cost.getSunburst());
|
sa.getSourceCard().setSunburstValue(cost.getSunburst());
|
||||||
manapool.clearPay(sa, test);
|
manapool.clearPay(sa, test);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!test) {
|
if (!test) {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
@@ -790,6 +925,7 @@ public class ComputerUtil {
|
|||||||
return ComputerUtil.getAvailableMana(AllZone.getComputerPlayer());
|
return ComputerUtil.getAvailableMana(AllZone.getComputerPlayer());
|
||||||
} // getAvailableMana()
|
} // getAvailableMana()
|
||||||
|
|
||||||
|
|
||||||
// gets available mana sources and sorts them
|
// gets available mana sources and sorts them
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -817,22 +953,40 @@ public class ComputerUtil {
|
|||||||
}); // CardListFilter
|
}); // CardListFilter
|
||||||
|
|
||||||
final CardList sortedManaSources = new CardList();
|
final CardList sortedManaSources = new CardList();
|
||||||
|
final CardList otherManaSources = new CardList();
|
||||||
|
final CardList colorlessManaSources = new CardList();
|
||||||
|
final CardList oneManaSources = new CardList();
|
||||||
|
final CardList twoManaSources = new CardList();
|
||||||
|
final CardList threeManaSources = new CardList();
|
||||||
|
final CardList fourManaSources = new CardList();
|
||||||
|
final CardList fiveManaSources = new CardList();
|
||||||
|
final CardList anyColorManaSources = new CardList();
|
||||||
|
|
||||||
|
// Sort mana sources
|
||||||
// 1. Use lands that can only produce colorless mana without
|
// 1. Use lands that can only produce colorless mana without
|
||||||
// drawback/cost first
|
// drawback/cost first
|
||||||
|
// 2. Search for mana sources that have a certain number of abilities
|
||||||
|
// 3. Use lands that produce any color many
|
||||||
|
// 4. all other sources (creature, costs, drawback, etc.)
|
||||||
for (int i = 0; i < manaSources.size(); i++) {
|
for (int i = 0; i < manaSources.size(); i++) {
|
||||||
final Card card = manaSources.get(i);
|
final Card card = manaSources.get(i);
|
||||||
|
|
||||||
if (card.isCreature() || card.isEnchanted()) {
|
if (card.isCreature() || card.isEnchanted()) {
|
||||||
|
otherManaSources.add(card);
|
||||||
continue; // don't use creatures before other permanents
|
continue; // don't use creatures before other permanents
|
||||||
}
|
}
|
||||||
|
|
||||||
int usableManaAbilities = 0;
|
int usableManaAbilities = 0;
|
||||||
boolean needsLimitedResources = false;
|
boolean needsLimitedResources = false;
|
||||||
|
boolean producesAnyColor = false;
|
||||||
final ArrayList<AbilityMana> manaAbilities = card.getAIPlayableMana();
|
final ArrayList<AbilityMana> manaAbilities = card.getAIPlayableMana();
|
||||||
|
|
||||||
for (final AbilityMana m : manaAbilities) {
|
for (final AbilityMana m : manaAbilities) {
|
||||||
|
|
||||||
|
if (m.isAnyMana()) {
|
||||||
|
producesAnyColor = true;
|
||||||
|
}
|
||||||
|
|
||||||
final Cost cost = m.getPayCosts();
|
final Cost cost = m.getPayCosts();
|
||||||
needsLimitedResources |= !cost.isReusuableResource();
|
needsLimitedResources |= !cost.isReusuableResource();
|
||||||
|
|
||||||
@@ -856,61 +1010,42 @@ public class ComputerUtil {
|
|||||||
usableManaAbilities++;
|
usableManaAbilities++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use lands that can only produce colorless mana first
|
if (needsLimitedResources) {
|
||||||
if ((usableManaAbilities == 1) && !needsLimitedResources && manaAbilities.get(0).mana().equals("1")) {
|
otherManaSources.add(card);
|
||||||
sortedManaSources.add(card);
|
|
||||||
}
|
}
|
||||||
|
else if (producesAnyColor) {
|
||||||
|
anyColorManaSources.add(card);
|
||||||
|
}
|
||||||
|
else if (usableManaAbilities == 1) {
|
||||||
|
if (manaAbilities.get(0).mana().equals("1")) {
|
||||||
|
colorlessManaSources.add(card);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oneManaSources.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (usableManaAbilities == 2) {
|
||||||
|
twoManaSources.add(card);
|
||||||
|
}
|
||||||
|
else if (usableManaAbilities == 3) {
|
||||||
|
threeManaSources.add(card);
|
||||||
|
}
|
||||||
|
else if (usableManaAbilities == 4) {
|
||||||
|
fourManaSources.add(card);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fiveManaSources.add(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Search for mana sources that have a certain number of mana
|
|
||||||
// abilities (start with 1 and go up to 5) and no drawback/costs
|
|
||||||
for (int number = 1; number < 6; number++) {
|
|
||||||
for (int i = 0; i < manaSources.size(); i++) {
|
|
||||||
final Card card = manaSources.get(i);
|
|
||||||
|
|
||||||
if (card.isCreature() || card.isEnchanted()) {
|
|
||||||
continue; // don't use creatures before other permanents
|
|
||||||
}
|
|
||||||
|
|
||||||
int usableManaAbilities = 0;
|
|
||||||
boolean needsLimitedResources = false;
|
|
||||||
final ArrayList<AbilityMana> manaAbilities = card.getAIPlayableMana();
|
|
||||||
|
|
||||||
for (final AbilityMana m : manaAbilities) {
|
|
||||||
|
|
||||||
final Cost cost = m.getPayCosts();
|
|
||||||
needsLimitedResources |= !cost.isReusuableResource();
|
|
||||||
// if the AI can't pay the additional costs skip the mana
|
|
||||||
// ability
|
|
||||||
if (cost != null) {
|
|
||||||
if (!ComputerUtil.canPayAdditionalCosts(m, player)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't use abilities with dangerous drawbacks
|
|
||||||
if (m.getSubAbility() != null) {
|
|
||||||
if (!m.getSubAbility().chkAIDrawback()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
needsLimitedResources = true; // TODO: check for good
|
|
||||||
// drawbacks (gainLife)
|
|
||||||
}
|
|
||||||
usableManaAbilities++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((usableManaAbilities == number) && !needsLimitedResources && !sortedManaSources.contains(card)) {
|
|
||||||
sortedManaSources.add(card);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the rest
|
|
||||||
for (int j = 0; j < manaSources.size(); j++) {
|
|
||||||
if (!sortedManaSources.contains(manaSources.get(j))) {
|
|
||||||
sortedManaSources.add(manaSources.get(j));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
sortedManaSources.addAll(colorlessManaSources);
|
||||||
|
sortedManaSources.addAll(oneManaSources);
|
||||||
|
sortedManaSources.addAll(twoManaSources);
|
||||||
|
sortedManaSources.addAll(threeManaSources);
|
||||||
|
sortedManaSources.addAll(fourManaSources);
|
||||||
|
sortedManaSources.addAll(fiveManaSources);
|
||||||
|
sortedManaSources.addAll(anyColorManaSources);
|
||||||
|
sortedManaSources.addAll(otherManaSources);
|
||||||
|
|
||||||
return sortedManaSources;
|
return sortedManaSources;
|
||||||
} // getAvailableMana()
|
} // getAvailableMana()
|
||||||
@@ -983,7 +1118,93 @@ public class ComputerUtil {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// plays a land if one is available
|
/**
|
||||||
|
* <p>mapManaSources.</p>
|
||||||
|
*
|
||||||
|
* @param player a {@link forge.Player} object.
|
||||||
|
* @return HashMap<String, CardList>
|
||||||
|
*/
|
||||||
|
public static HashMap<String, ArrayList<AbilityMana>> mapManaSources(final Player player) {
|
||||||
|
HashMap<String, ArrayList<AbilityMana>> manaMap = new HashMap<String, ArrayList<AbilityMana>>();
|
||||||
|
|
||||||
|
ArrayList<AbilityMana> whiteSources = new ArrayList<AbilityMana>();
|
||||||
|
ArrayList<AbilityMana> blueSources = new ArrayList<AbilityMana>();
|
||||||
|
ArrayList<AbilityMana> blackSources = new ArrayList<AbilityMana>();
|
||||||
|
ArrayList<AbilityMana> redSources = new ArrayList<AbilityMana>();
|
||||||
|
ArrayList<AbilityMana> greenSources = new ArrayList<AbilityMana>();
|
||||||
|
ArrayList<AbilityMana> colorlessSources = new ArrayList<AbilityMana>();
|
||||||
|
ArrayList<AbilityMana> snowSources = new ArrayList<AbilityMana>();
|
||||||
|
|
||||||
|
// Get list of current available mana sources
|
||||||
|
final CardList manaSources = ComputerUtil.getAvailableMana();
|
||||||
|
|
||||||
|
// Loop over all mana sources
|
||||||
|
for (int i = 0; i < manaSources.size(); i++) {
|
||||||
|
Card sourceCard = manaSources.get(i);
|
||||||
|
ArrayList<AbilityMana> manaAbilities = sourceCard.getAIPlayableMana();
|
||||||
|
|
||||||
|
// Loop over all mana abilities for a source
|
||||||
|
for (AbilityMana m : manaAbilities) {
|
||||||
|
|
||||||
|
//don't use abilities with dangerous drawbacks
|
||||||
|
if (m.getSubAbility() != null) {
|
||||||
|
if (!m.getSubAbility().chkAIDrawback()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to colorless source list
|
||||||
|
colorlessSources.add(m);
|
||||||
|
|
||||||
|
// find possible colors
|
||||||
|
if (m.canProduce("W") || m.isAnyMana()) {
|
||||||
|
whiteSources.add(m);
|
||||||
|
}
|
||||||
|
if (m.canProduce("U") || m.isAnyMana()) {
|
||||||
|
blueSources.add(m);
|
||||||
|
}
|
||||||
|
if (m.canProduce("B") || m.isAnyMana()) {
|
||||||
|
blackSources.add(m);
|
||||||
|
}
|
||||||
|
if (m.canProduce("R") || m.isAnyMana()) {
|
||||||
|
redSources.add(m);
|
||||||
|
}
|
||||||
|
if (m.canProduce("G") || m.isAnyMana()) {
|
||||||
|
greenSources.add(m);
|
||||||
|
}
|
||||||
|
if (m.isSnow()) {
|
||||||
|
snowSources.add(m);
|
||||||
|
}
|
||||||
|
} // end of mana abilities loop
|
||||||
|
} // end of mana sources loop
|
||||||
|
|
||||||
|
// Add sources
|
||||||
|
if (!whiteSources.isEmpty()) {
|
||||||
|
manaMap.put("W", whiteSources);
|
||||||
|
}
|
||||||
|
if (!blueSources.isEmpty()) {
|
||||||
|
manaMap.put("U", blueSources);
|
||||||
|
}
|
||||||
|
if (!blackSources.isEmpty()) {
|
||||||
|
manaMap.put("B", blackSources);
|
||||||
|
}
|
||||||
|
if (!redSources.isEmpty()) {
|
||||||
|
manaMap.put("R", redSources);
|
||||||
|
}
|
||||||
|
if (!greenSources.isEmpty()) {
|
||||||
|
manaMap.put("G", greenSources);
|
||||||
|
}
|
||||||
|
if (!colorlessSources.isEmpty()) {
|
||||||
|
manaMap.put("1", colorlessSources);
|
||||||
|
}
|
||||||
|
if (!snowSources.isEmpty()) {
|
||||||
|
manaMap.put("S", snowSources);
|
||||||
|
}
|
||||||
|
|
||||||
|
return manaMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//plays a land if one is available
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* chooseLandsToPlay.
|
* chooseLandsToPlay.
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import forge.Constant.Zone;
|
|||||||
import forge.Counters;
|
import forge.Counters;
|
||||||
import forge.MyRandom;
|
import forge.MyRandom;
|
||||||
import forge.Player;
|
import forge.Player;
|
||||||
|
import forge.card.cardfactory.CardFactoryUtil;
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.AbilityActivated;
|
import forge.card.spellability.AbilityActivated;
|
||||||
import forge.card.spellability.AbilityMana;
|
import forge.card.spellability.AbilityMana;
|
||||||
@@ -85,6 +86,10 @@ public class AbilityFactoryMana {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getManaProduced() {
|
||||||
|
return manaGenerated(this, this.af, this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return abMana;
|
return abMana;
|
||||||
}
|
}
|
||||||
@@ -242,6 +247,18 @@ public class AbilityFactoryMana {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>manaGenerated.</p>
|
||||||
|
*
|
||||||
|
* @param abMana a {@link forge.card.spellability.Ability_Mana} object.
|
||||||
|
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
|
||||||
|
* @param sa a {@link forge.card.spellability.SpellAbility} object.
|
||||||
|
* @return a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public static String manaGenerated(final AbilityMana abMana, final AbilityFactory af, final SpellAbility sa) {
|
||||||
|
return generatedMana(abMana, af, sa);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* manaResolve.
|
* manaResolve.
|
||||||
@@ -277,6 +294,40 @@ public class AbilityFactoryMana {
|
|||||||
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa);
|
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abMana.isAnyMana()) {
|
||||||
|
for (Player p : tgtPlayers) {
|
||||||
|
if (tgt == null || p.canBeTargetedBy(sa)) {
|
||||||
|
// AI color choice is set in ComputerUtils so only human players need to make a choice
|
||||||
|
if (sa.getActivatingPlayer().isHuman()) {
|
||||||
|
Object o = GuiUtils.getChoice("Choose a color", Constant.Color.ONLY_COLORS);
|
||||||
|
if (null == o) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String choice = (String) o;
|
||||||
|
abMana.setAnyChoice(InputPayManaCostUtil.getShortColorString(choice));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (params.containsKey("AILogic")) {
|
||||||
|
final String logic = params.get("AILogic");
|
||||||
|
String chosen = Constant.Color.BLACK;
|
||||||
|
if (logic.equals("MostProminentInComputerHand")) {
|
||||||
|
chosen = CardFactoryUtil.getMostProminentColor(AllZone.getComputerPlayer().getCardsIn(
|
||||||
|
Zone.Hand));
|
||||||
|
}
|
||||||
|
GuiUtils.getChoice("Computer picked: ", chosen);
|
||||||
|
abMana.setAnyChoice(InputPayManaCostUtil.getShortColorString(chosen));
|
||||||
|
}
|
||||||
|
if (abMana.getAnyChoice().isEmpty()) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("AbilityFactoryMana::manaResolve() - any color mana choice is empty for ");
|
||||||
|
sb.append(sa.getSourceCard().getName());
|
||||||
|
throw new RuntimeException(sb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (final Player player : tgtPlayers) {
|
for (final Player player : tgtPlayers) {
|
||||||
abMana.produceMana(AbilityFactoryMana.generatedMana(abMana, af, sa), player);
|
abMana.produceMana(AbilityFactoryMana.generatedMana(abMana, af, sa), player);
|
||||||
}
|
}
|
||||||
@@ -319,7 +370,16 @@ public class AbilityFactoryMana {
|
|||||||
int amount = params.containsKey("Amount") ? AbilityFactory.calculateAmount(af.getHostCard(),
|
int amount = params.containsKey("Amount") ? AbilityFactory.calculateAmount(af.getHostCard(),
|
||||||
params.get("Amount"), sa) : 1;
|
params.get("Amount"), sa) : 1;
|
||||||
|
|
||||||
String baseMana = abMana.mana();
|
String baseMana;
|
||||||
|
if (abMana.isAnyMana()) {
|
||||||
|
baseMana = abMana.getAnyChoice();
|
||||||
|
if (baseMana.isEmpty()) {
|
||||||
|
baseMana = "Any";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baseMana = abMana.mana();
|
||||||
|
}
|
||||||
|
|
||||||
if (baseMana.equals("Chosen")) {
|
if (baseMana.equals("Chosen")) {
|
||||||
// this will only support 1 chosen color for now.
|
// this will only support 1 chosen color for now.
|
||||||
baseMana = InputPayManaCostUtil.getShortColorString(card.getChosenColor().get(0));
|
baseMana = InputPayManaCostUtil.getShortColorString(card.getChosenColor().get(0));
|
||||||
@@ -684,7 +744,7 @@ public class AbilityFactoryMana {
|
|||||||
final ArrayList<String> colors) {
|
final ArrayList<String> colors) {
|
||||||
for (final String col : Constant.Color.ONLY_COLORS) {
|
for (final String col : Constant.Color.ONLY_COLORS) {
|
||||||
final String s = InputPayManaCostUtil.getShortColorString(col);
|
final String s = InputPayManaCostUtil.getShortColorString(col);
|
||||||
if (ab.canProduce(s) && !colors.contains(col)) {
|
if ((ab.canProduce(s) || ab.isAnyMana()) && !colors.contains(col)) {
|
||||||
colors.add(col);
|
colors.add(col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,4 +246,15 @@ public class Mana {
|
|||||||
public final void decrementAmount() {
|
public final void decrementAmount() {
|
||||||
this.amount--;
|
this.amount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* decrementAmount.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param amountDecrement a int.
|
||||||
|
*/
|
||||||
|
public void decrementAmount(final int amountDecrement) {
|
||||||
|
this.amount -= amountDecrement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -704,4 +704,13 @@ public class ManaCost {
|
|||||||
public final ArrayList<String> getManaNeededToAvoidNegativeEffect() {
|
public final ArrayList<String> getManaNeededToAvoidNegativeEffect() {
|
||||||
return this.manaNeededToAvoidNegativeEffect;
|
return this.manaNeededToAvoidNegativeEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the mana paid so far to avoid negative effect.
|
||||||
|
*
|
||||||
|
* @return the mana paid to avoid negative effect
|
||||||
|
*/
|
||||||
|
public final ArrayList<String> getManaPaidToAvoidNegativeEffect() {
|
||||||
|
return this.manaPaidToAvoidNegativeEffect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ public class ManaPool {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.removeManaFrom(pool, set);
|
this.removeManaFrom(pool, set, mana.getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -510,21 +510,23 @@ public class ManaPool {
|
|||||||
* a {@link java.util.ArrayList} object.
|
* a {@link java.util.ArrayList} object.
|
||||||
* @param choice
|
* @param choice
|
||||||
* a {@link forge.card.mana.Mana} object.
|
* a {@link forge.card.mana.Mana} object.
|
||||||
|
* @param amount
|
||||||
|
* an int .
|
||||||
*/
|
*/
|
||||||
public final void removeManaFrom(final ArrayList<Mana> pool, final Mana choice) {
|
public final void removeManaFrom(final ArrayList<Mana> pool, final Mana choice, final int amount) {
|
||||||
if (choice != null) {
|
if (choice != null) {
|
||||||
if (choice.getAmount() == 1) {
|
if (choice.getAmount() == amount) {
|
||||||
pool.remove(choice);
|
pool.remove(choice);
|
||||||
} else {
|
} else {
|
||||||
choice.decrementAmount();
|
choice.decrementAmount(amount);
|
||||||
}
|
}
|
||||||
if (pool.equals(this.floatingMana)) {
|
if (pool.equals(this.floatingMana)) {
|
||||||
int i = ManaPool.MAP.get(choice.getColor());
|
int i = ManaPool.MAP.get(choice.getColor());
|
||||||
if (choice.isSnow()) {
|
if (choice.isSnow()) {
|
||||||
this.floatingSnowTotals[i] -= choice.getAmount();
|
this.floatingSnowTotals[i] -= amount;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.floatingTotals[i] -= choice.getAmount();
|
this.floatingTotals[i] -= amount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
owner.updateObservers();
|
owner.updateObservers();
|
||||||
@@ -685,7 +687,7 @@ public class ManaPool {
|
|||||||
* @return a {@link forge.card.mana.ManaCost} object.
|
* @return a {@link forge.card.mana.ManaCost} object.
|
||||||
*/
|
*/
|
||||||
public final ManaCost subtractMana(final SpellAbility sa, ManaCost m, final AbilityMana... mAbilities) {
|
public final ManaCost subtractMana(final SpellAbility sa, ManaCost m, final AbilityMana... mAbilities) {
|
||||||
final ArrayList<AbilityMana> paidAbs = sa.getPayingManaAbilities();
|
final ArrayList<AbilityMana> paidAbs = sa.getPayingManaAbilities(); // why???
|
||||||
|
|
||||||
if (mAbilities.length == 0) {
|
if (mAbilities.length == 0) {
|
||||||
// paying from Mana Pool
|
// paying from Mana Pool
|
||||||
@@ -699,8 +701,17 @@ public class ManaPool {
|
|||||||
|
|
||||||
// paying via Mana Abilities
|
// paying via Mana Abilities
|
||||||
for (final AbilityMana mability : mAbilities) {
|
for (final AbilityMana mability : mAbilities) {
|
||||||
paidAbs.add(mability);
|
paidAbs.add(mability); // why???
|
||||||
final String[] cost = ManaPool.formatMana(mability);
|
//TODO: Look at using new getManaProduced() method of Ability_Mana (ArsenalNut)
|
||||||
|
//String[] cost = formatMana(mability);
|
||||||
|
String[] cost = null;
|
||||||
|
if (mability.isAnyMana()) {
|
||||||
|
cost = new String[1];
|
||||||
|
cost[0] = mability.getAnyChoice();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cost = formatMana(mability);
|
||||||
|
}
|
||||||
m = this.subtractMultiple(sa, cost, m);
|
m = this.subtractMultiple(sa, cost, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +749,7 @@ public class ManaPool {
|
|||||||
for (final Mana m : manaArray) {
|
for (final Mana m : manaArray) {
|
||||||
if (manaCost.isNeeded(m)) {
|
if (manaCost.isNeeded(m)) {
|
||||||
manaCost.payMana(m);
|
manaCost.payMana(m);
|
||||||
payMana.add(m);
|
payMana.add(m); // what is this used for? anything
|
||||||
this.findAndRemoveFrom(this.floatingMana, m);
|
this.findAndRemoveFrom(this.floatingMana, m);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -806,74 +817,77 @@ public class ManaPool {
|
|||||||
// TODO account for unpaying mana in payMana and floatingPool
|
// TODO account for unpaying mana in payMana and floatingPool
|
||||||
final ArrayList<Mana> payMana = sa.getPayingMana();
|
final ArrayList<Mana> payMana = sa.getPayingMana();
|
||||||
|
|
||||||
|
if ((payMana.size() == 0) && (this.floatingMana.size() == 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
final ArrayList<Mana> removePaying = new ArrayList<Mana>();
|
final ArrayList<Mana> removePaying = new ArrayList<Mana>();
|
||||||
final ArrayList<Mana> removeFloating = new ArrayList<Mana>();
|
final ArrayList<Mana> removeFloating = new ArrayList<Mana>();
|
||||||
|
|
||||||
int i = 0, j = 0;
|
int manaAccounted = 0;
|
||||||
boolean usePay = payMana.size() > 0;
|
// loop over mana paid
|
||||||
final boolean flag = false;
|
for (Mana manaPaid : payMana) {
|
||||||
|
if (manaPaid.fromSourceCard(c)) {
|
||||||
String manaStr = mana[i];
|
for (int i = 0; i < mana.length; i++) {
|
||||||
String color = InputPayManaCostUtil.getLongColorString(manaStr);
|
if (manaPaid.getColor().equals(InputPayManaCostUtil.getLongColorString(mana[i]))) {
|
||||||
|
final int amt = manaPaid.getColorlessAmount();
|
||||||
if (!usePay && (this.floatingMana.size() == 0)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i < mana.length) {
|
|
||||||
|
|
||||||
final Mana m = usePay ? payMana.get(j) : this.floatingMana.get(j);
|
|
||||||
|
|
||||||
if (m.fromSourceCard(c) && m.getColor().equals(color)) {
|
|
||||||
final int amt = m.getColorlessAmount();
|
|
||||||
if (amt > 0) {
|
if (amt > 0) {
|
||||||
final int difference = Integer.parseInt(manaStr) - amt;
|
final int difference = Integer.parseInt(mana[i]) - amt;
|
||||||
if (difference > 0) {
|
if (difference > 0) {
|
||||||
manaStr = Integer.toString(difference);
|
mana[i] = Integer.toString(difference);
|
||||||
} else {
|
} else {
|
||||||
i += amt;
|
manaAccounted += amt;
|
||||||
if (i < mana.length) {
|
|
||||||
manaStr = mana[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
i += m.getAmount();
|
manaAccounted += manaPaid.getAmount();
|
||||||
if (i < mana.length) {
|
|
||||||
manaStr = mana[i];
|
|
||||||
}
|
}
|
||||||
}
|
removePaying.add(manaPaid);
|
||||||
color = InputPayManaCostUtil.getLongColorString(manaStr);
|
|
||||||
if (usePay) {
|
|
||||||
removePaying.add(m);
|
|
||||||
} else {
|
|
||||||
removeFloating.add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If mana has been depleted, break from loop. All Accounted
|
|
||||||
// for!
|
|
||||||
if (i == mana.length) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
j++; // increase j until we reach the end of paying, then reset and
|
if (manaAccounted == mana.length) {
|
||||||
// use floating.
|
break;
|
||||||
if (usePay) {
|
|
||||||
if (payMana.size() == j) {
|
|
||||||
j = 0;
|
|
||||||
usePay = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!usePay && (this.floatingMana.size() == j) && !flag) {
|
// loop over mana pool if not all of the generated mana is accounted for
|
||||||
|
if (manaAccounted < mana.length) {
|
||||||
|
for (Mana manaFloat : this.floatingMana) {
|
||||||
|
if (manaFloat.fromSourceCard(c)) {
|
||||||
|
for (int i = 0; i < mana.length; i++) {
|
||||||
|
if (manaFloat.getColor().equals(InputPayManaCostUtil.getLongColorString(mana[i]))) {
|
||||||
|
final int amt = manaFloat.getColorlessAmount();
|
||||||
|
if (amt > 0) {
|
||||||
|
final int difference = Integer.parseInt(mana[i]) - amt;
|
||||||
|
if (difference > 0) {
|
||||||
|
mana[i] = Integer.toString(difference);
|
||||||
|
} else {
|
||||||
|
manaAccounted += amt;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
manaAccounted += manaFloat.getAmount();
|
||||||
|
}
|
||||||
|
removeFloating.add(manaFloat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (manaAccounted == mana.length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// When is it legitimate for all the mana not to be accountable?
|
||||||
|
// Does this condition really indicate an bug in Forge?
|
||||||
|
if (manaAccounted < mana.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (int k = 0; k < removePaying.size(); k++) {
|
for (int k = 0; k < removePaying.size(); k++) {
|
||||||
this.removeManaFrom(payMana, removePaying.get(k));
|
this.removeManaFrom(payMana, removePaying.get(k), removePaying.get(k).getAmount());
|
||||||
}
|
}
|
||||||
for (int k = 0; k < removeFloating.size(); k++) {
|
for (int k = 0; k < removeFloating.size(); k++) {
|
||||||
this.removeManaFrom(this.floatingMana, removeFloating.get(k));
|
this.removeManaFrom(this.floatingMana, removeFloating.get(k), removeFloating.get(k).getAmount());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -896,7 +910,16 @@ public class ManaPool {
|
|||||||
// go through paidAbilities if they are undoable
|
// go through paidAbilities if they are undoable
|
||||||
for (final AbilityMana am : payAbs) {
|
for (final AbilityMana am : payAbs) {
|
||||||
if (am.isUndoable()) {
|
if (am.isUndoable()) {
|
||||||
final String[] formattedMana = ManaPool.formatMana(am);
|
//final String[] formattedMana = ManaPool.formatMana(am);
|
||||||
|
/*String[] formattedMana = null;
|
||||||
|
if (am.isAnyMana()) {
|
||||||
|
formattedMana = new String[1];
|
||||||
|
formattedMana[0] = am.getAnyChoice();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
formattedMana = formatMana(am);
|
||||||
|
}*/
|
||||||
|
final String[] formattedMana = am.getLastProduced().split(" ");
|
||||||
if (this.accountFor(sa, formattedMana, am.getSourceCard())) {
|
if (this.accountFor(sa, formattedMana, am.getSourceCard())) {
|
||||||
am.undo();
|
am.undo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se
|
|||||||
private static final long serialVersionUID = -6816356991224950520L;
|
private static final long serialVersionUID = -6816356991224950520L;
|
||||||
|
|
||||||
private String origProduced;
|
private String origProduced;
|
||||||
|
private String lastAnyChoice = "";
|
||||||
|
private String lastProduced = "";
|
||||||
private int amount = 1;
|
private int amount = 1;
|
||||||
|
|
||||||
/** The reflected. */
|
/** The reflected. */
|
||||||
@@ -177,6 +179,8 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se
|
|||||||
// this.getActivatingPlayer().ManaPool.addManaToFloating(origProduced,
|
// this.getActivatingPlayer().ManaPool.addManaToFloating(origProduced,
|
||||||
// getSourceCard());
|
// getSourceCard());
|
||||||
manaPool.addManaToFloating(produced, source);
|
manaPool.addManaToFloating(produced, source);
|
||||||
|
//store produced to last produced
|
||||||
|
this.lastProduced = produced;
|
||||||
|
|
||||||
// TODO all of the following would be better as trigger events
|
// TODO all of the following would be better as trigger events
|
||||||
// "tapped for mana"
|
// "tapped for mana"
|
||||||
@@ -202,6 +206,35 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se
|
|||||||
|
|
||||||
} // end produceMana(String)
|
} // end produceMana(String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* getProducedMana.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public String getManaProduced() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (this.amount == 0) {
|
||||||
|
sb.append("0");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
// if baseMana is an integer(colorless), just multiply amount and baseMana
|
||||||
|
int base = Integer.parseInt(this.origProduced);
|
||||||
|
sb.append(base * this.amount);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
for (int i = 0; i < this.amount; i++) {
|
||||||
|
if (i != 0) {
|
||||||
|
sb.append(" ");
|
||||||
|
}
|
||||||
|
sb.append(this.origProduced);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* mana.
|
* mana.
|
||||||
@@ -237,6 +270,39 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se
|
|||||||
this.reflected = bReflect;
|
this.reflected = bReflect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* setAnyChoice.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param s a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public void setAnyChoice(String s) {
|
||||||
|
this.lastAnyChoice = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Getter for the field <code>lastAnyChoice</code>.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public String getAnyChoice() {
|
||||||
|
return this.lastAnyChoice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Getter for the field <code>lastProduced</code>.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a {@link java.lang.String} object.
|
||||||
|
*/
|
||||||
|
public String getLastProduced() {
|
||||||
|
return this.lastProduced;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* isSnow.
|
* isSnow.
|
||||||
@@ -270,6 +336,17 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se
|
|||||||
return this.reflected;
|
return this.reflected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* isAnyMana.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public boolean isAnyMana() {
|
||||||
|
return this.origProduced.contains("Any");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* canProduce.
|
* canProduce.
|
||||||
@@ -280,6 +357,7 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean canProduce(final String s) {
|
public final boolean canProduce(final String s) {
|
||||||
|
//TODO: look at where this called from and take "Any" into account
|
||||||
return this.origProduced.contains(s);
|
return this.origProduced.contains(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,7 +369,7 @@ public abstract class AbilityMana extends AbilityActivated implements java.io.Se
|
|||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public final boolean isBasic() {
|
public final boolean isBasic() {
|
||||||
if (this.origProduced.length() != 1) {
|
if (this.origProduced.length() != 1 && !this.origProduced.contains("Any")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -231,7 +231,8 @@ public class BoosterDraftAI {
|
|||||||
final ArrayList<AbilityMana> maList = typeList.get(i).getManaAbility();
|
final ArrayList<AbilityMana> maList = typeList.get(i).getManaAbility();
|
||||||
for (int j = 0; j < maList.size(); j++) {
|
for (int j = 0; j < maList.size(); j++) {
|
||||||
if (maList.get(j).canProduce(this.playerColors.get(player).getMana1())
|
if (maList.get(j).canProduce(this.playerColors.get(player).getMana1())
|
||||||
|| maList.get(j).canProduce(this.playerColors.get(player).getMana2())) {
|
|| maList.get(j).canProduce(this.playerColors.get(player).getMana2())
|
||||||
|
|| maList.get(j).isAnyMana()) {
|
||||||
wouldPick.add(typeList.get(i));
|
wouldPick.add(typeList.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,7 +331,9 @@ public class SealedDeck {
|
|||||||
public boolean addCard(final Card c) {
|
public boolean addCard(final Card c) {
|
||||||
final ArrayList<AbilityMana> maList = c.getManaAbility();
|
final ArrayList<AbilityMana> maList = c.getManaAbility();
|
||||||
for (int j = 0; j < maList.size(); j++) {
|
for (int j = 0; j < maList.size(); j++) {
|
||||||
if (maList.get(j).canProduce(aiDC.mana1) || maList.get(j).canProduce(aiDC.mana2)) {
|
if (maList.get(j).canProduce(aiDC.mana1)
|
||||||
|
|| maList.get(j).canProduce(aiDC.mana2)
|
||||||
|
|| maList.get(j).isAnyMana()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,6 +119,8 @@ public class InputPayManaCostUtil {
|
|||||||
colorMatches.add(am);
|
colorMatches.add(am);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (am.isAnyMana()) {
|
||||||
|
colorMatches.add(am);
|
||||||
} else {
|
} else {
|
||||||
final String[] m = ManaPool.formatMana(am);
|
final String[] m = ManaPool.formatMana(am);
|
||||||
for (final String color : m) {
|
for (final String color : m) {
|
||||||
@@ -130,7 +132,8 @@ public class InputPayManaCostUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((colorMatches.size() == 0) || (colorMatches.size() == abilities.size())) {
|
// Why is choice made "false" if colorMatches and abilities have same size
|
||||||
|
if ((colorMatches.size() == 0)) {
|
||||||
// can only match colorless just grab the first and move on.
|
// can only match colorless just grab the first and move on.
|
||||||
choice = false;
|
choice = false;
|
||||||
} else if (colorMatches.size() < abilities.size()) {
|
} else if (colorMatches.size() < abilities.size()) {
|
||||||
@@ -211,7 +214,9 @@ public class InputPayManaCostUtil {
|
|||||||
if (mana.contains("S") && am.isSnow()) {
|
if (mana.contains("S") && am.isSnow()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (am.isAnyMana()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (am.isReflectedMana()) {
|
if (am.isReflectedMana()) {
|
||||||
final ArrayList<String> reflectableColors = AbilityFactoryMana.reflectableMana(am, am.getAbilityFactory(),
|
final ArrayList<String> reflectableColors = AbilityFactoryMana.reflectableMana(am, am.getAbilityFactory(),
|
||||||
new ArrayList<String>(), new ArrayList<Card>());
|
new ArrayList<String>(), new ArrayList<Card>());
|
||||||
|
|||||||
Reference in New Issue
Block a user