diff --git a/.gitattributes b/.gitattributes index a2c069e49ab..7229ed564e4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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/desperate_charge.txt svneol=native#text/plain 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/despoil.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_empires.txt -text 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_retainer.txt -text 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/AbilityFactorySacrifice.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/AbilityFactoryTurns.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java svneol=native#text/plain diff --git a/pom.xml b/pom.xml index ffeb7d0651b..346ebf599dd 100644 --- a/pom.xml +++ b/pom.xml @@ -467,7 +467,7 @@ org.apache.maven.plugins maven-pmd-plugin - 2.7 + 2.7.1 @@ -627,7 +627,7 @@ org.apache.maven.plugins maven-pmd-plugin - 2.7 + 2.7.1 true utf-8 @@ -721,7 +721,7 @@ org.testng testng - 6.3.1 + 6.4 test diff --git a/res/cardsfolder/d/desperate_ritual.txt b/res/cardsfolder/d/desperate_ritual.txt new file mode 100644 index 00000000000..3b37bdaede7 --- /dev/null +++ b/res/cardsfolder/d/desperate_ritual.txt @@ -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 diff --git a/res/cardsfolder/t/through_the_breach.txt b/res/cardsfolder/t/through_the_breach.txt new file mode 100644 index 00000000000..53147178f19 --- /dev/null +++ b/res/cardsfolder/t/through_the_breach.txt @@ -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 \ No newline at end of file diff --git a/src/main/java/forge/ComputerUtil.java b/src/main/java/forge/ComputerUtil.java index 12798112e98..2dae1d52d97 100644 --- a/src/main/java/forge/ComputerUtil.java +++ b/src/main/java/forge/ComputerUtil.java @@ -79,7 +79,7 @@ public class ComputerUtil { if (source.hasStartOfKeyword("May be played without paying its mana cost")) { final SpellAbility newSA = sa.copy(); final Cost cost = sa.getPayCosts(); - for (CostPart part : cost.getCostParts()) { + for (final CostPart part : cost.getCostParts()) { if (part instanceof CostMana) { ((CostMana) part).setMana("0"); } @@ -189,8 +189,8 @@ public class ComputerUtil { final CostPayment pay = new CostPayment(cost, sa); if (pay.payComputerCosts()) { AllZone.getStack().addAndUnfreeze(sa); - //TODO: solve problems with TapsForMana triggers by adding - // sources tapped here if possible (ArsenalNut) + // TODO: solve problems with TapsForMana triggers by adding + // sources tapped here if possible (ArsenalNut) } } } @@ -408,7 +408,7 @@ public class ComputerUtil { public static final void playSpellAbilityWithoutPayingManaCost(final SpellAbility sa) { final SpellAbility newSA = sa.copy(); final Cost cost = sa.getPayCosts(); - for (CostPart part : cost.getCostParts()) { + for (final CostPart part : cost.getCostParts()) { if (part instanceof CostMana) { ((CostMana) part).setMana("0"); } @@ -420,7 +420,7 @@ public class ComputerUtil { newSA.setDescription(sb.toString()); newSA.setActivatingPlayer(AllZone.getComputerPlayer()); - if (!canPayAdditionalCosts(newSA)) { + if (!ComputerUtil.canPayAdditionalCosts(newSA)) { return; } @@ -624,7 +624,7 @@ public class ComputerUtil { 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); } @@ -658,7 +658,7 @@ public class ComputerUtil { // Make mana needed to avoid negative effect a mandatory cost for the AI if (card.getSVar("ManaNeededToAvoidNegativeEffect") != "") { - String[] negEffects = card.getSVar("ManaNeededToAvoidNegativeEffect").split(","); + final 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 @@ -667,13 +667,14 @@ public class ComputerUtil { } // make mana mandatory for AI if (!cost.isColor(negEffects[nStr])) { - cost.combineManaCost(negEffects[nStr]); - amountAdded++; + 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) + // 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); } @@ -687,37 +688,34 @@ public class ComputerUtil { } // get map of mana abilities - HashMap> manaAbilityMap = mapManaSources(player); + final HashMap> manaAbilityMap = ComputerUtil.mapManaSources(player); // initialize ArrayList list for mana needed - ArrayList> partSources = - new ArrayList>(); - ArrayList partPriority = new ArrayList(); - String[] costParts = cost.toString().replace("X ", "").replace("P", "").split(" "); + final ArrayList> partSources = new ArrayList>(); + final ArrayList partPriority = new ArrayList(); + final String[] costParts = cost.toString().replace("X ", "").replace("P", "").split(" "); Boolean foundAllSources = true; if (manaAbilityMap.isEmpty()) { foundAllSources = false; - } - else { - String[] shortColors = {"W", "U", "B" , "R", "G"}; + } else { + final String[] shortColors = { "W", "U", "B", "R", "G" }; // loop over cost parts for (int nPart = 0; nPart < costParts.length; nPart++) { - ArrayList srcFound = new ArrayList(); + final ArrayList srcFound = new ArrayList(); // 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 + if (costParts[nPart].matches("[0-9]+")) { // Colorless srcFound.addAll(manaAbilityMap.get("1")); - } - else if (costParts[nPart].contains("/")) { // Split - String colorKey = costParts[nPart].replace("2/", ""); + } else if (costParts[nPart].contains("/")) { // Split + final 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) { + for (final String color : shortColors) { if (!colorKey.contains(color)) { // Is source available? if (manaAbilityMap.containsKey(color)) { @@ -725,30 +723,25 @@ public class ComputerUtil { } } } - } - 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); + } else if (costParts[nPart].length() > 1) { // Hybrid + final String firstColor = costParts[nPart].substring(0, 1); + final String secondColor = costParts[nPart].substring(1); + final Boolean foundFirst = manaAbilityMap.containsKey(firstColor); + final Boolean foundSecond = manaAbilityMap.containsKey(secondColor); if (foundFirst || foundSecond) { if (!foundFirst) { srcFound.addAll(manaAbilityMap.get(secondColor)); - } - else if (!foundSecond) { + } else if (!foundSecond) { 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(secondColor)); - } - else { + } else { srcFound.addAll(manaAbilityMap.get(secondColor)); srcFound.addAll(manaAbilityMap.get(firstColor)); } } - } - else { // single color + } else { // single color if (manaAbilityMap.containsKey(costParts[nPart])) { srcFound.addAll(manaAbilityMap.get(costParts[nPart])); } @@ -765,8 +758,7 @@ public class ComputerUtil { } } partPriority.add(i, nPart); - } - else { + } else { foundAllSources = false; break; } @@ -775,25 +767,28 @@ public class ComputerUtil { if (!foundAllSources) { if (!test) { // 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 return false; } // Create array to keep track of sources used - ArrayList usedSources = new ArrayList(); - //this is to prevent errors for mana sources that have abilities that cost mana. + final ArrayList usedSources = new ArrayList(); + // 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 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(); + final int nPart = partPriority.get(nPriority); + final ArrayList manaAbilities = partSources.get(nPart); + final ManaCost costPart = new ManaCost(costParts[nPart]); + // Loop over mana abilities that can be used to current mana cost + // part + for (final AbilityMana m : manaAbilities) { + final Card sourceCard = m.getSourceCard(); // Check if source has already been used if (usedSources.contains(sourceCard)) { @@ -802,26 +797,26 @@ public class ComputerUtil { // Check if AI can still play this mana ability 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 (!canPayAdditionalCosts(m, player)) { + if (!ComputerUtil.canPayAdditionalCosts(m, player)) { continue; } } else if (sourceCard.isTapped()) { continue; } - String manaProduced; + String manaProduced; // Check if paying snow mana if ("S".equals(costParts[nPart])) { manaProduced = "S"; - } - else { + } else { // check if ability produces any color if (m.isAnyMana()) { String colorChoice = costParts[nPart]; - ArrayList negEffect = cost.getManaNeededToAvoidNegativeEffect(); - ArrayList negEffectPaid = cost.getManaPaidToAvoidNegativeEffect(); + final ArrayList negEffect = cost.getManaNeededToAvoidNegativeEffect(); + final ArrayList negEffectPaid = cost.getManaPaidToAvoidNegativeEffect(); // Check for // 1) Colorless // 2) Split e.g. 2/G @@ -834,15 +829,13 @@ public class ComputerUtil { break; } } - } - else if (costParts[nPart].contains("/")) { + } else if (costParts[nPart].contains("/")) { colorChoice = costParts[nPart].replace("2/", ""); - } - else if (costParts[nPart].length() > 1) { + } 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))) { + && !negEffectPaid.contains(negEffect.get(n))) { colorChoice = negEffect.get(n); break; } @@ -860,28 +853,26 @@ public class ComputerUtil { // add source card to used list usedSources.add(sourceCard); - //TODO: Change this if AI is able use to mana abilities that - // produce more than one mana (111230 - ArsenalNut) - String color = InputPayManaCostUtil.getLongColorString(manaProduced); + // TODO: Change this if AI is able use to mana abilities that + // produce more than one mana (111230 - ArsenalNut) + final String color = InputPayManaCostUtil.getLongColorString(manaProduced); costPart.payMana(color); if (!test) { - //Pay additional costs + // Pay additional costs if (m.getPayCosts() != null) { - CostPayment pay = new CostPayment(m.getPayCosts(), m); + final CostPayment pay = new CostPayment(m.getPayCosts(), m); if (!pay.payComputerCosts()) { continue; } - } - else { + } else { sourceCard.tap(); } // resolve mana ability m.resolve(); // subtract mana from mana pool cost = manapool.subtractMana(sa, cost, m); - } - else { + } else { cost.payMana(color); } // check if cost part is paid @@ -891,8 +882,7 @@ public class ComputerUtil { } // end of mana ability loop if (!costPart.isPaid() || cost.isPaid()) { break; - } - else { + } else { nPriority++; } @@ -901,7 +891,7 @@ public class ComputerUtil { manapool.clearPay(sa, test); // check if paid if (cost.isPaid()) { - //if (sa instanceof Spell_Permanent) // should probably add this + // if (sa instanceof Spell_Permanent) // should probably add this sa.getSourceCard().setColorsPaid(cost.getColorsPaid()); sa.getSourceCard().setSunburstValue(cost.getSunburst()); return true; @@ -972,7 +962,6 @@ public class ComputerUtil { return ComputerUtil.getAvailableMana(AllZone.getComputerPlayer()); } // getAvailableMana() - // gets available mana sources and sorts them /** *

