Update Maven plugins. Checkstyle

This commit is contained in:
jendave
2012-02-17 17:35:21 +00:00
parent a46a2c8308
commit eb5036e7c4
15 changed files with 968 additions and 322 deletions

3
.gitattributes vendored
View File

@@ -2122,6 +2122,7 @@ res/cardsfolder/d/desolation_angel.txt svneol=native#text/plain
res/cardsfolder/d/desolation_giant.txt svneol=native#text/plain res/cardsfolder/d/desolation_giant.txt svneol=native#text/plain
res/cardsfolder/d/desperate_charge.txt svneol=native#text/plain res/cardsfolder/d/desperate_charge.txt svneol=native#text/plain
res/cardsfolder/d/desperate_ravings.txt -text res/cardsfolder/d/desperate_ravings.txt -text
res/cardsfolder/d/desperate_ritual.txt svneol=native#text/plain
res/cardsfolder/d/despise.txt svneol=native#text/plain res/cardsfolder/d/despise.txt svneol=native#text/plain
res/cardsfolder/d/despoil.txt svneol=native#text/plain res/cardsfolder/d/despoil.txt svneol=native#text/plain
res/cardsfolder/d/despondency.txt svneol=native#text/plain res/cardsfolder/d/despondency.txt svneol=native#text/plain
@@ -9076,6 +9077,7 @@ res/cardsfolder/t/throat_slitter.txt svneol=native#text/plain
res/cardsfolder/t/throne_of_bone.txt svneol=native#text/plain res/cardsfolder/t/throne_of_bone.txt svneol=native#text/plain
res/cardsfolder/t/throne_of_empires.txt -text res/cardsfolder/t/throne_of_empires.txt -text
res/cardsfolder/t/throne_of_geth.txt svneol=native#text/plain res/cardsfolder/t/throne_of_geth.txt svneol=native#text/plain
res/cardsfolder/t/through_the_breach.txt svneol=native#text/plain
res/cardsfolder/t/thrull_champion.txt svneol=native#text/plain res/cardsfolder/t/thrull_champion.txt svneol=native#text/plain
res/cardsfolder/t/thrull_retainer.txt -text res/cardsfolder/t/thrull_retainer.txt -text
res/cardsfolder/t/thrull_surgeon.txt svneol=native#text/plain res/cardsfolder/t/thrull_surgeon.txt svneol=native#text/plain
@@ -11046,6 +11048,7 @@ src/main/java/forge/card/abilityfactory/AbilityFactoryRegenerate.java svneol=nat
src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactorySacrifice.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactorySacrifice.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactorySetState.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactorySetState.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactorySplice.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactoryToken.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryToken.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java svneol=native#text/plain

View File

@@ -467,7 +467,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId> <artifactId>maven-pmd-plugin</artifactId>
<version>2.7</version> <version>2.7.1</version>
</plugin> </plugin>
<plugin> <plugin>
@@ -627,7 +627,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId> <artifactId>maven-pmd-plugin</artifactId>
<version>2.7</version> <version>2.7.1</version>
<configuration> <configuration>
<linkXRef>true</linkXRef> <linkXRef>true</linkXRef>
<sourceEncoding>utf-8</sourceEncoding> <sourceEncoding>utf-8</sourceEncoding>
@@ -721,7 +721,7 @@
<dependency> <dependency>
<groupId>org.testng</groupId> <groupId>org.testng</groupId>
<artifactId>testng</artifactId> <artifactId>testng</artifactId>
<version>6.3.1</version> <version>6.4</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -0,0 +1,13 @@
Name:Desperate Ritual
ManaCost:1 R
Types:Instant Arcane
Text:no text
A:SP$ Mana | Cost$ R | Produced$ R | Amount$ 3 | SpellDescription$ Add R R R to your mana pool.
S:Mode$ Continuous | Affected$ Arcane.YouCtrl | EffectZone$ Stack | AffectedZone$ Stack| AddAbility$ Mana | Description$ Splice onto Arcane {1}{R}
SVar:Mana:SP$ Mana | Cost$ 1 R | Produced$ R | Amount$ 3 | SpellDescription$ Add R R R to your mana pool.
SVar:RemAIDeck:True
SVar:Rarity:Common
SVar:Picture:http://www.wizards.com/global/images/magic/general/desperate_ritual.jpg
SetInfo:CHK|Common|http://magiccards.info/scans/en/chk/163.jpg
Oracle:Add {R}{R}{R} to your mana pool.
End

View File

@@ -0,0 +1,15 @@
Name:Through the Breach
ManaCost:4 R
Types:Instant Arcane
Text:(Note: Splice onto Arcane is not properly implemented. It will create an instance of this spell on the stack rather than adding it to the first spell)
A:SP$ ChangeZone | Cost$ 4 R | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.YouCtrl | SubAbility$ DBPump | RememberChanged$ True | ForgetOtherRemembered$ True | SpellDescription$ You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice the creature at the beginning of the next end step.
SVar:DBPump:DB$Pump | KW$ Haste & HIDDEN At the beginning of the end step, sacrifice CARDNAME. | Defined$ Remembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True
T:Mode$ SpellCast | ValidCard$ Card.Arcane+YouCtrl | Execute$ TrigSplice | TriggerZones$ Hand | OptionalDecider$ You | TriggerDescription$ Splice onto Arcane 2 R R (As you cast an Arcane spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)
SVar:TrigSplice:AB$ChangeZone | Cost$ 2 R R | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.YouCtrl | SubAbility$ DBPump | RememberChanged$ True | ForgetOtherRemembered$ True | SpellDescription$ Splice CARDNAME onto Arcane.
SVar:RemAIDeck:True
SVar:Rarity:Rare
SVar:Picture:http://www.wizards.com/global/images/magic/general/through_the_breach.jpg
SetInfo:CHK|Rare|http://magiccards.info/scans/en/chk/193.jpg
Oracle:You may put a creature card from your hand onto the battlefield. That creature gains haste. Sacrifice that creature at the beginning of the next end step.\nSplice onto Arcane {2}{R}{R} (As you cast an Arcane spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)
End

View File