@@ -1059,28 +1048,21 @@ public class ComputerUtil { if (needsLimitedResources) { otherManaSources.add(card); - } - else if (producesAnyColor) { + } else if (producesAnyColor) { anyColorManaSources.add(card); - } - else if (usableManaAbilities == 1) { + } else if (usableManaAbilities == 1) { if (manaAbilities.get(0).mana().equals("1")) { colorlessManaSources.add(card); - } - else { + } else { oneManaSources.add(card); } - } - else if (usableManaAbilities == 2) { + } else if (usableManaAbilities == 2) { twoManaSources.add(card); - } - else if (usableManaAbilities == 3) { + } else if (usableManaAbilities == 3) { threeManaSources.add(card); - } - else if (usableManaAbilities == 4) { + } else if (usableManaAbilities == 4) { fourManaSources.add(card); - } - else { + } else { fiveManaSources.add(card); } @@ -1166,34 +1148,37 @@ public class ComputerUtil { } /** - *

mapManaSources.

- * - * @param player a {@link forge.Player} object. + *

+ * mapManaSources. + *

+ * + * @param player + * a {@link forge.Player} object. * @return HashMap - */ - public static HashMap> mapManaSources(final Player player) { - HashMap> manaMap = new HashMap>(); + */ + public static HashMap> mapManaSources(final Player player) { + final HashMap> manaMap = new HashMap>(); - ArrayList whiteSources = new ArrayList(); - ArrayList blueSources = new ArrayList(); - ArrayList blackSources = new ArrayList(); - ArrayList redSources = new ArrayList(); - ArrayList greenSources = new ArrayList(); - ArrayList colorlessSources = new ArrayList(); - ArrayList snowSources = new ArrayList(); + final ArrayList whiteSources = new ArrayList(); + final ArrayList blueSources = new ArrayList(); + final ArrayList blackSources = new ArrayList(); + final ArrayList redSources = new ArrayList(); + final ArrayList greenSources = new ArrayList(); + final ArrayList colorlessSources = new ArrayList(); + final ArrayList snowSources = new ArrayList(); // 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 manaAbilities = sourceCard.getAIPlayableMana(); + final Card sourceCard = manaSources.get(i); + final ArrayList manaAbilities = sourceCard.getAIPlayableMana(); // 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().chkAIDrawback()) { continue; @@ -1251,7 +1236,7 @@ public class ComputerUtil { return manaMap; } - //plays a land if one is available + // plays a land if one is available /** *

* chooseLandsToPlay. @@ -1784,13 +1769,16 @@ public class ComputerUtil { *

* sacrificePermanents. *

- * - * @param amount a int. - * @param list a {@link forge.CardList} object. - * @param destroy the destroy + * + * @param amount + * a int. + * @param list + * a {@link forge.CardList} object. + * @param destroy + * the destroy * @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(); // used in Annihilator and AF_Sacrifice int max = list.size(); @@ -1805,7 +1793,7 @@ public class ComputerUtil { Card c = null; if (destroy) { - CardList indestructibles = list.getKeyword("Indestructible"); + final CardList indestructibles = list.getKeyword("Indestructible"); if (!indestructibles.isEmpty()) { c = indestructibles.get(0); } @@ -1952,29 +1940,41 @@ public class ComputerUtil { return prevented; } - public static boolean containsUsefulKeyword(final ArrayList keywords, Card card) { + /** + * Contains useful keyword. + * + * @param keywords the keywords + * @param card the card + * @return true, if successful + */ + public static boolean containsUsefulKeyword(final ArrayList keywords, final Card card) { for (final String keyword : keywords) { - if (isUsefulKeyword(keyword, card)) { + if (ComputerUtil.isUsefulKeyword(keyword, card)) { return true; } } 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)) { return false; } if (keyword.equals("Defender") || keyword.endsWith("CARDNAME can't attack.")) { if (card.getController().isComputer() || AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) - || !CombatUtil.canAttack(card) - || card.getNetCombatDamage() <= 0) { + || !CombatUtil.canAttack(card) || (card.getNetCombatDamage() <= 0)) { return false; } } else if (keyword.contains("CARDNAME can't block.")) { - if (card.getController().isComputer() - || AllZone.getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer()) + if (card.getController().isComputer() || AllZone.getPhaseHandler().isPlayerTurn(AllZone.getHumanPlayer()) || !CombatUtil.canBlock(card)) { return false; } @@ -1984,8 +1984,7 @@ public class ComputerUtil { return false; } } else if (keyword.endsWith("CARDNAME attacks each turn if able.")) { - if (AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) - || !CombatUtil.canAttack(card) + if (AllZone.getPhaseHandler().isPlayerTurn(AllZone.getComputerPlayer()) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card)) { return false; } diff --git a/src/main/java/forge/PhaseHandler.java b/src/main/java/forge/PhaseHandler.java index d4493bee446..7f014b4662c 100644 --- a/src/main/java/forge/PhaseHandler.java +++ b/src/main/java/forge/PhaseHandler.java @@ -347,7 +347,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { 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)) { if (this.inCombat()) { PhaseUtil.verifyCombat(); @@ -411,8 +412,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { AllZone.getEndOfCombat().executeAt(); CombatUtil.showCombat(); Singletons.getControl().getMatchControl().showStack(); - } - else if (phase.equals(Constant.Phase.MAIN2)) { + } else if (phase.equals(Constant.Phase.MAIN2)) { CombatUtil.showCombat(); 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 // this to handleBeginPhase if (this.getPhase().equals(Constant.Phase.UNTAP)) { this.turn++; - AllZone.getGameLog().add("Turn", "Turn " + turn + " (" + getPlayerTurn() + ")", 0); + AllZone.getGameLog().add("Turn", "Turn " + this.turn + " (" + this.getPlayerTurn() + ")", 0); } PhaseUtil.visuallyActivatePhase(this.getPhase()); @@ -951,8 +951,8 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { */ public static boolean canCastSorcery(final Player player) { return AllZone.getPhaseHandler().isPlayerTurn(player) - && (AllZone.getPhaseHandler().getPhase().equals(Constant.Phase.MAIN2) || AllZone.getPhaseHandler().getPhase() - .equals(Constant.Phase.MAIN1)) && (AllZone.getStack().size() == 0); + && (AllZone.getPhaseHandler().getPhase().equals(Constant.Phase.MAIN2) || AllZone.getPhaseHandler() + .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); } + /** + * Sets the phase state. + * + * @param phaseID the new phase state + */ public final void setPhaseState(final String phaseID) { this.phaseIndex = this.findIndex(phaseID); this.handleBeginPhase(); diff --git a/src/main/java/forge/Player.java b/src/main/java/forge/Player.java index f7094518030..e3d29639af7 100644 --- a/src/main/java/forge/Player.java +++ b/src/main/java/forge/Player.java @@ -57,7 +57,7 @@ public abstract class Player extends GameEntity { private int startingLife; /** The assigned damage. */ - private Map assignedDamage = new HashMap(); + private final Map assignedDamage = new HashMap(); /** The life lost this turn. */ private int lifeLostThisTurn = 0; @@ -168,7 +168,7 @@ public abstract class Player extends GameEntity { */ public final void reset() { this.life = 20; - lifeLostThisTurn = 0; + this.lifeLostThisTurn = 0; this.poisonCounters = 0; this.assignedDamage.clear(); this.setPreventNextDamage(0); @@ -265,10 +265,11 @@ 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 - * a int. + * a int. */ public final void setStartingLife(final int startLife) { this.startingLife = startLife; @@ -323,8 +324,8 @@ public abstract class Player extends GameEntity { */ public final boolean gainLife(final int toGain, final Card source) { - //Run any applicable replacement effects. - HashMap repParams = new HashMap(); + // Run any applicable replacement effects. + final HashMap repParams = new HashMap(); repParams.put("Event", "GainLife"); repParams.put("Affected", this); repParams.put("LifeGained", toGain); @@ -336,7 +337,7 @@ public abstract class Player extends GameEntity { if (!this.canGainLife()) { return false; } - int lifeGain = toGain; + final int lifeGain = toGain; if (lifeGain > 0) { this.addLife(lifeGain); @@ -363,8 +364,8 @@ public abstract class Player extends GameEntity { * @return a boolean. */ public final boolean canGainLife() { - if (AllZoneUtil.isCardInPlay("Leyline of Punishment") - || AllZoneUtil.isCardInPlay("Platinum Emperion", this) || AllZoneUtil.isCardInPlay("Forsaken Wastes")) { + if (AllZoneUtil.isCardInPlay("Leyline of Punishment") || AllZoneUtil.isCardInPlay("Platinum Emperion", this) + || AllZoneUtil.isCardInPlay("Forsaken Wastes")) { return false; } return true; @@ -505,9 +506,9 @@ public abstract class Player extends GameEntity { 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."); - if (this.getLife() <= 0 && !infect) { - CardList cards = this.getCardsIn(Zone.Battlefield); - for (Card card : cards) { + if ((this.getLife() <= 0) && !infect) { + final CardList cards = this.getCardsIn(Zone.Battlefield); + for (final Card card : cards) { if (card.hasKeyword(sb.toString())) { infect = true; 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 // 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 /** *

* staticReplaceDamage. @@ -678,21 +680,21 @@ public abstract class Player extends GameEntity { restDamage += 2; } } -// + // if (AllZoneUtil.isCardInPlay("Furnace of Rath")) { final int amount = AllZoneUtil.getCardsIn(Zone.Battlefield, "Furnace of Rath").size(); for (int i = 0; i < amount; i++) { restDamage += restDamage; } } -// + // if (AllZoneUtil.isCardInPlay("Gratuitous Violence", source.getController()) && source.isCreature()) { final int amount = source.getController().getCardsIn(Zone.Battlefield, "Gratuitous Violence").size(); for (int i = 0; i < amount; i++) { restDamage += restDamage; } } -// + // if (AllZoneUtil.isCardInPlay("Fire Servant", source.getController()) && source.isRed() && (source.isInstant() || source.isSorcery())) { final int amount = source.getController().getCardsIn(Zone.Battlefield, "Fire Servant").size(); @@ -716,7 +718,7 @@ public abstract class Player extends GameEntity { restDamage = 3; } -// + // if (AllZoneUtil.isCardInPlay("Forethought Amulet", this) && (source.isInstant() || source.isSorcery()) && (restDamage > 2)) { @@ -742,8 +744,8 @@ public abstract class Player extends GameEntity { @Override public final int replaceDamage(final int damage, final Card source, final boolean isCombat) { - //Replacement effects - HashMap repParams = new HashMap(); + // Replacement effects + final HashMap repParams = new HashMap(); repParams.put("Event", "DamageDone"); repParams.put("Affected", this); repParams.put("DamageSource", source); @@ -848,7 +850,7 @@ public abstract class Player extends GameEntity { */ public final int getAssignedDamage() { int num = 0; - for (Integer value : assignedDamage.values()) { + for (final Integer value : this.assignedDamage.values()) { num += value; } return num; @@ -864,15 +866,15 @@ public abstract class Player extends GameEntity { * * @return a int. */ - public final int getAssignedDamage(String type) { - Map valueMap = new HashMap(); - for (Card c : assignedDamage.keySet()) { + public final int getAssignedDamage(final String type) { + final Map valueMap = new HashMap(); + for (final Card c : this.assignedDamage.keySet()) { if (c.isType(type)) { - valueMap.put(c, assignedDamage.get(c)); + valueMap.put(c, this.assignedDamage.get(c)); } } int num = 0; - for (Integer value : valueMap.values()) { + for (final Integer value : valueMap.values()) { num += value; } return num; @@ -915,9 +917,11 @@ public abstract class Player extends GameEntity { *

* addPoisonCounters. *

- * - * @param num a int. - * @param source the source + * + * @param num + * a int. + * @param source + * the source */ public final void addPoisonCounters(final int num, final Card source) { if (!this.hasKeyword("You can't get poison counters")) { @@ -1242,8 +1246,8 @@ public abstract class Player extends GameEntity { final CardList drawn = new CardList(); final PlayerZone library = this.getZone(Constant.Zone.Library); - //Replacement effects - HashMap repRunParams = new HashMap(); + // Replacement effects + final HashMap repRunParams = new HashMap(); repRunParams.put("Event", "Draw"); repRunParams.put("Affected", this); @@ -1257,10 +1261,10 @@ public abstract class Player extends GameEntity { c = AllZone.getGameAction().moveToHand(c); drawn.add(c); - if (numDrawnThisTurn == 0 && this.isComputer()) { + if ((this.numDrawnThisTurn == 0) && this.isComputer()) { boolean reveal = false; - CardList cards = this.getCardsIn(Zone.Battlefield); - for (Card card : cards) { + final CardList cards = this.getCardsIn(Zone.Battlefield); + for (final Card card : cards) { if (card.hasKeyword("Reveal the first card you draw each turn")) { reveal = true; break; @@ -1278,7 +1282,7 @@ public abstract class Player extends GameEntity { // Run triggers final HashMap runParams = new HashMap(); runParams.put("Card", c); - runParams.put("Number", numDrawnThisTurn); + runParams.put("Number", this.numDrawnThisTurn); AllZone.getTriggerHandler().runTrigger("Drawn", runParams); } // lose: @@ -1790,7 +1794,7 @@ public abstract class Player extends GameEntity { // etc...) AllZone.getGameAction().checkStateEffects(); - //add to log + // add to log AllZone.getGameLog().add("Land", this + " played " + land, 2); // Run triggers @@ -1810,7 +1814,8 @@ public abstract class Player extends GameEntity { * @return a boolean. */ 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); } @@ -2145,8 +2150,8 @@ public abstract class Player extends GameEntity { return false; } - //Replacement effects - HashMap runParams = new HashMap(); + // Replacement effects + final HashMap runParams = new HashMap(); runParams.put("Affected", this); runParams.put("Event", "GameLoss"); @@ -2241,7 +2246,7 @@ public abstract class Player extends GameEntity { } if (this.lossState != GameLossReason.DidNotLoseYet) { - return this.loseConditionMet(lossState, null); + return this.loseConditionMet(this.lossState, null); } if (this.poisonCounters >= 10) { @@ -2374,11 +2379,11 @@ public abstract class Player extends GameEntity { return false; } } else if (incR[0].equals("EnchantedController")) { - GameEntity enchanted = source.getEnchanting(); - if (enchanted == null || !(enchanted instanceof Card)) { + final GameEntity enchanted = source.getEnchanting(); + if ((enchanted == null) || !(enchanted instanceof Card)) { return false; } - Card enchantedCard = (Card) enchanted; + final Card enchantedCard = (Card) enchanted; if (!this.equals(enchantedCard.getController())) { return false; } @@ -2730,6 +2735,9 @@ public abstract class Player extends GameEntity { return this.mustAttackEntity; } + /** + * Update label observers. + */ public final void updateLabelObservers() { this.getZone(Zone.Hand).updateObservers(); } diff --git a/src/main/java/forge/Upkeep.java b/src/main/java/forge/Upkeep.java index e946c133144..1bcf5d209dc 100644 --- a/src/main/java/forge/Upkeep.java +++ b/src/main/java/forge/Upkeep.java @@ -486,8 +486,11 @@ public class Upkeep extends Phase implements java.io.Serializable { @Override public void showMessage() { - Singletons.getControl().getMatchControl().showMessage( - abyss.getName() + " - Select one nonartifact creature to destroy"); + Singletons + .getControl() + .getMatchControl() + .showMessage( + abyss.getName() + " - Select one nonartifact creature to destroy"); ButtonUtil.disableAll(); } @@ -554,8 +557,11 @@ public class Upkeep extends Phase implements java.io.Serializable { @Override public void showMessage() { - Singletons.getControl().getMatchControl().showMessage( - "Yawgmoth Demon - Select one artifact to sacrifice or be dealt 2 damage"); + Singletons + .getControl() + .getMatchControl() + .showMessage( + "Yawgmoth Demon - Select one artifact to sacrifice or be dealt 2 damage"); ButtonUtil.enableOnlyCancel(); } @@ -2252,8 +2258,8 @@ public class Upkeep extends Phase implements java.io.Serializable { private static void upkeepVesuvanDoppelgangerKeyword() { final Player player = AllZone.getPhaseHandler().getPlayerTurn(); final String keyword = "At the beginning of your upkeep, you may have this " - + "creature become a copy of target creature except it doesn't copy that " - + "creature's color. If you do, this creature gains this ability."; + + "creature become a copy of target creature except it doesn't copy that " + + "creature's color. If you do, this creature gains this ability."; CardList list = player.getCardsIn(Zone.Battlefield); list = list.getKeyword(keyword); @@ -2261,7 +2267,7 @@ public class Upkeep extends Phase implements java.io.Serializable { final SpellAbility ability = new Ability(c, "0") { @Override public void resolve() { - StringBuilder question = new StringBuilder(); + final StringBuilder question = new StringBuilder(); question.append("Use triggered ability of ").append(c).append("?"); question.append("\r\n").append("(").append(keyword).append(")").append("\r\n"); if (GameActionUtil.showYesNoDialog(c, question.toString(), true)) { @@ -2274,14 +2280,14 @@ public class Upkeep extends Phase implements java.io.Serializable { if (newTarget[0] != null) { /* - * 1. need to select new card - DONE 1a. need to - * create the newly copied card with pic and - * setinfo 2. need to add the leaves play - * command 3. need to transfer the keyword 4. - * need to update the clone origin of new card - * and old card 5. remove clone leaves play - * commands from old 5a. remove old from play 6. - * add new to play + * 1. need to select new card - DONE 1a. + * need to create the newly copied card with + * pic and setinfo 2. need to add the leaves + * play command 3. need to transfer the + * keyword 4. need to update the clone + * origin of new card and old card 5. remove + * clone leaves play commands from old 5a. + * remove old from play 6. add new to play */ final Card newCopy = AllZone.getCardFactory().getCard( @@ -2308,8 +2314,8 @@ public class Upkeep extends Phase implements java.io.Serializable { @Override public void showMessage() { - Singletons.getControl().getMatchControl().showMessage( - c.getName() + " - Select target creature."); + Singletons.getControl().getMatchControl() + .showMessage(c.getName() + " - Select target creature."); ButtonUtil.enableOnlyCancel(); } @@ -2382,9 +2388,14 @@ public class Upkeep extends Phase implements java.io.Serializable { this.stop(); return; } - Singletons.getControl().getMatchControl().showMessage( - source.getName() + " - Select " + num - + " untapped artifact(s), creature(s), or land(s) you control"); + Singletons + .getControl() + .getMatchControl() + .showMessage( + source.getName() + + " - Select " + + num + + " untapped artifact(s), creature(s), or land(s) you control"); ButtonUtil.disableAll(); } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactorySplice.java b/src/main/java/forge/card/abilityfactory/AbilityFactorySplice.java new file mode 100644 index 00000000000..858968481ff --- /dev/null +++ b/src/main/java/forge/card/abilityfactory/AbilityFactorySplice.java @@ -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 . + */ +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. + +/** + *

+ * AbilityFactorySplice class. + *

+ * + * @author Forge + * @version $Id$ + */ +public class AbilityFactorySplice { + + private AbilityFactory abilityFactory = null; + private HashMap params = null; + private String unlessCost = null; + + /** + *

+ * Constructor for AbilityFactorySplice. + *

+ * + * @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(); + } + + } + + /** + *

+ * getAbilitySplice. + *

+ * + * @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; + } + + /** + *

+ * getSpellSplice. + *

+ * + * @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; + } + + /** + *

+ * getDrawbackSplice. + *

+ * + * @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; + } + + /** + *

+ * spliceCanPlayAI. + *

+ * + * @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; + } + + /** + *

+ * spliceDoTriggerAI. + *

+ * + * @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; + } + + /** + *

+ * spliceResolve. + *

+ * + * @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 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 + + /** + *

+ * spliceStackDescription. + *

+ * + * @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 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 + + /** + *

+ * removeFromStack. + *

+ * + * @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 diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java index 2d0c32a0331..31b4291830a 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java @@ -293,8 +293,14 @@ public class AbilityFactoryTurns { // ************************* END TURN ************************************** // ************************************************************************* + /** + * Creates the ability end turn. + * + * @param af the af + * @return the spell ability + */ 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; @@ -309,7 +315,7 @@ public class AbilityFactoryTurns { } @Override - public boolean doTrigger(boolean mandatory) { + public boolean doTrigger(final boolean mandatory) { if (mandatory) { return true; } @@ -319,7 +325,7 @@ public class AbilityFactoryTurns { @Override public void resolve() { - endTurnResolve(af, this); + AbilityFactoryTurns.endTurnResolve(af, this); } }; @@ -327,8 +333,14 @@ public class AbilityFactoryTurns { return ret; } + /** + * Creates the spell end turn. + * + * @param af the af + * @return the spell ability + */ 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; @@ -344,7 +356,7 @@ public class AbilityFactoryTurns { @Override public void resolve() { - endTurnResolve(af, this); + AbilityFactoryTurns.endTurnResolve(af, this); } }; @@ -352,6 +364,12 @@ public class AbilityFactoryTurns { return ret; } + /** + * Creates the drawback end turn. + * + * @param af the af + * @return the spell ability + */ public static SpellAbility createDrawbackEndTurn(final AbilityFactory af) { final SpellAbility dbEndTurn = new AbilitySub(af.getHostCard(), af.getAbTgt()) { private static final long serialVersionUID = -562517287448810951L; @@ -386,24 +404,28 @@ public class AbilityFactoryTurns { private static void endTurnResolve(final AbilityFactory af, final SpellAbility sa) { - //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. - for (Card c : AllZone.getStackZone().getCards()) { + // 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. + for (final Card c : AllZone.getStackZone().getCards()) { AllZone.getGameAction().exile(c); } AllZone.getStack().getStack().clear(); - //2) All attacking and blocking creatures are removed from combat. + // 2) All attacking and blocking creatures are removed from combat. AllZone.getCombat().resetAttackers(); 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(); - //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); - //Update observers + // Update observers AllZone.getStack().updateObservers(); AllZone.getComputerPlayer().updateObservers(); AllZone.getHumanPlayer().updateObservers(); diff --git a/src/main/java/forge/card/replacement/ReplacementEffect.java b/src/main/java/forge/card/replacement/ReplacementEffect.java index 40db45b59fc..ffc5e11fc5d 100644 --- a/src/main/java/forge/card/replacement/ReplacementEffect.java +++ b/src/main/java/forge/card/replacement/ReplacementEffect.java @@ -29,9 +29,9 @@ import forge.card.abilityfactory.AbilityFactory; import forge.card.cardfactory.CardFactoryUtil; import forge.card.spellability.SpellAbility; -/** +/** * TODO: Write javadoc for this type. - * + * */ public abstract class ReplacementEffect extends TriggerReplacementBase { @@ -40,45 +40,55 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { /** * Checks for run. - * + * * @return the hasRun */ public final boolean hasRun() { - return hasRun; + return this.hasRun; } - + + /** + * Checks if is secondary. + * + * @return true, if is secondary + */ 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) { - if (mapParams.containsKey("AICheckSVar")) { - String svarToCheck = mapParams.get("AICheckSVar"); + if (this.mapParams.containsKey("AICheckSVar")) { + final String svarToCheck = this.mapParams.get("AICheckSVar"); String comparator = "GE"; int compareTo = 1; - if (mapParams.containsKey("AISVarCompare")) { - String fullCmp = mapParams.get("AISVarCompare"); + if (this.mapParams.containsKey("AISVarCompare")) { + final String fullCmp = this.mapParams.get("AISVarCompare"); comparator = fullCmp.substring(0, 2); - String strCmpTo = fullCmp.substring(2); + final String strCmpTo = fullCmp.substring(2); try { compareTo = Integer.parseInt(strCmpTo); - } - catch (Exception ignored) { + } catch (final Exception ignored) { if (sa == null) { - compareTo = CardFactoryUtil.xCount(hostCard, hostCard.getSVar(strCmpTo)); + compareTo = CardFactoryUtil.xCount(this.hostCard, this.hostCard.getSVar(strCmpTo)); } else { - compareTo = AbilityFactory.calculateAmount(hostCard, hostCard.getSVar(strCmpTo), sa); + compareTo = AbilityFactory.calculateAmount(this.hostCard, this.hostCard.getSVar(strCmpTo), sa); } } } int left = 0; - if (sa == null) { - left = CardFactoryUtil.xCount(hostCard, hostCard.getSVar(svarToCheck)); + if (sa == null) { + left = CardFactoryUtil.xCount(this.hostCard, this.hostCard.getSVar(svarToCheck)); } 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)) { @@ -92,10 +102,11 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { /** * 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; } @@ -151,20 +162,23 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { /** * Can replace. - * - * @param runParams the run params + * + * @param runParams + * the run params * @return true, if successful */ public abstract boolean canReplace(final HashMap runParams); /** + * To string. + * * @return a String */ + @Override public String toString() { - if (getMapParams().containsKey("Description") && !this.isSuppressed()) { - return getMapParams().get("Description"); - } - else { + if (this.getMapParams().containsKey("Description") && !this.isSuppressed()) { + return this.getMapParams().get("Description"); + } else { return ""; } } @@ -371,26 +385,30 @@ public abstract class ReplacementEffect extends TriggerReplacementBase { /** * Gets the copy. - * + * * @return the copy */ public abstract ReplacementEffect getCopy(); /** * Sets the replacing objects. - * - * @param runParams the run params - * @param spellAbility the SpellAbility + * + * @param runParams + * the run params + * @param spellAbility + * the SpellAbility */ - public void setReplacingObjects(HashMap runParams, SpellAbility spellAbility) { - //Should be overridden by replacers that need it. + public void setReplacingObjects(final HashMap runParams, final SpellAbility spellAbility) { + // Should be overridden by replacers that need it. } /** * Instantiates a new replacement effect. - * - * @param map the map - * @param host the host + * + * @param map + * the map + * @param host + * the host */ public ReplacementEffect(final HashMap map, final Card host) { this.setMapParams(map); diff --git a/src/main/java/forge/card/replacement/ReplacementHandler.java b/src/main/java/forge/card/replacement/ReplacementHandler.java index 567bf660533..392393f92fc 100644 --- a/src/main/java/forge/card/replacement/ReplacementHandler.java +++ b/src/main/java/forge/card/replacement/ReplacementHandler.java @@ -24,51 +24,54 @@ import java.util.List; import forge.AllZone; import forge.Card; import forge.ComputerUtil; +import forge.Constant.Zone; import forge.GameActionUtil; import forge.Player; -import forge.Constant.Zone; import forge.card.abilityfactory.AbilityFactory; import forge.card.spellability.SpellAbility; import forge.gui.GuiUtils; -/** +/** * TODO: Write javadoc for this type. - * + * */ public class ReplacementHandler { - private List tmpEffects = new ArrayList(); + private final List tmpEffects = new ArrayList(); /** * * 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. */ public boolean run(final HashMap runParams) { - Object affected = runParams.get("Affected"); - List possibleReplacers = new ArrayList(); + final Object affected = runParams.get("Affected"); + final List possibleReplacers = new ArrayList(); Player decider = null; - //Figure out who decides which of multiple replacements to apply - //as well as whether or not to apply optional replacements. + // Figure out who decides which of multiple replacements to apply + // as well as whether or not to apply optional replacements. if (affected instanceof Player) { decider = (Player) affected; } else { decider = ((Card) affected).getController(); } - //Round up Non-static replacement effects ("Until EOT," or "The next time you would..." etc) - for (ReplacementEffect replacementEffect : tmpEffects) { + // Round up Non-static replacement effects ("Until EOT," or + // "The next time you would..." etc) + for (final ReplacementEffect replacementEffect : this.tmpEffects) { if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) { possibleReplacers.add(replacementEffect); } } - //Round up Static replacement effects - for (Player p : AllZone.getPlayersInGame()) { - for (Card crd : p.getCardsIn(Zone.Battlefield)) { - for (ReplacementEffect replacementEffect : crd.getReplacementEffects()) { + // Round up Static replacement effects + for (final Player p : AllZone.getPlayersInGame()) { + for (final Card crd : p.getCardsIn(Zone.Battlefield)) { + for (final ReplacementEffect replacementEffect : crd.getReplacementEffects()) { if (replacementEffect.requirementsCheck()) { if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) { possibleReplacers.add(replacementEffect); @@ -90,20 +93,20 @@ public class ReplacementHandler { if (possibleReplacers.size() > 1) { if (decider.isHuman()) { - chosenRE = (ReplacementEffect) GuiUtils.getChoice( - "Choose which replacement effect to apply.", possibleReplacers.toArray()); + chosenRE = (ReplacementEffect) GuiUtils.getChoice("Choose which replacement effect to apply.", + possibleReplacers.toArray()); } 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); } } - if (chosenRE != null) { - if (executeReplacement(runParams, chosenRE, decider)) { + if (chosenRE != null) { + if (this.executeReplacement(runParams, chosenRE, decider)) { AllZone.getGameLog().add("ReplacementEffect", chosenRE.toString(), 2); return true; - } - else { + } else { return false; } } else { @@ -115,35 +118,39 @@ public class ReplacementHandler { /** * * Runs a single replacement effect. - * @param replacementEffect the replacement effect to run + * + * @param replacementEffect + * the replacement effect to run */ - private boolean executeReplacement(HashMap runParams, ReplacementEffect replacementEffect, Player decider) { + private boolean executeReplacement(final HashMap runParams, + final ReplacementEffect replacementEffect, final Player decider) { - HashMap mapParams = replacementEffect.getMapParams(); + final HashMap mapParams = replacementEffect.getMapParams(); replacementEffect.setHasRun(true); - SpellAbility effectSA = null; + SpellAbility effectSA = null; if (mapParams.containsKey("ReplaceWith")) { - String effectSVar = mapParams.get("ReplaceWith"); - String effectAbString = replacementEffect.getHostCard().getSVar(effectSVar); + final String effectSVar = mapParams.get("ReplaceWith"); + final String effectAbString = replacementEffect.getHostCard().getSVar(effectSVar); - AbilityFactory abilityFactory = new AbilityFactory(); + final AbilityFactory abilityFactory = new AbilityFactory(); effectSA = abilityFactory.getAbility(effectAbString, replacementEffect.getHostCard()); replacementEffect.setReplacingObjects(runParams, effectSA); } - - //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")) { Player optDecider = decider; - if (mapParams.containsKey("OptionalDecider") && effectSA != null) { - optDecider = AbilityFactory.getDefinedPlayers(replacementEffect.getHostCard(), mapParams.get("OptionalDecider"), effectSA).get(0); + if (mapParams.containsKey("OptionalDecider") && (effectSA != null)) { + optDecider = AbilityFactory.getDefinedPlayers(replacementEffect.getHostCard(), + mapParams.get("OptionalDecider"), effectSA).get(0); } 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("?\r\n("); buildQuestion.append(replacementEffect.toString()); @@ -151,8 +158,8 @@ public class ReplacementHandler { if (!GameActionUtil.showYesNoDialog(replacementEffect.getHostCard(), buildQuestion.toString())) { return false; } - } else { - //AI-logic + } else { + // AI-logic if (!replacementEffect.aiShouldRun(effectSA)) { return false; } @@ -162,14 +169,13 @@ public class ReplacementHandler { if (mapParams.containsKey("Prevent")) { if (mapParams.get("Prevent").equals("True")) { replacementEffect.setHasRun(false); - return true; //Nothing should replace the event. + return true; // Nothing should replace the event. } } if (replacementEffect.getHostCard().getController().isHuman()) { AllZone.getGameAction().playSpellAbilityNoStack(effectSA, false); - } - else { + } else { ComputerUtil.playNoStack(effectSA); } @@ -180,9 +186,13 @@ public class ReplacementHandler { /** * - * Creates an instance of the proper replacement effect object based on raw script. - * @param repParse A raw line of script - * @param host The cards that hosts the replacement effect. + * Creates an instance of the proper replacement effect object based on raw + * script. + * + * @param repParse + * A raw line of script + * @param host + * The cards that hosts the replacement effect. * @return A finished instance */ 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. - * @param mapParams The parsed script - * @param host The card that hosts the replacement effect + * Creates an instance of the proper replacement effect object based on a + * parsed script. + * + * @param mapParams + * The parsed script + * @param host + * The card that hosts the replacement effect * @return The finished instance */ public static ReplacementEffect parseReplacement(final HashMap mapParams, final Card host) { diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index 85f8e4a5f13..6538f23792c 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -102,14 +102,16 @@ public class FModel { // TODO this single setting from preferences should not be here, or, // 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, - // currently in GuiTopLevel. When that code is updated, this TODO should be resolved. + // Unfortunately, they're tied up in legacy code in the Display + // interface, + // currently in GuiTopLevel. When that code is updated, this TODO should + // be resolved. // Doublestrike 24-01-12 // == // It's looking like all the settings at the same time, here only. // Doublestrike 06-02-12 - Constant.Runtime.DEV_MODE[0] = preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED); - Constant.Runtime.setSkinName(preferences.getPref(FPref.UI_SKIN)); + Constant.Runtime.DEV_MODE[0] = this.preferences.getPrefBoolean(FPref.DEV_MODE_ENABLED); + Constant.Runtime.setSkinName(this.preferences.getPref(FPref.UI_SKIN)); // Load splash image and preloader swatches for skin 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() { return this.buildInfo; } - /** @param bi0   {@link forge.model.BuildInfo} */ + /** + * Sets the builds the info. + * + * @param bi0   {@link forge.model.BuildInfo} + */ protected final void setBuildInfo(final BuildInfo bi0) { this.buildInfo = bi0; } - /** @return {@link forge.properties.ForgePreferences} */ + /** + * Gets the preferences. + * + * @return {@link forge.properties.ForgePreferences} + */ public final ForgePreferences getPreferences() { return this.preferences; } - /** @return {@link forge.quest.data.QuestPreferences} */ + /** + * Gets the quest preferences. + * + * @return {@link forge.quest.data.QuestPreferences} + */ public final QuestPreferences getQuestPreferences() { return this.questPreferences; } - /** @return {@link forge.model.FGameState} */ + /** + * Gets the game state. + * + * @return {@link forge.model.FGameState} + */ public final FGameState getGameState() { return this.gameState; } - /** @return {@link forge.game.GameSummary} */ + /** + * Gets the game summary. + * + * @return {@link forge.game.GameSummary} + */ public final GameSummary 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. * * @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() { - final ForgePreferences fp = preferences; + final ForgePreferences fp = this.preferences; final List fieldViews = Singletons.getView().getMatchView().getFieldViews(); // 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_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_DECLAREATTACKERS, 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_DECLAREATTACKERS, + 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_COMBATDAMAGE, String.valueOf(fieldViews.get(0).getLblCombatDamage().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_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_DECLAREATTACKERS, 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_DECLAREATTACKERS, + 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_COMBATDAMAGE, String.valueOf(fieldViews.get(1).getLblCombatDamage().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_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(); 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. * * @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() { 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.UPLOAD_DRAFT[0] = fp.getPrefBoolean(FPref.UI_UPLOAD_DRAFT); Constant.Runtime.RANDOM_FOIL[0] = fp.getPrefBoolean(FPref.UI_RANDOM_FOIL); - Constant.Runtime.UPLOAD_DRAFT[0] = - (Constant.Runtime.NET_CONN[0] ? fp.getPrefBoolean(FPref.UI_UPLOAD_DRAFT) : false); + Constant.Runtime.UPLOAD_DRAFT[0] = (Constant.Runtime.NET_CONN[0] ? fp.getPrefBoolean(FPref.UI_UPLOAD_DRAFT) + : false); // AI field is at index [0] fieldViews.get(0).getLblUpkeep().setEnabled(fp.getPrefBoolean(FPref.PHASE_AI_UPKEEP)); diff --git a/src/main/java/forge/util/SectionUtil.java b/src/main/java/forge/util/SectionUtil.java index d6541e12963..3861543e038 100644 --- a/src/main/java/forge/util/SectionUtil.java +++ b/src/main/java/forge/util/SectionUtil.java @@ -31,8 +31,9 @@ public class SectionUtil { /** * Parses the sections. - * - * @param source the source + * + * @param source + * the source * @return the map */ @SuppressWarnings("unchecked") @@ -77,9 +78,15 @@ public class SectionUtil { return result; } - - public static Map parseKvPairs(List lines) { - Map result = new TreeMap(String.CASE_INSENSITIVE_ORDER); + + /** + * Parses the kv pairs. + * + * @param lines the lines + * @return the map + */ + public static Map parseKvPairs(final List lines) { + final Map result = new TreeMap(String.CASE_INSENSITIVE_ORDER); for (final String dd : lines) { final String[] v = dd.split(":", 2); diff --git a/src/main/java/net/slightlymagic/braids/util/lambda/Lambda0.java b/src/main/java/net/slightlymagic/braids/util/lambda/Lambda0.java index 212b66d70e5..00582a7d751 100644 --- a/src/main/java/net/slightlymagic/braids/util/lambda/Lambda0.java +++ b/src/main/java/net/slightlymagic/braids/util/lambda/Lambda0.java @@ -22,19 +22,14 @@ package net.slightlymagic.braids.util.lambda; /** * The Class Lambda1. - * - * @param - * the generic type - * @param - * the generic type + * + * @param the generic type */ public abstract class Lambda0 implements Lambda { /** * Apply. - * - * @param arg1 - * the arg1 + * * @return the r */ public abstract R apply(); @@ -49,12 +44,14 @@ public abstract class Lambda0 implements Lambda { // TODO @Override /** * Apply. - * - * @param args Object[] + * + * @param args + * Object[] * @return R */ + @Override public final R apply(final Object[] args) { - return apply(); + return this.apply(); } }