@@ -79,7 +79,7 @@ public class ComputerUtil {
if (source.hasStartOfKeyword("May be played without paying its mana cost")) { if (source.hasStartOfKeyword("May be played without paying its mana cost")) {
final SpellAbility newSA = sa.copy(); final SpellAbility newSA = sa.copy();
final Cost cost = sa.getPayCosts(); final Cost cost = sa.getPayCosts();
for (CostPart part : cost.getCostParts()) { for (final CostPart part : cost.getCostParts()) {
if (part instanceof CostMana) { if (part instanceof CostMana) {
((CostMana) part).setMana("0"); ((CostMana) part).setMana("0");
} }
@@ -408,7 +408,7 @@ public class ComputerUtil {
public static final void playSpellAbilityWithoutPayingManaCost(final SpellAbility sa) { public static final void playSpellAbilityWithoutPayingManaCost(final SpellAbility sa) {
final SpellAbility newSA = sa.copy(); final SpellAbility newSA = sa.copy();
final Cost cost = sa.getPayCosts(); final Cost cost = sa.getPayCosts();
for (CostPart part : cost.getCostParts()) { for (final CostPart part : cost.getCostParts()) {
if (part instanceof CostMana) { if (part instanceof CostMana) {
((CostMana) part).setMana("0"); ((CostMana) part).setMana("0");
} }
@@ -420,7 +420,7 @@ public class ComputerUtil {
newSA.setDescription(sb.toString()); newSA.setDescription(sb.toString());
newSA.setActivatingPlayer(AllZone.getComputerPlayer()); newSA.setActivatingPlayer(AllZone.getComputerPlayer());
if (!canPayAdditionalCosts(newSA)) { if (!ComputerUtil.canPayAdditionalCosts(newSA)) {
return; return;
} }
@@ -624,7 +624,7 @@ public class ComputerUtil {
ManaCost cost = new ManaCost(mana); ManaCost cost = new ManaCost(mana);
if (sa.getPayCosts() == null || !sa.getPayCosts().getNoManaCostChange()) { if ((sa.getPayCosts() == null) || !sa.getPayCosts().getNoManaCostChange()) {
cost = AllZone.getGameAction().getSpellCostChange(sa, cost); cost = AllZone.getGameAction().getSpellCostChange(sa, cost);
} }
@@ -658,7 +658,7 @@ public class ComputerUtil {
// Make mana needed to avoid negative effect a mandatory cost for the AI // Make mana needed to avoid negative effect a mandatory cost for the AI
if (card.getSVar("ManaNeededToAvoidNegativeEffect") != "") { if (card.getSVar("ManaNeededToAvoidNegativeEffect") != "") {
String[] negEffects = card.getSVar("ManaNeededToAvoidNegativeEffect").split(","); final String[] negEffects = card.getSVar("ManaNeededToAvoidNegativeEffect").split(",");
int amountAdded = 0; int amountAdded = 0;
for (int nStr = 0; nStr < negEffects.length; nStr++) { for (int nStr = 0; nStr < negEffects.length; nStr++) {
// convert long color strings to short color strings // convert long color strings to short color strings
@@ -672,7 +672,8 @@ public class ComputerUtil {
} }
} }
cost.setManaNeededToAvoidNegativeEffect(negEffects); cost.setManaNeededToAvoidNegativeEffect(negEffects);
//TODO: should it be an error condition if amountAdded is greater than the colorless // TODO: should it be an error condition if amountAdded is greater
// than the colorless
// in the original cost? (ArsenalNut - 120102) // in the original cost? (ArsenalNut - 120102)
// adjust colorless amount to account for added mana // adjust colorless amount to account for added mana
cost.decreaseColorlessMana(amountAdded); cost.decreaseColorlessMana(amountAdded);
@@ -687,21 +688,19 @@ public class ComputerUtil {
} }
// get map of mana abilities // get map of mana abilities
HashMap<String, ArrayList<AbilityMana>> manaAbilityMap = mapManaSources(player); final HashMap<String, ArrayList<AbilityMana>> manaAbilityMap = ComputerUtil.mapManaSources(player);
// initialize ArrayList list for mana needed // initialize ArrayList list for mana needed
ArrayList<ArrayList<AbilityMana>> partSources = final ArrayList<ArrayList<AbilityMana>> partSources = new ArrayList<ArrayList<AbilityMana>>();
new ArrayList<ArrayList<AbilityMana>>(); final ArrayList<Integer> partPriority = new ArrayList<Integer>();
ArrayList<Integer> partPriority = new ArrayList<Integer>(); final String[] costParts = cost.toString().replace("X ", "").replace("P", "").split(" ");
String[] costParts = cost.toString().replace("X ", "").replace("P", "").split(" ");
Boolean foundAllSources = true; Boolean foundAllSources = true;
if (manaAbilityMap.isEmpty()) { if (manaAbilityMap.isEmpty()) {
foundAllSources = false; foundAllSources = false;
} } else {
else { final String[] shortColors = { "W", "U", "B", "R", "G" };
String[] shortColors = {"W", "U", "B" , "R", "G"};
// loop over cost parts // loop over cost parts
for (int nPart = 0; nPart < costParts.length; nPart++) { for (int nPart = 0; nPart < costParts.length; nPart++) {
ArrayList<AbilityMana> srcFound = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> srcFound = new ArrayList<AbilityMana>();
// Test for: // Test for:
// 1) Colorless // 1) Colorless
// 2) Split e.g. 2/G // 2) Split e.g. 2/G
@@ -709,15 +708,14 @@ public class ComputerUtil {
// defaults to single short color // defaults to single short color
if (costParts[nPart].matches("[0-9]+")) { // Colorless if (costParts[nPart].matches("[0-9]+")) { // Colorless
srcFound.addAll(manaAbilityMap.get("1")); srcFound.addAll(manaAbilityMap.get("1"));
} } else if (costParts[nPart].contains("/")) { // Split
else if (costParts[nPart].contains("/")) { // Split final String colorKey = costParts[nPart].replace("2/", "");
String colorKey = costParts[nPart].replace("2/", "");
// add specified color sources first // add specified color sources first
if (manaAbilityMap.containsKey(colorKey)) { if (manaAbilityMap.containsKey(colorKey)) {
srcFound.addAll(manaAbilityMap.get(colorKey)); srcFound.addAll(manaAbilityMap.get(colorKey));
} }
// add other available colors // add other available colors
for (String color : shortColors) { for (final String color : shortColors) {
if (!colorKey.contains(color)) { if (!colorKey.contains(color)) {
// Is source available? // Is source available?
if (manaAbilityMap.containsKey(color)) { if (manaAbilityMap.containsKey(color)) {
@@ -725,30 +723,25 @@ public class ComputerUtil {
} }
} }
} }
} } else if (costParts[nPart].length() > 1) { // Hybrid
else if (costParts[nPart].length() > 1) { // Hybrid final String firstColor = costParts[nPart].substring(0, 1);
String firstColor = costParts[nPart].substring(0, 1); final String secondColor = costParts[nPart].substring(1);
String secondColor = costParts[nPart].substring(1); final Boolean foundFirst = manaAbilityMap.containsKey(firstColor);
Boolean foundFirst = manaAbilityMap.containsKey(firstColor); final Boolean foundSecond = manaAbilityMap.containsKey(secondColor);
Boolean foundSecond = manaAbilityMap.containsKey(secondColor);
if (foundFirst || foundSecond) { if (foundFirst || foundSecond) {
if (!foundFirst) { if (!foundFirst) {
srcFound.addAll(manaAbilityMap.get(secondColor)); srcFound.addAll(manaAbilityMap.get(secondColor));
} } else if (!foundSecond) {
else if (!foundSecond) {
srcFound.addAll(manaAbilityMap.get(firstColor)); srcFound.addAll(manaAbilityMap.get(firstColor));
} } else if (manaAbilityMap.get(firstColor).size() > manaAbilityMap.get(secondColor).size()) {
else if (manaAbilityMap.get(firstColor).size() > manaAbilityMap.get(secondColor).size()) {
srcFound.addAll(manaAbilityMap.get(firstColor)); srcFound.addAll(manaAbilityMap.get(firstColor));
srcFound.addAll(manaAbilityMap.get(secondColor)); srcFound.addAll(manaAbilityMap.get(secondColor));
} } else {
else {
srcFound.addAll(manaAbilityMap.get(secondColor)); srcFound.addAll(manaAbilityMap.get(secondColor));
srcFound.addAll(manaAbilityMap.get(firstColor)); srcFound.addAll(manaAbilityMap.get(firstColor));
} }
} }
} } else { // single color
else { // single color
if (manaAbilityMap.containsKey(costParts[nPart])) { if (manaAbilityMap.containsKey(costParts[nPart])) {
srcFound.addAll(manaAbilityMap.get(costParts[nPart])); srcFound.addAll(manaAbilityMap.get(costParts[nPart]));
} }
@@ -765,8 +758,7 @@ public class ComputerUtil {
} }
} }
partPriority.add(i, nPart); partPriority.add(i, nPart);
} } else {
else {
foundAllSources = false; foundAllSources = false;
break; break;
} }
@@ -775,25 +767,28 @@ public class ComputerUtil {
if (!foundAllSources) { if (!foundAllSources) {
if (!test) { if (!test) {
// real payment should not arrive here // real payment should not arrive here
throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for " + sa.getSourceCard().getName()); throw new RuntimeException("ComputerUtil : payManaCost() cost was not paid for "
+ sa.getSourceCard().getName());
} }
manapool.clearPay(sa, test); // refund any mana taken from mana pool manapool.clearPay(sa, test); // refund any mana taken from mana pool
return false; return false;
} }
// Create array to keep track of sources used // Create array to keep track of sources used
ArrayList<Card> usedSources = new ArrayList<Card>(); final ArrayList<Card> usedSources = new ArrayList<Card>();
//this is to prevent errors for mana sources that have abilities that cost mana. // this is to prevent errors for mana sources that have abilities that
// cost mana.
usedSources.add(sa.getSourceCard()); usedSources.add(sa.getSourceCard());
// Loop over mana needed // Loop over mana needed
int nPriority = 0; int nPriority = 0;
while (nPriority < partPriority.size()) { while (nPriority < partPriority.size()) {
int nPart = partPriority.get(nPriority); final int nPart = partPriority.get(nPriority);
ArrayList<AbilityMana> manaAbilities = partSources.get(nPart); final ArrayList<AbilityMana> manaAbilities = partSources.get(nPart);
ManaCost costPart = new ManaCost(costParts[nPart]); final ManaCost costPart = new ManaCost(costParts[nPart]);
// Loop over mana abilities that can be used to current mana cost part // Loop over mana abilities that can be used to current mana cost
for (AbilityMana m : manaAbilities) { // part
Card sourceCard = m.getSourceCard(); for (final AbilityMana m : manaAbilities) {
final Card sourceCard = m.getSourceCard();
// Check if source has already been used // Check if source has already been used
if (usedSources.contains(sourceCard)) { if (usedSources.contains(sourceCard)) {
@@ -802,9 +797,10 @@ public class ComputerUtil {
// Check if AI can still play this mana ability // 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 ability // if the AI can't pay the additional costs skip the mana
// ability
if (m.getPayCosts() != null) { if (m.getPayCosts() != null) {
if (!canPayAdditionalCosts(m, player)) { if (!ComputerUtil.canPayAdditionalCosts(m, player)) {
continue; continue;
} }
} else if (sourceCard.isTapped()) { } else if (sourceCard.isTapped()) {
@@ -815,13 +811,12 @@ public class ComputerUtil {
// Check if paying snow mana // Check if paying snow mana
if ("S".equals(costParts[nPart])) { if ("S".equals(costParts[nPart])) {
manaProduced = "S"; manaProduced = "S";
} } else {
else {
// check if ability produces any color // check if ability produces any color
if (m.isAnyMana()) { if (m.isAnyMana()) {
String colorChoice = costParts[nPart]; String colorChoice = costParts[nPart];
ArrayList<String> negEffect = cost.getManaNeededToAvoidNegativeEffect(); final ArrayList<String> negEffect = cost.getManaNeededToAvoidNegativeEffect();
ArrayList<String> negEffectPaid = cost.getManaPaidToAvoidNegativeEffect(); final ArrayList<String> negEffectPaid = cost.getManaPaidToAvoidNegativeEffect();
// Check for // Check for
// 1) Colorless // 1) Colorless
// 2) Split e.g. 2/G // 2) Split e.g. 2/G
@@ -834,11 +829,9 @@ public class ComputerUtil {
break; break;
} }
} }
} } else if (costParts[nPart].contains("/")) {
else if (costParts[nPart].contains("/")) {
colorChoice = costParts[nPart].replace("2/", ""); colorChoice = costParts[nPart].replace("2/", "");
} } else if (costParts[nPart].length() > 1) {
else if (costParts[nPart].length() > 1) {
colorChoice = costParts[nPart].substring(0, 1); colorChoice = costParts[nPart].substring(0, 1);
for (int n = 0; n < negEffect.size(); n++) { for (int n = 0; n < negEffect.size(); n++) {
if (costParts[nPart].contains(negEffect.get(n)) if (costParts[nPart].contains(negEffect.get(n))
@@ -862,26 +855,24 @@ public class ComputerUtil {
// TODO: Change this if AI is able use to mana abilities that // TODO: Change this if AI is able use to mana abilities that
// produce more than one mana (111230 - ArsenalNut) // produce more than one mana (111230 - ArsenalNut)
String color = InputPayManaCostUtil.getLongColorString(manaProduced); final String color = InputPayManaCostUtil.getLongColorString(manaProduced);
costPart.payMana(color); costPart.payMana(color);
if (!test) { if (!test) {
// Pay additional costs // Pay additional costs
if (m.getPayCosts() != null) { if (m.getPayCosts() != null) {
CostPayment pay = new CostPayment(m.getPayCosts(), m); final CostPayment pay = new CostPayment(m.getPayCosts(), m);
if (!pay.payComputerCosts()) { if (!pay.payComputerCosts()) {
continue; continue;
} }
} } else {
else {
sourceCard.tap(); sourceCard.tap();
} }
// resolve mana ability // resolve mana ability
m.resolve(); m.resolve();
// subtract mana from mana pool // subtract mana from mana pool
cost = manapool.subtractMana(sa, cost, m); cost = manapool.subtractMana(sa, cost, m);
} } else {
else {
cost.payMana(color); cost.payMana(color);
} }
// check if cost part is paid // check if cost part is paid
@@ -891,8 +882,7 @@ public class ComputerUtil {
} // end of mana ability loop } // end of mana ability loop
if (!costPart.isPaid() || cost.isPaid()) { if (!costPart.isPaid() || cost.isPaid()) {
break; break;
} } else {
else {
nPriority++; nPriority++;
} }
@@ -972,7 +962,6 @@ 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>
@@ -1059,28 +1048,21 @@ public class ComputerUtil {
if (needsLimitedResources) { if (needsLimitedResources) {
otherManaSources.add(card); otherManaSources.add(card);
} } else if (producesAnyColor) {
else if (producesAnyColor) {
anyColorManaSources.add(card); anyColorManaSources.add(card);
} } else if (usableManaAbilities == 1) {
else if (usableManaAbilities == 1) {
if (manaAbilities.get(0).mana().equals("1")) { if (manaAbilities.get(0).mana().equals("1")) {
colorlessManaSources.add(card); colorlessManaSources.add(card);
} } else {
else {
oneManaSources.add(card); oneManaSources.add(card);
} }
} } else if (usableManaAbilities == 2) {
else if (usableManaAbilities == 2) {
twoManaSources.add(card); twoManaSources.add(card);
} } else if (usableManaAbilities == 3) {
else if (usableManaAbilities == 3) {
threeManaSources.add(card); threeManaSources.add(card);
} } else if (usableManaAbilities == 4) {
else if (usableManaAbilities == 4) {
fourManaSources.add(card); fourManaSources.add(card);
} } else {
else {
fiveManaSources.add(card); fiveManaSources.add(card);
} }
@@ -1166,32 +1148,35 @@ public class ComputerUtil {
} }
/** /**
* <p>mapManaSources.</p> * <p>
* mapManaSources.
* </p>
* *
* @param player a {@link forge.Player} object. * @param player
* a {@link forge.Player} object.
* @return HashMap<String, CardList> * @return HashMap<String, CardList>
*/ */
public static HashMap<String, ArrayList<AbilityMana>> mapManaSources(final Player player) { public static HashMap<String, ArrayList<AbilityMana>> mapManaSources(final Player player) {
HashMap<String, ArrayList<AbilityMana>> manaMap = new HashMap<String, ArrayList<AbilityMana>>(); final HashMap<String, ArrayList<AbilityMana>> manaMap = new HashMap<String, ArrayList<AbilityMana>>();
ArrayList<AbilityMana> whiteSources = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> whiteSources = new ArrayList<AbilityMana>();
ArrayList<AbilityMana> blueSources = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> blueSources = new ArrayList<AbilityMana>();
ArrayList<AbilityMana> blackSources = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> blackSources = new ArrayList<AbilityMana>();
ArrayList<AbilityMana> redSources = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> redSources = new ArrayList<AbilityMana>();
ArrayList<AbilityMana> greenSources = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> greenSources = new ArrayList<AbilityMana>();
ArrayList<AbilityMana> colorlessSources = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> colorlessSources = new ArrayList<AbilityMana>();
ArrayList<AbilityMana> snowSources = new ArrayList<AbilityMana>(); final ArrayList<AbilityMana> snowSources = new ArrayList<AbilityMana>();
// Get list of current available mana sources // Get list of current available mana sources
final CardList manaSources = ComputerUtil.getAvailableMana(); final CardList manaSources = ComputerUtil.getAvailableMana();
// Loop over all mana sources // Loop over all mana sources
for (int i = 0; i < manaSources.size(); i++) { for (int i = 0; i < manaSources.size(); i++) {
Card sourceCard = manaSources.get(i); final Card sourceCard = manaSources.get(i);
ArrayList<AbilityMana> manaAbilities = sourceCard.getAIPlayableMana(); final ArrayList<AbilityMana> manaAbilities = sourceCard.getAIPlayableMana();
// Loop over all mana abilities for a source // Loop over all mana abilities for a source
for (AbilityMana m : manaAbilities) { for (final AbilityMana m : manaAbilities) {
// don't use abilities with dangerous drawbacks // don't use abilities with dangerous drawbacks
if (m.getSubAbility() != null) { if (m.getSubAbility() != null) {
@@ -1785,12 +1770,15 @@ public class ComputerUtil {
* sacrificePermanents. * sacrificePermanents.
* </p> * </p>
* *
* @param amount a int. * @param amount
* @param list a {@link forge.CardList} object. * a int.
* @param destroy the destroy * @param list
* a {@link forge.CardList} object.
* @param destroy
* the destroy
* @return the card list * @return the card list
*/ */
public static CardList sacrificePermanents(final int amount, final CardList list, boolean destroy) { public static CardList sacrificePermanents(final int amount, final CardList list, final boolean destroy) {
final CardList sacList = new CardList(); final CardList sacList = new CardList();
// used in Annihilator and AF_Sacrifice // used in Annihilator and AF_Sacrifice
int max = list.size(); int max = list.size();
@@ -1805,7 +1793,7 @@ public class ComputerUtil {
Card c = null; Card c = null;
if (destroy) { if (destroy) {
CardList indestructibles = list.getKeyword("Indestructible"); final CardList indestructibles = list.getKeyword("Indestructible");
if (!indestructibles.isEmpty()) { if (!indestructibles.isEmpty()) {
c = indestructibles.get(0); c = indestructibles.get(0);
} }
@@ -1952,29 +1940,41 @@ public class ComputerUtil {
return prevented; return prevented;
} }
public static boolean containsUsefulKeyword(final ArrayList<String> keywords, Card card) { /**
* Contains useful keyword.
*
* @param keywords the keywords
* @param card the card
* @return true, if successful
*/
public static boolean containsUsefulKeyword(final ArrayList<String> keywords, final Card card) {
for (final String keyword : keywords) { for (final String keyword : keywords) {
if (isUsefulKeyword(keyword, card)) { if (ComputerUtil.isUsefulKeyword(keyword, card)) {
return true; return true;
} }
} }
return false; return false;
} }
public static boolean isUsefulKeyword(final String keyword, Card card) { /**
* Checks if is useful keyword.
*
* @param keyword the keyword
* @param card the card
* @return true, if is useful keyword
*/
public static boolean isUsefulKeyword(final String keyword, final Card card) {
if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) { if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) {
return false; return false;
} }
if (keyword.equals("Defender") || keyword.endsWith("CARDNAME can't attack.")) { if (keyword.equals("Defender") || keyword.endsWith("CARDNAME can't attack.")) {
if (card.getController().isComputer() if (card.getController().isComputer()
|| AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) || AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer())
|| !CombatUtil.canAttack(card) || !CombatUtil.canAttack(card) || (card.getNetCombatDamage() <= 0)) {
|| card.getNetCombatDamage() <= 0) {
return false; return false;
} }
} else if (keyword.contains("CARDNAME can't block.")) { } else if (keyword.contains("CARDNAME can't block.")) {
if (card.getController().isComputer() if (card.getController().isComputer() || AllZone.getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer())
|| AllZone.getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer())
|| !CombatUtil.canBlock(card)) { || !CombatUtil.canBlock(card)) {
return false; return false;
} }
@@ -1984,8 +1984,7 @@ public class ComputerUtil {
return false; return false;
} }
} else if (keyword.endsWith("CARDNAME attacks each turn if able.")) { } else if (keyword.endsWith("CARDNAME attacks each turn if able.")) {
if (AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) if (AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) || !CombatUtil.canAttack(card)
|| !CombatUtil.canAttack(card)
|| !CombatUtil.canBeBlocked(card)) { || !CombatUtil.canBeBlocked(card)) {
return false; return false;
} }

View File

@@ -347,7 +347,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
AllZone.getPhaseHandler().setNeedToNextPhase(true); AllZone.getPhaseHandler().setNeedToNextPhase(true);
} }
} }
// COMBAT_DECLARE_BLOCKERS: we can skip AfterBlockers and AfterAttackers if necessary // COMBAT_DECLARE_BLOCKERS: we can skip AfterBlockers and AfterAttackers
// if necessary
else if (phase.equals(Constant.Phase.COMBAT_DECLARE_BLOCKERS)) { else if (phase.equals(Constant.Phase.COMBAT_DECLARE_BLOCKERS)) {
if (this.inCombat()) { if (this.inCombat()) {
PhaseUtil.verifyCombat(); PhaseUtil.verifyCombat();
@@ -411,8 +412,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
AllZone.getEndOfCombat().executeAt(); AllZone.getEndOfCombat().executeAt();
CombatUtil.showCombat(); CombatUtil.showCombat();
Singletons.getControl().getMatchControl().showStack(); Singletons.getControl().getMatchControl().showStack();
} } else if (phase.equals(Constant.Phase.MAIN2)) {
else if (phase.equals(Constant.Phase.MAIN2)) {
CombatUtil.showCombat(); CombatUtil.showCombat();
Singletons.getControl().getMatchControl().showStack(); Singletons.getControl().getMatchControl().showStack();
} }
@@ -565,13 +565,13 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
} }
} }
AllZone.getGameLog().add("Phase", getPlayerTurn() + " " + getPhase(), 6); AllZone.getGameLog().add("Phase", this.getPlayerTurn() + " " + this.getPhase(), 6);
// **** Anything BELOW Here is actually in the next phase. Maybe move // **** Anything BELOW Here is actually in the next phase. Maybe move
// this to handleBeginPhase // this to handleBeginPhase
if (this.getPhase().equals(Constant.Phase.UNTAP)) { if (this.getPhase().equals(Constant.Phase.UNTAP)) {
this.turn++; this.turn++;
AllZone.getGameLog().add("Turn", "Turn " + turn + " (" + getPlayerTurn() + ")", 0); AllZone.getGameLog().add("Turn", "Turn " + this.turn + " (" + this.getPlayerTurn() + ")", 0);
} }
PhaseUtil.visuallyActivatePhase(this.getPhase()); PhaseUtil.visuallyActivatePhase(this.getPhase());
@@ -951,8 +951,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
*/ */
public static boolean canCastSorcery(final Player player) { public static boolean canCastSorcery(final Player player) {
return AllZone.getPhaseHandler().isPlayerTurn(player) return AllZone.getPhaseHandler().isPlayerTurn(player)
&& (AllZone.getPhaseHandler().getPhase().equals(Constant.Phase.MAIN2) || AllZone.getPhaseHandler().getPhase() && (AllZone.getPhaseHandler().getPhase().equals(Constant.Phase.MAIN2) || AllZone.getPhaseHandler()
.equals(Constant.Phase.MAIN1)) && (AllZone.getStack().size() == 0); .getPhase().equals(Constant.Phase.MAIN1)) && (AllZone.getStack().size() == 0);
} }
/** /**
@@ -1029,6 +1029,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
this.phaseIndex = this.findIndex(phaseID); this.phaseIndex = this.findIndex(phaseID);
} }
/**
* Sets the phase state.
*
* @param phaseID the new phase state
*/
public final void setPhaseState(final String phaseID) { public final void setPhaseState(final String phaseID) {
this.phaseIndex = this.findIndex(phaseID); this.phaseIndex = this.findIndex(phaseID);
this.handleBeginPhase(); this.handleBeginPhase();

View File

@@ -57,7 +57,7 @@ public abstract class Player extends GameEntity {
private int startingLife; private int startingLife;
/** The assigned damage. */ /** The assigned damage. */
private Map<Card, Integer> assignedDamage = new HashMap<Card, Integer>(); private final Map<Card, Integer> assignedDamage = new HashMap<Card, Integer>();
/** The life lost this turn. */ /** The life lost this turn. */
private int lifeLostThisTurn = 0; private int lifeLostThisTurn = 0;
@@ -168,7 +168,7 @@ public abstract class Player extends GameEntity {
*/ */
public final void reset() { public final void reset() {
this.life = 20; this.life = 20;
lifeLostThisTurn = 0; this.lifeLostThisTurn = 0;
this.poisonCounters = 0; this.poisonCounters = 0;
this.assignedDamage.clear(); this.assignedDamage.clear();
this.setPreventNextDamage(0); this.setPreventNextDamage(0);
@@ -265,7 +265,8 @@ public abstract class Player extends GameEntity {
} }
/** /**
* Sets the starting life for a game. Should only be called from newGame()'s. * Sets the starting life for a game. Should only be called from
* newGame()'s.
* *
* @param startLife * @param startLife
* a int. * a int.
@@ -324,7 +325,7 @@ public abstract class Player extends GameEntity {
public final boolean gainLife(final int toGain, final Card source) { public final boolean gainLife(final int toGain, final Card source) {
// Run any applicable replacement effects. // Run any applicable replacement effects.
HashMap<String, Object> repParams = new HashMap<String, Object>(); final HashMap<String, Object> repParams = new HashMap<String, Object>();
repParams.put("Event", "GainLife"); repParams.put("Event", "GainLife");
repParams.put("Affected", this); repParams.put("Affected", this);
repParams.put("LifeGained", toGain); repParams.put("LifeGained", toGain);
@@ -336,7 +337,7 @@ public abstract class Player extends GameEntity {
if (!this.canGainLife()) { if (!this.canGainLife()) {
return false; return false;
} }
int lifeGain = toGain; final int lifeGain = toGain;
if (lifeGain > 0) { if (lifeGain > 0) {
this.addLife(lifeGain); this.addLife(lifeGain);
@@ -363,8 +364,8 @@ public abstract class Player extends GameEntity {
* @return a boolean. * @return a boolean.
*/ */
public final boolean canGainLife() { public final boolean canGainLife() {
if (AllZoneUtil.isCardInPlay("Leyline of Punishment") if (AllZoneUtil.isCardInPlay("Leyline of Punishment") || AllZoneUtil.isCardInPlay("Platinum Emperion", this)
|| AllZoneUtil.isCardInPlay("Platinum Emperion", this) || AllZoneUtil.isCardInPlay("Forsaken Wastes")) { || AllZoneUtil.isCardInPlay("Forsaken Wastes")) {
return false; return false;
} }
return true; return true;
@@ -505,9 +506,9 @@ public abstract class Player extends GameEntity {
final StringBuilder sb = new StringBuilder( final StringBuilder sb = new StringBuilder(
"As long as you have 0 or less life, all damage is dealt to you as though its source had infect."); "As long as you have 0 or less life, all damage is dealt to you as though its source had infect.");
if (this.getLife() <= 0 && !infect) { if ((this.getLife() <= 0) && !infect) {
CardList cards = this.getCardsIn(Zone.Battlefield); final CardList cards = this.getCardsIn(Zone.Battlefield);
for (Card card : cards) { for (final Card card : cards) {
if (card.hasKeyword(sb.toString())) { if (card.hasKeyword(sb.toString())) {
infect = true; infect = true;
break; break;
@@ -645,7 +646,8 @@ public abstract class Player extends GameEntity {
// This should be also usable by the AI to forecast an effect (so it must // This should be also usable by the AI to forecast an effect (so it must
// not change the game state) // not change the game state)
// 2012/01/02: No longer used in calculating the finalized damage, but retained for damageprediction. -Hellfish // 2012/01/02: No longer used in calculating the finalized damage, but
// retained for damageprediction. -Hellfish
/** /**
* <p> * <p>
* staticReplaceDamage. * staticReplaceDamage.
@@ -743,7 +745,7 @@ public abstract class Player extends GameEntity {
public final int replaceDamage(final int damage, final Card source, final boolean isCombat) { public final int replaceDamage(final int damage, final Card source, final boolean isCombat) {
// Replacement effects // Replacement effects
HashMap<String, Object> repParams = new HashMap<String, Object>(); final HashMap<String, Object> repParams = new HashMap<String, Object>();
repParams.put("Event", "DamageDone"); repParams.put("Event", "DamageDone");
repParams.put("Affected", this); repParams.put("Affected", this);
repParams.put("DamageSource", source); repParams.put("DamageSource", source);
@@ -848,7 +850,7 @@ public abstract class Player extends GameEntity {
*/ */
public final int getAssignedDamage() { public final int getAssignedDamage() {
int num = 0; int num = 0;
for (Integer value : assignedDamage.values()) { for (final Integer value : this.assignedDamage.values()) {
num += value; num += value;
} }
return num; return num;
@@ -864,15 +866,15 @@ public abstract class Player extends GameEntity {
* *
* @return a int. * @return a int.
*/ */
public final int getAssignedDamage(String type) { public final int getAssignedDamage(final String type) {
Map<Card, Integer> valueMap = new HashMap<Card, Integer>(); final Map<Card, Integer> valueMap = new HashMap<Card, Integer>();
for (Card c : assignedDamage.keySet()) { for (final Card c : this.assignedDamage.keySet()) {
if (c.isType(type)) { if (c.isType(type)) {
valueMap.put(c, assignedDamage.get(c)); valueMap.put(c, this.assignedDamage.get(c));
} }
} }
int num = 0; int num = 0;
for (Integer value : valueMap.values()) { for (final Integer value : valueMap.values()) {
num += value; num += value;
} }
return num; return num;
@@ -916,8 +918,10 @@ public abstract class Player extends GameEntity {
* addPoisonCounters. * addPoisonCounters.
* </p> * </p>
* *
* @param num a int. * @param num
* @param source the source * a int.
* @param source
* the source
*/ */
public final void addPoisonCounters(final int num, final Card source) { public final void addPoisonCounters(final int num, final Card source) {
if (!this.hasKeyword("You can't get poison counters")) { if (!this.hasKeyword("You can't get poison counters")) {
@@ -1243,7 +1247,7 @@ public abstract class Player extends GameEntity {
final PlayerZone library = this.getZone(Constant.Zone.Library); final PlayerZone library = this.getZone(Constant.Zone.Library);
// Replacement effects // Replacement effects
HashMap<String, Object> repRunParams = new HashMap<String, Object>(); final HashMap<String, Object> repRunParams = new HashMap<String, Object>();
repRunParams.put("Event", "Draw"); repRunParams.put("Event", "Draw");
repRunParams.put("Affected", this); repRunParams.put("Affected", this);
@@ -1257,10 +1261,10 @@ public abstract class Player extends GameEntity {
c = AllZone.getGameAction().moveToHand(c); c = AllZone.getGameAction().moveToHand(c);
drawn.add(c); drawn.add(c);
if (numDrawnThisTurn == 0 && this.isComputer()) { if ((this.numDrawnThisTurn == 0) && this.isComputer()) {
boolean reveal = false; boolean reveal = false;
CardList cards = this.getCardsIn(Zone.Battlefield); final CardList cards = this.getCardsIn(Zone.Battlefield);
for (Card card : cards) { for (final Card card : cards) {
if (card.hasKeyword("Reveal the first card you draw each turn")) { if (card.hasKeyword("Reveal the first card you draw each turn")) {
reveal = true; reveal = true;
break; break;
@@ -1278,7 +1282,7 @@ public abstract class Player extends GameEntity {
// Run triggers // Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>(); final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", c); runParams.put("Card", c);
runParams.put("Number", numDrawnThisTurn); runParams.put("Number", this.numDrawnThisTurn);
AllZone.getTriggerHandler().runTrigger("Drawn", runParams); AllZone.getTriggerHandler().runTrigger("Drawn", runParams);
} }
// lose: // lose:
@@ -1810,7 +1814,8 @@ public abstract class Player extends GameEntity {
* @return a boolean. * @return a boolean.
*/ */
public final boolean canPlayLand() { public final boolean canPlayLand() {
if (Singletons.getView().getMatchView().getViewTabber().getLblUnlimitedLands().getEnabled() && this.isHuman() && Constant.Runtime.DEV_MODE[0]) { if (Singletons.getView().getMatchView().getViewTabber().getLblUnlimitedLands().getEnabled() && this.isHuman()
&& Constant.Runtime.DEV_MODE[0]) {
return PhaseHandler.canCastSorcery(this); return PhaseHandler.canCastSorcery(this);
} }
@@ -2146,7 +2151,7 @@ public abstract class Player extends GameEntity {
} }
// Replacement effects // Replacement effects
HashMap<String, Object> runParams = new HashMap<String, Object>(); final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Affected", this); runParams.put("Affected", this);
runParams.put("Event", "GameLoss"); runParams.put("Event", "GameLoss");
@@ -2241,7 +2246,7 @@ public abstract class Player extends GameEntity {
} }
if (this.lossState != GameLossReason.DidNotLoseYet) { if (this.lossState != GameLossReason.DidNotLoseYet) {
return this.loseConditionMet(lossState, null); return this.loseConditionMet(this.lossState, null);
} }
if (this.poisonCounters >= 10) { if (this.poisonCounters >= 10) {
@@ -2374,11 +2379,11 @@ public abstract class Player extends GameEntity {
return false; return false;
} }
} else if (incR[0].equals("EnchantedController")) { } else if (incR[0].equals("EnchantedController")) {
GameEntity enchanted = source.getEnchanting(); final GameEntity enchanted = source.getEnchanting();
if (enchanted == null || !(enchanted instanceof Card)) { if ((enchanted == null) || !(enchanted instanceof Card)) {
return false; return false;
} }
Card enchantedCard = (Card) enchanted; final Card enchantedCard = (Card) enchanted;
if (!this.equals(enchantedCard.getController())) { if (!this.equals(enchantedCard.getController())) {
return false; return false;
} }
@@ -2730,6 +2735,9 @@ public abstract class Player extends GameEntity {
return this.mustAttackEntity; return this.mustAttackEntity;
} }
/**
* Update label observers.
*/
public final void updateLabelObservers() { public final void updateLabelObservers() {
this.getZone(Zone.Hand).updateObservers(); this.getZone(Zone.Hand).updateObservers();
} }

View File

@@ -486,7 +486,10 @@ public class Upkeep extends Phase implements java.io.Serializable {
@Override @Override
public void showMessage() { public void showMessage() {
Singletons.getControl().getMatchControl().showMessage( Singletons
.getControl()
.getMatchControl()
.showMessage(
abyss.getName() + " - Select one nonartifact creature to destroy"); abyss.getName() + " - Select one nonartifact creature to destroy");
ButtonUtil.disableAll(); ButtonUtil.disableAll();
} }
@@ -554,7 +557,10 @@ public class Upkeep extends Phase implements java.io.Serializable {
@Override @Override
public void showMessage() { public void showMessage() {
Singletons.getControl().getMatchControl().showMessage( Singletons
.getControl()
.getMatchControl()
.showMessage(
"Yawgmoth Demon - Select one artifact to sacrifice or be dealt 2 damage"); "Yawgmoth Demon - Select one artifact to sacrifice or be dealt 2 damage");
ButtonUtil.enableOnlyCancel(); ButtonUtil.enableOnlyCancel();
} }
@@ -2261,7 +2267,7 @@ public class Upkeep extends Phase implements java.io.Serializable {
final SpellAbility ability = new Ability(c, "0") { final SpellAbility ability = new Ability(c, "0") {
@Override @Override
public void resolve() { public void resolve() {
StringBuilder question = new StringBuilder(); final StringBuilder question = new StringBuilder();
question.append("Use triggered ability of ").append(c).append("?"); question.append("Use triggered ability of ").append(c).append("?");
question.append("\r\n").append("(").append(keyword).append(")").append("\r\n"); question.append("\r\n").append("(").append(keyword).append(")").append("\r\n");
if (GameActionUtil.showYesNoDialog(c, question.toString(), true)) { if (GameActionUtil.showYesNoDialog(c, question.toString(), true)) {
@@ -2274,14 +2280,14 @@ public class Upkeep extends Phase implements java.io.Serializable {
if (newTarget[0] != null) { if (newTarget[0] != null) {
/* /*
* 1. need to select new card - DONE 1a. need to * 1. need to select new card - DONE 1a.
* create the newly copied card with pic and * need to create the newly copied card with
* setinfo 2. need to add the leaves play * pic and setinfo 2. need to add the leaves
* command 3. need to transfer the keyword 4. * play command 3. need to transfer the
* need to update the clone origin of new card * keyword 4. need to update the clone
* and old card 5. remove clone leaves play * origin of new card and old card 5. remove
* commands from old 5a. remove old from play 6. * clone leaves play commands from old 5a.
* add new to play * remove old from play 6. add new to play
*/ */
final Card newCopy = AllZone.getCardFactory().getCard( final Card newCopy = AllZone.getCardFactory().getCard(
@@ -2308,8 +2314,8 @@ public class Upkeep extends Phase implements java.io.Serializable {
@Override @Override
public void showMessage() { public void showMessage() {
Singletons.getControl().getMatchControl().showMessage( Singletons.getControl().getMatchControl()
c.getName() + " - Select target creature."); .showMessage(c.getName() + " - Select target creature.");
ButtonUtil.enableOnlyCancel(); ButtonUtil.enableOnlyCancel();
} }
@@ -2382,8 +2388,13 @@ public class Upkeep extends Phase implements java.io.Serializable {
this.stop(); this.stop();
return; return;
} }
Singletons.getControl().getMatchControl().showMessage( Singletons
source.getName() + " - Select " + num .getControl()
.getMatchControl()
.showMessage(
source.getName()
+ " - Select "
+ num
+ " untapped artifact(s), creature(s), or land(s) you control"); + " untapped artifact(s), creature(s), or land(s) you control");
ButtonUtil.disableAll(); ButtonUtil.disableAll();
} }

View File

@@ -0,0 +1,490 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.card.abilityfactory;
import java.util.ArrayList;
import java.util.HashMap;
import forge.AllZone;
import forge.Card;
import forge.ComputerUtil;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.Cost;
import forge.card.cost.CostUtil;
import forge.card.spellability.AbilityActivated;
import forge.card.spellability.AbilitySub;
import forge.card.spellability.Spell;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.spellability.Target;
import forge.card.spellability.TargetSelection;
import forge.util.MyRandom;
//Examples:
//A:SP$ Splice | Cost$ 1 G | TargetType$ Arcane | SpellDescription$ Counter target activated ability.
/**
* <p>
* AbilityFactorySplice class.
* </p>
*
* @author Forge
* @version $Id$
*/
public class AbilityFactorySplice {
private AbilityFactory abilityFactory = null;
private HashMap<String, String> params = null;
private String unlessCost = null;
/**
* <p>
* Constructor for AbilityFactorySplice.
* </p>
*
* @param newAbilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
*/
public AbilityFactorySplice(final AbilityFactory newAbilityFactory) {
this.abilityFactory = newAbilityFactory;
this.params = this.abilityFactory.getMapParams();
if (this.params.containsKey("UnlessCost")) {
this.unlessCost = this.params.get("UnlessCost").trim();
}
}
/**
* <p>
* getAbilitySplice.
* </p>
*
* @param abilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public final SpellAbility getAbilitySplice(final AbilityFactory abilityFactory) {
final SpellAbility abilitySplice = new AbilityActivated(abilityFactory.getHostCard(), abilityFactory.getAbCost(),
abilityFactory.getAbTgt()) {
private static final long serialVersionUID = -3895990436431818899L;
@Override
public String getStackDescription() {
// when getStackDesc is called, just build exactly what is
// happening
return AbilityFactorySplice.this
.spliceStackDescription(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public boolean canPlayAI() {
return AbilityFactorySplice.this.spliceCanPlayAI(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public void resolve() {
AbilityFactorySplice.this.spliceResolve(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public boolean doTrigger(final boolean mandatory) {
return AbilityFactorySplice.this.spliceCanPlayAI(AbilityFactorySplice.this.abilityFactory, this);
}
};
return abilitySplice;
}
/**
* <p>
* getSpellSplice.
* </p>
*
* @param abilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public final SpellAbility getSpellSplice(final AbilityFactory abilityFactory) {
final SpellAbility spellAbilitySplice = new Spell(abilityFactory.getHostCard(), abilityFactory.getAbCost(),
abilityFactory.getAbTgt()) {
private static final long serialVersionUID = -4272851734871573693L;
@Override
public String getStackDescription() {
return AbilityFactorySplice.this
.spliceStackDescription(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public boolean canPlayAI() {
return AbilityFactorySplice.this.spliceCanPlayAI(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public void resolve() {
AbilityFactorySplice.this.spliceResolve(AbilityFactorySplice.this.abilityFactory, this);
}
};
return spellAbilitySplice;
}
/**
* <p>
* getDrawbackSplice.
* </p>
*
* @param abilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public final SpellAbility getDrawbackSplice(final AbilityFactory abilityFactory) {
final SpellAbility drawbackSplice = new AbilitySub(abilityFactory.getHostCard(), abilityFactory.getAbTgt()) {
private static final long serialVersionUID = -4272851734871573693L;
@Override
public String getStackDescription() {
return AbilityFactorySplice.this
.spliceStackDescription(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public boolean canPlayAI() {
return AbilityFactorySplice.this.spliceCanPlayAI(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public void resolve() {
AbilityFactorySplice.this.spliceResolve(AbilityFactorySplice.this.abilityFactory, this);
}
@Override
public boolean chkAIDrawback() {
return AbilityFactorySplice.this.spliceDoTriggerAI(AbilityFactorySplice.this.abilityFactory, this,
true);
}
@Override
public boolean doTrigger(final boolean mandatory) {
return AbilityFactorySplice.this.spliceDoTriggerAI(AbilityFactorySplice.this.abilityFactory, this,
mandatory);
}
};
return drawbackSplice;
}
/**
* <p>
* spliceCanPlayAI.
* </p>
*
* @param abilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
* @param spellAbility
* a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
private boolean spliceCanPlayAI(final AbilityFactory abilityFactory, final SpellAbility spellAbility) {
boolean toReturn = true;
final Cost abCost = abilityFactory.getAbCost();
final Card source = spellAbility.getSourceCard();
if (AllZone.getStack().size() < 1) {
return false;
}
if (abCost != null) {
// AI currently disabled for these costs
if (!CostUtil.checkSacrificeCost(abCost, source)) {
return false;
}
if (!CostUtil.checkLifeCost(abCost, source, 4)) {
return false;
}
}
final Target tgt = spellAbility.getTarget();
if (tgt != null) {
final SpellAbility topSA = AllZone.getStack().peekAbility();
if (!CardFactoryUtil.isCounterable(topSA.getSourceCard()) || topSA.getActivatingPlayer().isComputer()) {
return false;
}
tgt.resetTargets();
if (TargetSelection.matchSpellAbility(spellAbility, topSA, tgt)) {
tgt.addTarget(topSA);
} else {
return false;
}
}
if (this.unlessCost != null) {
// Is this Usable Mana Sources? Or Total Available Mana?
final int usableManaSources = CardFactoryUtil.getUsableManaSources(AllZone.getHumanPlayer());
int toPay = 0;
boolean setPayX = false;
if (this.unlessCost.equals("X") && source.getSVar(this.unlessCost).equals("Count$xPaid")) {
setPayX = true;
toPay = ComputerUtil.determineLeftoverMana(spellAbility);
} else {
toPay = AbilityFactory.calculateAmount(source, this.unlessCost, spellAbility);
}
if (toPay == 0) {
return false;
}
if (toPay <= usableManaSources) {
// If this is a reusable Resource, feel free to play it most of
// the time
if (!spellAbility.getPayCosts().isReusuableResource() || (MyRandom.getRandom().nextFloat() < .4)) {
return false;
}
}
if (setPayX) {
source.setSVar("PayX", Integer.toString(toPay));
}
}
// TODO Improve AI
// Will return true if this spell can counter (or is Reusable and can
// force the Human into making decisions)
// But really it should be more picky about how it counters things
final AbilitySub subAb = spellAbility.getSubAbility();
if (subAb != null) {
toReturn &= subAb.chkAIDrawback();
}
return toReturn;
}
/**
* <p>
* spliceDoTriggerAI.
* </p>
*
* @param abilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
* @param spellAbility
* a {@link forge.card.spellability.SpellAbility} object.
* @param mandatory
* a boolean.
* @return a boolean.
*/
private boolean spliceDoTriggerAI(final AbilityFactory abilityFactory, final SpellAbility spellAbility, final boolean mandatory) {
boolean toReturn = true;
if (AllZone.getStack().size() < 1) {
return false;
}
final Target tgt = spellAbility.getTarget();
if (tgt != null) {
final SpellAbility topSA = AllZone.getStack().peekAbility();
if (!CardFactoryUtil.isCounterable(topSA.getSourceCard()) || topSA.getActivatingPlayer().isComputer()) {
return false;
}
tgt.resetTargets();
if (TargetSelection.matchSpellAbility(spellAbility, topSA, tgt)) {
tgt.addTarget(topSA);
} else {
return false;
}
final Card source = spellAbility.getSourceCard();
if (this.unlessCost != null) {
// Is this Usable Mana Sources? Or Total Available Mana?
final int usableManaSources = CardFactoryUtil.getUsableManaSources(AllZone.getHumanPlayer());
int toPay = 0;
boolean setPayX = false;
if (this.unlessCost.equals("X") && source.getSVar(this.unlessCost).equals("Count$xPaid")) {
setPayX = true;
toPay = ComputerUtil.determineLeftoverMana(spellAbility);
} else {
toPay = AbilityFactory.calculateAmount(source, this.unlessCost, spellAbility);
}
if (toPay == 0) {
return false;
}
if (toPay <= usableManaSources) {
// If this is a reusable Resource, feel free to play it most
// of the time
if (!spellAbility.getPayCosts().isReusuableResource() || (MyRandom.getRandom().nextFloat() < .4)) {
return false;
}
}
if (setPayX) {
source.setSVar("PayX", Integer.toString(toPay));
}
}
}
// TODO Improve AI
// Will return true if this spell can counter (or is Reusable and can
// force the Human into making decisions)
// But really it should be more picky about how it counters things
final AbilitySub subAb = spellAbility.getSubAbility();
if (subAb != null) {
toReturn &= subAb.chkAIDrawback();
}
return toReturn;
}
/**
* <p>
* spliceResolve.
* </p>
*
* @param abilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
* @param spellAbility
* a {@link forge.card.spellability.SpellAbility} object.
*/
private void spliceResolve(final AbilityFactory abilityFactory, final SpellAbility spellAbility) {
// TODO Before this resolves we should see if any of our targets are
// still on the stack
ArrayList<SpellAbility> sas;
final Target tgt = abilityFactory.getAbTgt();
if (tgt != null) {
sas = tgt.getTargetSAs();
} else {
sas = AbilityFactory.getDefinedSpellAbilities(spellAbility.getSourceCard(), this.params.get("Defined"), spellAbility);
}
if (this.params.containsKey("ForgetOtherTargets")) {
if (this.params.get("ForgetOtherTargets").equals("True")) {
abilityFactory.getHostCard().clearRemembered();
}
}
for (final SpellAbility tgtSA : sas) {
final Card tgtSACard = tgtSA.getSourceCard();
if (tgtSA.isSpell() && !CardFactoryUtil.isCounterable(tgtSACard)) {
continue;
}
final SpellAbilityStackInstance si = AllZone.getStack().getInstanceFromSpellAbility(tgtSA);
if (si == null) {
continue;
}
this.removeFromStack(tgtSA, spellAbility, si);
// Destroy Permanent may be able to be turned into a SubAbility
if (tgtSA.isAbility() && this.params.containsKey("DestroyPermanent")) {
AllZone.getGameAction().destroy(tgtSACard);
}
if (this.params.containsKey("RememberTargets")) {
if (this.params.get("RememberTargets").equals("True")) {
abilityFactory.getHostCard().addRemembered(tgtSACard);
}
}
}
} // end spliceResolve
/**
* <p>
* spliceStackDescription.
* </p>
*
* @param abilityFactory
* a {@link forge.card.abilityfactory.AbilityFactory} object.
* @param spellAbility
* a {@link forge.card.spellability.SpellAbility} object.
* @return a {@link java.lang.String} object.
*/
private String spliceStackDescription(final AbilityFactory abilityFactory, final SpellAbility spellAbility) {
final StringBuilder sb = new StringBuilder();
if (!(spellAbility instanceof AbilitySub)) {
sb.append(spellAbility.getSourceCard().getName()).append(" - ");
} else {
sb.append(" ");
}
ArrayList<SpellAbility> sas;
final Target tgt = abilityFactory.getAbTgt();
if (tgt != null) {
sas = tgt.getTargetSAs();
} else {
sas = AbilityFactory.getDefinedSpellAbilities(spellAbility.getSourceCard(), this.params.get("Defined"), spellAbility);
}
sb.append("splicing");
boolean isAbility = false;
for (final SpellAbility tgtSA : sas) {
sb.append(" ");
sb.append(tgtSA.getSourceCard());
isAbility = tgtSA.isAbility();
if (isAbility) {
sb.append("'s ability");
}
}
if (isAbility && this.params.containsKey("DestroyPermanent")) {
sb.append(" and destroy it");
}
sb.append(".");
final AbilitySub abSub = spellAbility.getSubAbility();
if (abSub != null) {
sb.append(abSub.getStackDescription());
}
return sb.toString();
} // end spliceStackDescription
/**
* <p>
* removeFromStack.
* </p>
*
* @param targetSpellAbility
* a {@link forge.card.spellability.SpellAbility} object.
* @param sourceSpellAbility
* a {@link forge.card.spellability.SpellAbility} object.
* @param spellAbilityStackInstance
* a {@link forge.card.spellability.SpellAbilityStackInstance}
* object.
*/
private void removeFromStack(final SpellAbility targetSpellAbility, final SpellAbility sourceSpellAbility, final SpellAbilityStackInstance spellAbilityStackInstance) {
AllZone.getStack().remove(spellAbilityStackInstance);
}
} // end class AbilityFactorySplice

View File

@@ -293,8 +293,14 @@ public class AbilityFactoryTurns {
// ************************* END TURN ************************************** // ************************* END TURN **************************************
// ************************************************************************* // *************************************************************************
/**
* Creates the ability end turn.
*
* @param af the af
* @return the spell ability
*/
public static SpellAbility createAbilityEndTurn(final AbilityFactory af) { public static SpellAbility createAbilityEndTurn(final AbilityFactory af) {
SpellAbility ret = new AbilityActivated(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { final SpellAbility ret = new AbilityActivated(af.getHostCard(), af.getAbCost(), af.getAbTgt()) {
private static final long serialVersionUID = 72570867940224012L; private static final long serialVersionUID = 72570867940224012L;
@@ -309,7 +315,7 @@ public class AbilityFactoryTurns {
} }
@Override @Override
public boolean doTrigger(boolean mandatory) { public boolean doTrigger(final boolean mandatory) {
if (mandatory) { if (mandatory) {
return true; return true;
} }
@@ -319,7 +325,7 @@ public class AbilityFactoryTurns {
@Override @Override
public void resolve() { public void resolve() {
endTurnResolve(af, this); AbilityFactoryTurns.endTurnResolve(af, this);
} }
}; };
@@ -327,8 +333,14 @@ public class AbilityFactoryTurns {
return ret; return ret;
} }
/**
* Creates the spell end turn.
*
* @param af the af
* @return the spell ability
*/
public static SpellAbility createSpellEndTurn(final AbilityFactory af) { public static SpellAbility createSpellEndTurn(final AbilityFactory af) {
SpellAbility ret = new Spell(af.getHostCard(), af.getAbCost(), af.getAbTgt()) { final SpellAbility ret = new Spell(af.getHostCard(), af.getAbCost(), af.getAbTgt()) {
private static final long serialVersionUID = -2553413143747617709L; private static final long serialVersionUID = -2553413143747617709L;
@@ -344,7 +356,7 @@ public class AbilityFactoryTurns {
@Override @Override
public void resolve() { public void resolve() {
endTurnResolve(af, this); AbilityFactoryTurns.endTurnResolve(af, this);
} }
}; };
@@ -352,6 +364,12 @@ public class AbilityFactoryTurns {
return ret; return ret;
} }
/**
* Creates the drawback end turn.
*
* @param af the af
* @return the spell ability
*/
public static SpellAbility createDrawbackEndTurn(final AbilityFactory af) { public static SpellAbility createDrawbackEndTurn(final AbilityFactory af) {
final SpellAbility dbEndTurn = new AbilitySub(af.getHostCard(), af.getAbTgt()) { final SpellAbility dbEndTurn = new AbilitySub(af.getHostCard(), af.getAbTgt()) {
private static final long serialVersionUID = -562517287448810951L; private static final long serialVersionUID = -562517287448810951L;
@@ -387,8 +405,10 @@ public class AbilityFactoryTurns {
private static void endTurnResolve(final AbilityFactory af, final SpellAbility sa) { private static void endTurnResolve(final AbilityFactory af, final SpellAbility sa) {
// Steps taken from gatherer's rulings on Time Stop. // Steps taken from gatherer's rulings on Time Stop.
//1) All spells and abilities on the stack are exiled. This includes Time Stop, though it will continue to resolve. It also includes spells and abilities that can't be countered. // 1) All spells and abilities on the stack are exiled. This includes
for (Card c : AllZone.getStackZone().getCards()) { // Time Stop, though it will continue to resolve. It also includes
// spells and abilities that can't be countered.
for (final Card c : AllZone.getStackZone().getCards()) {
AllZone.getGameAction().exile(c); AllZone.getGameAction().exile(c);
} }
AllZone.getStack().getStack().clear(); AllZone.getStack().getStack().clear();
@@ -397,10 +417,12 @@ public class AbilityFactoryTurns {
AllZone.getCombat().resetAttackers(); AllZone.getCombat().resetAttackers();
AllZone.getCombat().resetBlockers(); AllZone.getCombat().resetBlockers();
//3) State-based actions are checked. No player gets priority, and no triggered abilities are put onto the stack. // 3) State-based actions are checked. No player gets priority, and no
// triggered abilities are put onto the stack.
AllZone.getGameAction().checkStateEffects(); AllZone.getGameAction().checkStateEffects();
//4) The current phase and/or step ends. The game skips straight to the cleanup step. The cleanup step happens in its entirety. // 4) The current phase and/or step ends. The game skips straight to the
// cleanup step. The cleanup step happens in its entirety.
AllZone.getPhaseHandler().setPhaseState(Constant.Phase.CLEANUP); AllZone.getPhaseHandler().setPhaseState(Constant.Phase.CLEANUP);
// Update observers // Update observers

View File

@@ -44,31 +44,41 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
* @return the hasRun * @return the hasRun
*/ */
public final boolean hasRun() { public final boolean hasRun() {
return hasRun; return this.hasRun;
} }
/**
* Checks if is secondary.
*
* @return true, if is secondary
*/
public final boolean isSecondary() { public final boolean isSecondary() {
return mapParams.containsKey("Secondary"); return this.mapParams.containsKey("Secondary");
} }
/**
* Ai should run.
*
* @param sa the sa
* @return true, if successful
*/
public final boolean aiShouldRun(final SpellAbility sa) { public final boolean aiShouldRun(final SpellAbility sa) {
if (mapParams.containsKey("AICheckSVar")) { if (this.mapParams.containsKey("AICheckSVar")) {
String svarToCheck = mapParams.get("AICheckSVar"); final String svarToCheck = this.mapParams.get("AICheckSVar");
String comparator = "GE"; String comparator = "GE";
int compareTo = 1; int compareTo = 1;
if (mapParams.containsKey("AISVarCompare")) { if (this.mapParams.containsKey("AISVarCompare")) {
String fullCmp = mapParams.get("AISVarCompare"); final String fullCmp = this.mapParams.get("AISVarCompare");
comparator = fullCmp.substring(0, 2); comparator = fullCmp.substring(0, 2);
String strCmpTo = fullCmp.substring(2); final String strCmpTo = fullCmp.substring(2);
try { try {
compareTo = Integer.parseInt(strCmpTo); compareTo = Integer.parseInt(strCmpTo);
} } catch (final Exception ignored) {
catch (Exception ignored) {
if (sa == null) { if (sa == null) {
compareTo = CardFactoryUtil.xCount(hostCard, hostCard.getSVar(strCmpTo)); compareTo = CardFactoryUtil.xCount(this.hostCard, this.hostCard.getSVar(strCmpTo));
} else { } else {
compareTo = AbilityFactory.calculateAmount(hostCard, hostCard.getSVar(strCmpTo), sa); compareTo = AbilityFactory.calculateAmount(this.hostCard, this.hostCard.getSVar(strCmpTo), sa);
} }
} }
} }
@@ -76,9 +86,9 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
int left = 0; int left = 0;
if (sa == null) { if (sa == null) {
left = CardFactoryUtil.xCount(hostCard, hostCard.getSVar(svarToCheck)); left = CardFactoryUtil.xCount(this.hostCard, this.hostCard.getSVar(svarToCheck));
} else { } else {
left = AbilityFactory.calculateAmount(hostCard, hostCard.getSVar(svarToCheck), sa); left = AbilityFactory.calculateAmount(this.hostCard, this.hostCard.getSVar(svarToCheck), sa);
} }
if (AllZoneUtil.compare(left, comparator, compareTo)) { if (AllZoneUtil.compare(left, comparator, compareTo)) {
@@ -93,9 +103,10 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
/** /**
* Sets the checks for run. * Sets the checks for run.
* *
* @param hasRun the hasRun to set * @param hasRun
* the hasRun to set
*/ */
public final void setHasRun(boolean hasRun) { public final void setHasRun(final boolean hasRun) {
this.hasRun = hasRun; this.hasRun = hasRun;
} }
@@ -152,19 +163,22 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
/** /**
* Can replace. * Can replace.
* *
* @param runParams the run params * @param runParams
* the run params
* @return true, if successful * @return true, if successful
*/ */
public abstract boolean canReplace(final HashMap<String, Object> runParams); public abstract boolean canReplace(final HashMap<String, Object> runParams);
/** /**
* To string.
*
* @return a String * @return a String
*/ */
@Override
public String toString() { public String toString() {
if (getMapParams().containsKey("Description") && !this.isSuppressed()) { if (this.getMapParams().containsKey("Description") && !this.isSuppressed()) {
return getMapParams().get("Description"); return this.getMapParams().get("Description");
} } else {
else {
return ""; return "";
} }
} }
@@ -379,18 +393,22 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
/** /**
* Sets the replacing objects. * Sets the replacing objects.
* *
* @param runParams the run params * @param runParams
* @param spellAbility the SpellAbility * the run params
* @param spellAbility
* the SpellAbility
*/ */
public void setReplacingObjects(HashMap<String, Object> runParams, SpellAbility spellAbility) { public void setReplacingObjects(final HashMap<String, Object> runParams, final SpellAbility spellAbility) {
// Should be overridden by replacers that need it. // Should be overridden by replacers that need it.
} }
/** /**
* Instantiates a new replacement effect. * Instantiates a new replacement effect.
* *
* @param map the map * @param map
* @param host the host * the map
* @param host
* the host
*/ */
public ReplacementEffect(final HashMap<String, String> map, final Card host) { public ReplacementEffect(final HashMap<String, String> map, final Card host) {
this.setMapParams(map); this.setMapParams(map);

View File

@@ -24,9 +24,9 @@ import java.util.List;
import forge.AllZone; import forge.AllZone;
import forge.Card; import forge.Card;
import forge.ComputerUtil; import forge.ComputerUtil;
import forge.Constant.Zone;
import forge.GameActionUtil; import forge.GameActionUtil;
import forge.Player; import forge.Player;
import forge.Constant.Zone;
import forge.card.abilityfactory.AbilityFactory; import forge.card.abilityfactory.AbilityFactory;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.gui.GuiUtils; import forge.gui.GuiUtils;
@@ -37,17 +37,19 @@ import forge.gui.GuiUtils;
*/ */
public class ReplacementHandler { public class ReplacementHandler {
private List<ReplacementEffect> tmpEffects = new ArrayList<ReplacementEffect>(); private final List<ReplacementEffect> tmpEffects = new ArrayList<ReplacementEffect>();
/** /**
* *
* Runs any applicable replacement effects. * Runs any applicable replacement effects.
* @param runParams the run params,same as for triggers. *
* @param runParams
* the run params,same as for triggers.
* @return true if the event was replaced. * @return true if the event was replaced.
*/ */
public boolean run(final HashMap<String, Object> runParams) { public boolean run(final HashMap<String, Object> runParams) {
Object affected = runParams.get("Affected"); final Object affected = runParams.get("Affected");
List<ReplacementEffect> possibleReplacers = new ArrayList<ReplacementEffect>(); final List<ReplacementEffect> possibleReplacers = new ArrayList<ReplacementEffect>();
Player decider = null; Player decider = null;
// Figure out who decides which of multiple replacements to apply // Figure out who decides which of multiple replacements to apply
@@ -58,17 +60,18 @@ public class ReplacementHandler {
decider = ((Card) affected).getController(); decider = ((Card) affected).getController();
} }
//Round up Non-static replacement effects ("Until EOT," or "The next time you would..." etc) // Round up Non-static replacement effects ("Until EOT," or
for (ReplacementEffect replacementEffect : tmpEffects) { // "The next time you would..." etc)
for (final ReplacementEffect replacementEffect : this.tmpEffects) {
if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) { if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) {
possibleReplacers.add(replacementEffect); possibleReplacers.add(replacementEffect);
} }
} }
// Round up Static replacement effects // Round up Static replacement effects
for (Player p : AllZone.getPlayersInGame()) { for (final Player p : AllZone.getPlayersInGame()) {
for (Card crd : p.getCardsIn(Zone.Battlefield)) { for (final Card crd : p.getCardsIn(Zone.Battlefield)) {
for (ReplacementEffect replacementEffect : crd.getReplacementEffects()) { for (final ReplacementEffect replacementEffect : crd.getReplacementEffects()) {
if (replacementEffect.requirementsCheck()) { if (replacementEffect.requirementsCheck()) {
if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) { if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) {
possibleReplacers.add(replacementEffect); possibleReplacers.add(replacementEffect);
@@ -90,20 +93,20 @@ public class ReplacementHandler {
if (possibleReplacers.size() > 1) { if (possibleReplacers.size() > 1) {
if (decider.isHuman()) { if (decider.isHuman()) {
chosenRE = (ReplacementEffect) GuiUtils.getChoice( chosenRE = (ReplacementEffect) GuiUtils.getChoice("Choose which replacement effect to apply.",
"Choose which replacement effect to apply.", possibleReplacers.toArray()); possibleReplacers.toArray());
} else { } else {
//AI logic for choosing which replacement effect to apply happens here. // AI logic for choosing which replacement effect to apply
// happens here.
chosenRE = possibleReplacers.get(0); chosenRE = possibleReplacers.get(0);
} }
} }
if (chosenRE != null) { if (chosenRE != null) {
if (executeReplacement(runParams, chosenRE, decider)) { if (this.executeReplacement(runParams, chosenRE, decider)) {
AllZone.getGameLog().add("ReplacementEffect", chosenRE.toString(), 2); AllZone.getGameLog().add("ReplacementEffect", chosenRE.toString(), 2);
return true; return true;
} } else {
else {
return false; return false;
} }
} else { } else {
@@ -115,20 +118,23 @@ public class ReplacementHandler {
/** /**
* *
* Runs a single replacement effect. * Runs a single replacement effect.
* @param replacementEffect the replacement effect to run *
* @param replacementEffect
* the replacement effect to run
*/ */
private boolean executeReplacement(HashMap<String, Object> runParams, ReplacementEffect replacementEffect, Player decider) { private boolean executeReplacement(final HashMap<String, Object> runParams,
final ReplacementEffect replacementEffect, final Player decider) {
HashMap<String, String> mapParams = replacementEffect.getMapParams(); final HashMap<String, String> mapParams = replacementEffect.getMapParams();
replacementEffect.setHasRun(true); replacementEffect.setHasRun(true);
SpellAbility effectSA = null; SpellAbility effectSA = null;
if (mapParams.containsKey("ReplaceWith")) { if (mapParams.containsKey("ReplaceWith")) {
String effectSVar = mapParams.get("ReplaceWith"); final String effectSVar = mapParams.get("ReplaceWith");
String effectAbString = replacementEffect.getHostCard().getSVar(effectSVar); final String effectAbString = replacementEffect.getHostCard().getSVar(effectSVar);
AbilityFactory abilityFactory = new AbilityFactory(); final AbilityFactory abilityFactory = new AbilityFactory();
effectSA = abilityFactory.getAbility(effectAbString, replacementEffect.getHostCard()); effectSA = abilityFactory.getAbility(effectAbString, replacementEffect.getHostCard());
@@ -138,12 +144,13 @@ public class ReplacementHandler {
// Decider gets to choose wether or not to apply the replacement. // Decider gets to choose wether or not to apply the replacement.
if (replacementEffect.getMapParams().containsKey("Optional")) { if (replacementEffect.getMapParams().containsKey("Optional")) {
Player optDecider = decider; Player optDecider = decider;
if (mapParams.containsKey("OptionalDecider") && effectSA != null) { if (mapParams.containsKey("OptionalDecider") && (effectSA != null)) {
optDecider = AbilityFactory.getDefinedPlayers(replacementEffect.getHostCard(), mapParams.get("OptionalDecider"), effectSA).get(0); optDecider = AbilityFactory.getDefinedPlayers(replacementEffect.getHostCard(),
mapParams.get("OptionalDecider"), effectSA).get(0);
} }
if (optDecider.isHuman()) { if (optDecider.isHuman()) {
StringBuilder buildQuestion = new StringBuilder("Apply replacement effect of "); final StringBuilder buildQuestion = new StringBuilder("Apply replacement effect of ");
buildQuestion.append(replacementEffect.getHostCard()); buildQuestion.append(replacementEffect.getHostCard());
buildQuestion.append("?\r\n("); buildQuestion.append("?\r\n(");
buildQuestion.append(replacementEffect.toString()); buildQuestion.append(replacementEffect.toString());
@@ -168,8 +175,7 @@ public class ReplacementHandler {
if (replacementEffect.getHostCard().getController().isHuman()) { if (replacementEffect.getHostCard().getController().isHuman()) {
AllZone.getGameAction().playSpellAbilityNoStack(effectSA, false); AllZone.getGameAction().playSpellAbilityNoStack(effectSA, false);
} } else {
else {
ComputerUtil.playNoStack(effectSA); ComputerUtil.playNoStack(effectSA);
} }
@@ -180,9 +186,13 @@ public class ReplacementHandler {
/** /**
* *
* Creates an instance of the proper replacement effect object based on raw script. * Creates an instance of the proper replacement effect object based on raw
* @param repParse A raw line of script * script.
* @param host The cards that hosts the replacement effect. *
* @param repParse
* A raw line of script
* @param host
* The cards that hosts the replacement effect.
* @return A finished instance * @return A finished instance
*/ */
public static ReplacementEffect parseReplacement(final String repParse, final Card host) { public static ReplacementEffect parseReplacement(final String repParse, final Card host) {
@@ -192,9 +202,13 @@ public class ReplacementHandler {
/** /**
* *
* Creates an instance of the proper replacement effect object based on a parsed script. * Creates an instance of the proper replacement effect object based on a
* @param mapParams The parsed script * parsed script.
* @param host The card that hosts the replacement effect *
* @param mapParams
* The parsed script
* @param host
* The card that hosts the replacement effect
* @return The finished instance * @return The finished instance
*/ */
public static ReplacementEffect parseReplacement(final HashMap<String, String> mapParams, final Card host) { public static ReplacementEffect parseReplacement(final HashMap<String, String> mapParams, final Card host) {

View File

@@ -102,14 +102,16 @@ public class FModel {
// TODO this single setting from preferences should not be here, or, // TODO this single setting from preferences should not be here, or,
// it should be here with all the other settings at the same time. // it should be here with all the other settings at the same time.
// Unfortunately, they're tied up in legacy code in the Display interface, // Unfortunately, they're tied up in legacy code in the Display
// currently in GuiTopLevel. When that code is updated, this TODO should be resolved. // interface,
// currently in GuiTopLevel. When that code is updated, this TODO should
// be resolved.
// Doublestrike 24-01-12 // Doublestrike 24-01-12
// == // ==
// It's looking like all the settings at the same time, here only. // It's looking like all the settings at the same time, here only.
// Doublestrike 06-02-12 // Doublestrike 06-02-12
Constant.Runtime.DEV_MODE[0] = preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED); Constant.Runtime.DEV_MODE[0] = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED);
Constant.Runtime.setSkinName(preferences.getPref(FPref.UI_SKIN)); Constant.Runtime.setSkinName(this.preferences.getPref(FPref.UI_SKIN));
// Load splash image and preloader swatches for skin // Load splash image and preloader swatches for skin
FSkin.loadLight(Constant.Runtime.getSkinName()); FSkin.loadLight(Constant.Runtime.getSkinName());
@@ -270,32 +272,56 @@ public class FModel {
} }
} }
/** @return {@link forge.model.BuildInfo} */ /**
* Gets the builds the info.
*
* @return {@link forge.model.BuildInfo}
*/
public final BuildInfo getBuildInfo() { public final BuildInfo getBuildInfo() {
return this.buildInfo; return this.buildInfo;
} }
/** @param bi0 &emsp; {@link forge.model.BuildInfo} */ /**
* Sets the builds the info.
*
* @param bi0 &emsp; {@link forge.model.BuildInfo}
*/
protected final void setBuildInfo(final BuildInfo bi0) { protected final void setBuildInfo(final BuildInfo bi0) {
this.buildInfo = bi0; this.buildInfo = bi0;
} }
/** @return {@link forge.properties.ForgePreferences} */ /**
* Gets the preferences.
*
* @return {@link forge.properties.ForgePreferences}
*/
public final ForgePreferences getPreferences() { public final ForgePreferences getPreferences() {
return this.preferences; return this.preferences;
} }
/** @return {@link forge.quest.data.QuestPreferences} */ /**
* Gets the quest preferences.
*
* @return {@link forge.quest.data.QuestPreferences}
*/
public final QuestPreferences getQuestPreferences() { public final QuestPreferences getQuestPreferences() {
return this.questPreferences; return this.questPreferences;
} }
/** @return {@link forge.model.FGameState} */ /**
* Gets the game state.
*
* @return {@link forge.model.FGameState}
*/
public final FGameState getGameState() { public final FGameState getGameState() {
return this.gameState; return this.gameState;
} }
/** @return {@link forge.game.GameSummary} */ /**
* Gets the game summary.
*
* @return {@link forge.game.GameSummary}
*/
public final GameSummary getGameSummary() { public final GameSummary getGameSummary() {
return this.gameState.getGameSummary(); return this.gameState.getGameSummary();
} }
@@ -311,12 +337,19 @@ public class FModel {
} }
/** /**
<<<<<<< HEAD
* TODO: Needs to be reworked for efficiency with rest of prefs saves in codebase. * TODO: Needs to be reworked for efficiency with rest of prefs saves in codebase.
* *
* @return a boolean. * @return a boolean.
=======
* TODO: Needs to be reworked for efficiency with rest of prefs saves in
* codebase.
*
* @return true, if successful
>>>>>>> Update Maven plugins. Checkstyle
*/ */
public final boolean savePrefs() { public final boolean savePrefs() {
final ForgePreferences fp = preferences; final ForgePreferences fp = this.preferences;
final List<ViewField> fieldViews = Singletons.getView().getMatchView().getFieldViews(); final List<ViewField> fieldViews = Singletons.getView().getMatchView().getFieldViews();
// AI field is at index [0] // AI field is at index [0]
@@ -324,8 +357,10 @@ public class FModel {
fp.setPref(FPref.PHASE_AI_DRAW, String.valueOf(fieldViews.get(0).getLblDraw().getEnabled())); fp.setPref(FPref.PHASE_AI_DRAW, String.valueOf(fieldViews.get(0).getLblDraw().getEnabled()));
fp.setPref(FPref.PHASE_AI_MAIN1, String.valueOf(fieldViews.get(0).getLblMain1().getEnabled())); fp.setPref(FPref.PHASE_AI_MAIN1, String.valueOf(fieldViews.get(0).getLblMain1().getEnabled()));
fp.setPref(FPref.PHASE_AI_BEGINCOMBAT, String.valueOf(fieldViews.get(0).getLblBeginCombat().getEnabled())); fp.setPref(FPref.PHASE_AI_BEGINCOMBAT, String.valueOf(fieldViews.get(0).getLblBeginCombat().getEnabled()));
fp.setPref(FPref.PHASE_AI_DECLAREATTACKERS, String.valueOf(fieldViews.get(0).getLblDeclareAttackers().getEnabled())); fp.setPref(FPref.PHASE_AI_DECLAREATTACKERS,
fp.setPref(FPref.PHASE_AI_DECLAREBLOCKERS, String.valueOf(fieldViews.get(0).getLblDeclareBlockers().getEnabled())); String.valueOf(fieldViews.get(0).getLblDeclareAttackers().getEnabled()));
fp.setPref(FPref.PHASE_AI_DECLAREBLOCKERS,
String.valueOf(fieldViews.get(0).getLblDeclareBlockers().getEnabled()));
fp.setPref(FPref.PHASE_AI_FIRSTSTRIKE, String.valueOf(fieldViews.get(0).getLblFirstStrike().getEnabled())); fp.setPref(FPref.PHASE_AI_FIRSTSTRIKE, String.valueOf(fieldViews.get(0).getLblFirstStrike().getEnabled()));
fp.setPref(FPref.PHASE_AI_COMBATDAMAGE, String.valueOf(fieldViews.get(0).getLblCombatDamage().getEnabled())); fp.setPref(FPref.PHASE_AI_COMBATDAMAGE, String.valueOf(fieldViews.get(0).getLblCombatDamage().getEnabled()));
fp.setPref(FPref.PHASE_AI_ENDCOMBAT, String.valueOf(fieldViews.get(0).getLblEndCombat().getEnabled())); fp.setPref(FPref.PHASE_AI_ENDCOMBAT, String.valueOf(fieldViews.get(0).getLblEndCombat().getEnabled()));
@@ -338,8 +373,10 @@ public class FModel {
fp.setPref(FPref.PHASE_HUMAN_DRAW, String.valueOf(fieldViews.get(1).getLblDraw().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_DRAW, String.valueOf(fieldViews.get(1).getLblDraw().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_MAIN1, String.valueOf(fieldViews.get(1).getLblMain1().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_MAIN1, String.valueOf(fieldViews.get(1).getLblMain1().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_BEGINCOMBAT, String.valueOf(fieldViews.get(1).getLblBeginCombat().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_BEGINCOMBAT, String.valueOf(fieldViews.get(1).getLblBeginCombat().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_DECLAREATTACKERS, String.valueOf(fieldViews.get(1).getLblDeclareAttackers().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_DECLAREATTACKERS,
fp.setPref(FPref.PHASE_HUMAN_DECLAREBLOCKERS, String.valueOf(fieldViews.get(1).getLblDeclareBlockers().getEnabled())); String.valueOf(fieldViews.get(1).getLblDeclareAttackers().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_DECLAREBLOCKERS,
String.valueOf(fieldViews.get(1).getLblDeclareBlockers().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_FIRSTSTRIKE, String.valueOf(fieldViews.get(1).getLblFirstStrike().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_FIRSTSTRIKE, String.valueOf(fieldViews.get(1).getLblFirstStrike().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_COMBATDAMAGE, String.valueOf(fieldViews.get(1).getLblCombatDamage().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_COMBATDAMAGE, String.valueOf(fieldViews.get(1).getLblCombatDamage().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_ENDCOMBAT, String.valueOf(fieldViews.get(1).getLblEndCombat().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_ENDCOMBAT, String.valueOf(fieldViews.get(1).getLblEndCombat().getEnabled()));
@@ -347,7 +384,7 @@ public class FModel {
fp.setPref(FPref.PHASE_HUMAN_EOT, String.valueOf(fieldViews.get(1).getLblEndTurn().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_EOT, String.valueOf(fieldViews.get(1).getLblEndTurn().getEnabled()));
fp.setPref(FPref.PHASE_HUMAN_CLEANUP, String.valueOf(fieldViews.get(1).getLblCleanup().getEnabled())); fp.setPref(FPref.PHASE_HUMAN_CLEANUP, String.valueOf(fieldViews.get(1).getLblCleanup().getEnabled()));
ViewTabber v = Singletons.getView().getMatchView().getViewTabber(); final ViewTabber v = Singletons.getView().getMatchView().getViewTabber();
Constant.Runtime.MILL[0] = v.getLblMilling().getEnabled(); Constant.Runtime.MILL[0] = v.getLblMilling().getEnabled();
fp.setPref(FPref.DEV_MILLING_LOSS, String.valueOf(Constant.Runtime.MILL[0])); fp.setPref(FPref.DEV_MILLING_LOSS, String.valueOf(Constant.Runtime.MILL[0]));
@@ -359,9 +396,16 @@ public class FModel {
} }
/** /**
<<<<<<< HEAD
* TODO: Needs to be reworked for efficiency with rest of prefs loads in codebase. * TODO: Needs to be reworked for efficiency with rest of prefs loads in codebase.
* *
* @return a boolean. * @return a boolean.
=======
* TODO: Needs to be reworked for efficiency with rest of prefs loads in
* codebase.
*
* @return true, if successful
>>>>>>> Update Maven plugins. Checkstyle
*/ */
public final boolean loadPrefs() { public final boolean loadPrefs() {
final ForgePreferences fp = Singletons.getModel().getPreferences(); final ForgePreferences fp = Singletons.getModel().getPreferences();
@@ -371,8 +415,8 @@ public class FModel {
Constant.Runtime.DEV_MODE[0] = fp.getPrefBoolean(FPref.DEV_MODE_ENABLED); Constant.Runtime.DEV_MODE[0] = fp.getPrefBoolean(FPref.DEV_MODE_ENABLED);
Constant.Runtime.UPLOAD_DRAFT[0] = fp.getPrefBoolean(FPref.UI_UPLOAD_DRAFT); Constant.Runtime.UPLOAD_DRAFT[0] = fp.getPrefBoolean(FPref.UI_UPLOAD_DRAFT);
Constant.Runtime.RANDOM_FOIL[0] = fp.getPrefBoolean(FPref.UI_RANDOM_FOIL); Constant.Runtime.RANDOM_FOIL[0] = fp.getPrefBoolean(FPref.UI_RANDOM_FOIL);
Constant.Runtime.UPLOAD_DRAFT[0] = Constant.Runtime.UPLOAD_DRAFT[0] = (Constant.Runtime.NET_CONN[0] ? fp.getPrefBoolean(FPref.UI_UPLOAD_DRAFT)
(Constant.Runtime.NET_CONN[0] ? fp.getPrefBoolean(FPref.UI_UPLOAD_DRAFT) : false); : false);
// AI field is at index [0] // AI field is at index [0]
fieldViews.get(0).getLblUpkeep().setEnabled(fp.getPrefBoolean(FPref.PHASE_AI_UPKEEP)); fieldViews.get(0).getLblUpkeep().setEnabled(fp.getPrefBoolean(FPref.PHASE_AI_UPKEEP));

View File

@@ -32,7 +32,8 @@ public class SectionUtil {
/** /**
* Parses the sections. * Parses the sections.
* *
* @param source the source * @param source
* the source
* @return the map * @return the map
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -78,8 +79,14 @@ public class SectionUtil {
return result; return result;
} }
public static Map<String, String> parseKvPairs(List<String> lines) { /**
Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); * Parses the kv pairs.
*
* @param lines the lines
* @return the map
*/
public static Map<String, String> parseKvPairs(final List<String> lines) {
final Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
for (final String dd : lines) { for (final String dd : lines) {
final String[] v = dd.split(":", 2); final String[] v = dd.split(":", 2);

View File

@@ -23,18 +23,13 @@ package net.slightlymagic.braids.util.lambda;
/** /**
* The Class Lambda1. * The Class Lambda1.
* *
* @param <R> * @param <R> the generic type
* the generic type
* @param <A1>
* the generic type
*/ */
public abstract class Lambda0<R> implements Lambda<R> { public abstract class Lambda0<R> implements Lambda<R> {
/** /**
* Apply. * Apply.
* *
* @param arg1
* the arg1
* @return the r * @return the r
*/ */
public abstract R apply(); public abstract R apply();
@@ -50,11 +45,13 @@ public abstract class Lambda0<R> implements Lambda<R> {
/** /**
* Apply. * Apply.
* *
* @param args Object[] * @param args
* Object[]
* @return R * @return R
*/ */
@Override
public final R apply(final Object[] args) { public final R apply(final Object[] args) {
return apply(); return this.apply();
} }
} }