diff --git a/src/main/java/forge/MagicStack.java b/src/main/java/forge/MagicStack.java index 7fef2ea6d02..168fbdeba1a 100644 --- a/src/main/java/forge/MagicStack.java +++ b/src/main/java/forge/MagicStack.java @@ -1,18 +1,29 @@ package forge; -import com.esotericsoftware.minlog.Log; -import forge.card.abilityFactory.AbilityFactory; -import forge.card.cardFactory.CardFactoryUtil; -import forge.card.mana.ManaCost; -import forge.card.spellability.*; -import forge.gui.GuiUtils; -import forge.gui.input.Input; -import forge.gui.input.Input_PayManaCost_Ability; - import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Stack; +import com.esotericsoftware.minlog.Log; + +import forge.card.abilityFactory.AbilityFactory; +import forge.card.cardFactory.CardFactoryUtil; +import forge.card.mana.ManaCost; +import forge.card.spellability.Ability; +import forge.card.spellability.Ability_Mana; +import forge.card.spellability.Ability_Static; +import forge.card.spellability.Ability_Triggered; +import forge.card.spellability.SpellAbility; +import forge.card.spellability.SpellAbility_StackInstance; +import forge.card.spellability.Spell_Permanent; +import forge.card.spellability.Target; +import forge.card.spellability.Target_Choices; +import forge.card.spellability.Target_Selection; +import forge.gui.GuiUtils; +import forge.gui.input.Input; +import forge.gui.input.Input_PayManaCost_Ability; + /** *
MagicStack class.
* @@ -20,10 +31,10 @@ import java.util.Stack; * @version $Id$ */ public class MagicStack extends MyObservable { - private ArrayListSetter for the field frozen.
reset.
*/ - public void reset() { - stack.clear(); + public final void reset() { + getStack().clear(); frozen = false; splitSecondOnStack = 0; - frozenStack.clear(); + getFrozenStack().clear(); this.updateObservers(); } @@ -63,7 +74,7 @@ public class MagicStack extends MyObservable { * * @return a boolean. */ - public boolean isSplitSecondOnStack() { + public final boolean isSplitSecondOnStack() { return splitSecondOnStack > 0; } @@ -72,9 +83,10 @@ public class MagicStack extends MyObservable { * * @param sp a {@link forge.card.spellability.SpellAbility} object. */ - public void incrementSplitSecond(SpellAbility sp) { - if (sp.getSourceCard().hasKeyword("Split second")) + public final void incrementSplitSecond(final SpellAbility sp) { + if (sp.getSourceCard().hasKeyword("Split second")) { splitSecondOnStack++; + } } /** @@ -82,18 +94,20 @@ public class MagicStack extends MyObservable { * * @param sp a {@link forge.card.spellability.SpellAbility} object. */ - public void decrementSplitSecond(SpellAbility sp) { - if (sp.getSourceCard().hasKeyword("Split second")) + public final void decrementSplitSecond(final SpellAbility sp) { + if (sp.getSourceCard().hasKeyword("Split second")) { splitSecondOnStack--; + } - if (splitSecondOnStack < 0) + if (splitSecondOnStack < 0) { splitSecondOnStack = 0; + } } /** *freezeStack.
*/ - public void freezeStack() { + public final void freezeStack() { frozen = true; } @@ -102,50 +116,56 @@ public class MagicStack extends MyObservable { * * @param ability a {@link forge.card.spellability.SpellAbility} object. */ - public void addAndUnfreeze(SpellAbility ability) { + public final void addAndUnfreeze(final SpellAbility ability) { ability.getRestrictions().abilityActivated(); - if (ability.getRestrictions().getActivationNumberSacrifice() != -1 && - ability.getRestrictions().getNumberTurnActivations() >= ability.getRestrictions().getActivationNumberSacrifice()) { + if (ability.getRestrictions().getActivationNumberSacrifice() != -1 + && ability.getRestrictions().getNumberTurnActivations() + >= ability.getRestrictions().getActivationNumberSacrifice()) + { ability.getSourceCard().addExtrinsicKeyword("At the beginning of the end step, sacrifice CARDNAME."); } // triggered abilities should go on the frozen stack - if (!ability.isTrigger()) + if (!ability.isTrigger()) { frozen = false; + } this.add(ability); // if the ability is a spell, but not a copied spell and its not already on the stack zone, move there if (ability.isSpell()) { Card source = ability.getSourceCard(); - if (!source.isCopiedSpell() && !AllZone.getZone(source).is(Constant.Zone.Stack)) + if (!source.isCopiedSpell() && !AllZone.getZone(source).is(Constant.Zone.Stack)) { AllZone.getGameAction().moveToStack(source); + } } - if (ability.isTrigger()) + if (ability.isTrigger()) { unfreezeStack(); + } } /** *unfreezeStack.
*/ - public void unfreezeStack() { + public final void unfreezeStack() { frozen = false; - boolean checkState = !frozenStack.isEmpty(); - while (!frozenStack.isEmpty()) { - SpellAbility sa = frozenStack.pop().getSpellAbility(); + boolean checkState = !getFrozenStack().isEmpty(); + while (!getFrozenStack().isEmpty()) { + SpellAbility sa = getFrozenStack().pop().getSpellAbility(); this.add(sa); } - if (checkState) + if (checkState) { AllZone.getGameAction().checkStateEffects(); + } } /** *clearFrozen.
*/ - public void clearFrozen() { + public final void clearFrozen() { // TODO: frozen triggered abilities and undoable costs have nasty consequences frozen = false; - frozenStack.clear(); + getFrozenStack().clear(); } /** @@ -153,9 +173,11 @@ public class MagicStack extends MyObservable { * * @param b a boolean. */ - public void setResolving(boolean b) { + public final void setResolving(final boolean b) { bResolving = b; - if (!bResolving) chooseOrderOfSimultaneousStackEntryAll(); + if (!bResolving) { + chooseOrderOfSimultaneousStackEntryAll(); + } } /** @@ -163,7 +185,7 @@ public class MagicStack extends MyObservable { * * @return a boolean. */ - public boolean getResolving() { + public final boolean getResolving() { return bResolving; } @@ -173,14 +195,16 @@ public class MagicStack extends MyObservable { * @param sp a {@link forge.card.spellability.SpellAbility} object. * @param useX a boolean. */ - public void add(SpellAbility sp, boolean useX) { - if (!useX) + public final void add(final SpellAbility sp, final boolean useX) { + if (!useX) { this.add(sp); + } else { - // TODO make working triggered abilities! - if (sp instanceof Ability_Mana || sp instanceof Ability_Triggered) + // TODO: make working triggered abilities! + if (sp instanceof Ability_Mana || sp instanceof Ability_Triggered) { sp.resolve(); + } else { push(sp); /*if (sp.getTargetCard() != null) @@ -195,75 +219,82 @@ public class MagicStack extends MyObservable { * @param sa a {@link forge.card.spellability.SpellAbility} object. * @return a {@link forge.card.mana.ManaCost} object. */ - public ManaCost getMultiKickerSpellCostChange(SpellAbility sa) { - int Max = 25; - String[] Numbers = new String[Max]; - for (int no = 0; no < Max; no++) - Numbers[no] = String.valueOf(no); + public final ManaCost getMultiKickerSpellCostChange(final SpellAbility sa) { + int max = 25; + String[] numbers = new String[max]; + for (int no = 0; no < max; no++) { + numbers[no] = String.valueOf(no); + } ManaCost manaCost = new ManaCost(sa.getManaCost()); - String Mana = manaCost.toString(); + String mana = manaCost.toString(); - int MultiKickerPaid = AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid; + int multiKickerPaid = AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid; - String Number_ManaCost = " "; + String numberManaCost = " "; - if (Mana.toString().length() == 1) - Number_ManaCost = Mana.toString().substring(0, 1); + if (mana.toString().length() == 1) { + numberManaCost = mana.toString().substring(0, 1); + } + else if (mana.toString().length() == 0) { + numberManaCost = "0"; // Should Never Occur + } + else { + numberManaCost = mana.toString().substring(0, 2); + } - else if (Mana.toString().length() == 0) - Number_ManaCost = "0"; // Should Never Occur + numberManaCost = numberManaCost.trim(); - else - Number_ManaCost = Mana.toString().substring(0, 2); - Number_ManaCost = Number_ManaCost.trim(); + for (int check = 0; check < max; check++) { + if (numberManaCost.equals(numbers[check])) { - for (int check = 0; check < Max; check++) { - if (Number_ManaCost.equals(Numbers[check])) { - - if (check - MultiKickerPaid < 0) { - MultiKickerPaid = MultiKickerPaid - check; - AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid = MultiKickerPaid; - Mana = Mana.replaceFirst(String.valueOf(check), "0"); + if (check - multiKickerPaid < 0) { + multiKickerPaid = multiKickerPaid - check; + AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid = multiKickerPaid; + mana = mana.replaceFirst(String.valueOf(check), "0"); } else { - Mana = Mana.replaceFirst(String.valueOf(check), String.valueOf(check - MultiKickerPaid)); - MultiKickerPaid = 0; - AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid = MultiKickerPaid; + mana = mana.replaceFirst(String.valueOf(check), String.valueOf(check - multiKickerPaid)); + multiKickerPaid = 0; + AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid = multiKickerPaid; } } - Mana = Mana.trim(); - if (Mana.equals("")) - Mana = "0"; - manaCost = new ManaCost(Mana); + mana = mana.trim(); + if (mana.equals("")) { + mana = "0"; + } + manaCost = new ManaCost(mana); } - String Color_cut = AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid_Colored; + String colorCut = AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid_Colored; - for (int Colored_Cut = 0; Colored_Cut < Color_cut.length(); Colored_Cut++) { - if ("WUGRB".contains(Color_cut.substring(Colored_Cut, Colored_Cut + 1))) { + for (int colorCutIx = 0; colorCutIx < colorCut.length(); colorCutIx++) { + if ("WUGRB".contains(colorCut.substring(colorCutIx, colorCutIx + 1)) + && !mana.equals(mana.replaceFirst((colorCut.substring(colorCutIx, colorCutIx + 1)), ""))) + { + mana = mana.replaceFirst(colorCut.substring(colorCutIx, colorCutIx + 1), ""); - if (!Mana.equals(Mana.replaceFirst((Color_cut.substring(Colored_Cut, Colored_Cut + 1)), ""))) { - Mana = Mana.replaceFirst(Color_cut.substring(Colored_Cut, Colored_Cut + 1), ""); - AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid_Colored = AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid_Colored - .replaceFirst(Color_cut.substring(Colored_Cut, Colored_Cut + 1), ""); - Mana = Mana.trim(); - if (Mana.equals("")) - Mana = "0"; - manaCost = new ManaCost(Mana); - } + AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid_Colored = + AllZone.getGameAction().CostCutting_GetMultiMickerManaCostPaid_Colored + .replaceFirst(colorCut.substring(colorCutIx, colorCutIx + 1), ""); + + mana = mana.trim(); + if (mana.equals("")) { + mana = "0"; + } + manaCost = new ManaCost(mana); } } return manaCost; } - //TODO - this may be able to use a straight copy of MultiKicker cost change + //TODO: this may be able to use a straight copy of MultiKicker cost change /** *getReplicateSpellCostChange.
* * @param sa a {@link forge.card.spellability.SpellAbility} object. * @return a {@link forge.card.mana.ManaCost} object. */ - public ManaCost getReplicateSpellCostChange(SpellAbility sa) { + public final ManaCost getReplicateSpellCostChange(final SpellAbility sa) { ManaCost manaCost = new ManaCost(sa.getManaCost()); //String Mana = manaCost.toString(); return manaCost; @@ -271,10 +302,10 @@ public class MagicStack extends MyObservable { /** *add.
- * + * * @param sp a {@link forge.card.spellability.SpellAbility} object. */ - public void add(final SpellAbility sp) { + public final void add(final SpellAbility sp) { ArrayListresolveStack.
*/ - public void resolveStack() { + public final void resolveStack() { // Resolving the Stack + + // TODO: change to use forge.view.FView? GuiDisplayUtil.updateGUI(); + this.freezeStack(); // freeze the stack while we're in the middle of resolving setResolving(true); @@ -773,7 +821,7 @@ public class MagicStack extends MyObservable { AllZone.getPhase().resetPriority(); // ActivePlayer gains priority first after Resolve Card source = sa.getSourceCard(); - if (hasFizzled(sa, source)) {//Fizzle + if (hasFizzled(sa, source)) { //Fizzle // TODO: Spell fizzles, what's the best way to alert player? Log.debug(source.getName() + " ability fizzles."); finishResolving(sa, true); @@ -794,7 +842,7 @@ public class MagicStack extends MyObservable { * @param fizzle a boolean. * @since 1.0.15 */ - public void removeCardFromStack(SpellAbility sa, boolean fizzle) { + public final void removeCardFromStack(final SpellAbility sa, final boolean fizzle) { Card source = sa.getSourceCard(); //do nothing @@ -809,10 +857,12 @@ public class MagicStack extends MyObservable { } // If Spell and still on the Stack then let it goto the graveyard or replace its own movement - else if (!source.isCopiedSpell() && (source.isInstant() || source.isSorcery() || fizzle) && - AllZone.getZone(source).is(Constant.Zone.Stack)) { - if (source.getReplaceMoveToGraveyard().size() == 0) + else if (!source.isCopiedSpell() && (source.isInstant() || source.isSorcery() || fizzle) + && AllZone.getZone(source).is(Constant.Zone.Stack)) + { + if (source.getReplaceMoveToGraveyard().size() == 0) { AllZone.getGameAction().moveToGraveyard(source); + } else { source.replaceMoveToGraveyard(); } @@ -826,7 +876,7 @@ public class MagicStack extends MyObservable { * @param fizzle a boolean. * @since 1.0.15 */ - public void finishResolving(SpellAbility sa, boolean fizzle) { + public final void finishResolving(final SpellAbility sa, final boolean fizzle) { //remove card from the stack removeCardFromStack(sa, fizzle); @@ -840,12 +890,14 @@ public class MagicStack extends MyObservable { AllZone.getPhase().setNeedToNextPhase(false); - if (AllZone.getPhase().inCombat()) + if (AllZone.getPhase().inCombat()) { CombatUtil.showCombat(); + } + // TODO: change to use forge.view.FView? GuiDisplayUtil.updateGUI(); - //TODO - this is a huge hack. Why is this necessary? + //TODO: this is a huge hack. Why is this necessary? //hostCard in AF is not the same object that's on the battlefield //verified by System.identityHashCode(card); Card tmp = sa.getSourceCard(); @@ -866,7 +918,7 @@ public class MagicStack extends MyObservable { * @param source a {@link forge.Card} object. * @return a boolean. */ - public boolean hasFizzled(SpellAbility sa, Card source) { + public final boolean hasFizzled(final SpellAbility sa, final Card source) { // By default this has not fizzled boolean fizzle = false; @@ -878,7 +930,10 @@ public class MagicStack extends MyObservable { Target tgt = fizzSA.getTarget(); if (tgt != null && tgt.getMinTargets(source, fizzSA) == 0 && tgt.getNumTargeted() == 0) { // Don't assume fizzled for minTargets == 0 and nothing is targeted - } else if (firstTarget && (tgt != null || fizzSA.getTargetCard() != null || fizzSA.getTargetPlayer() != null)) { + } + else if (firstTarget && (tgt != null || fizzSA.getTargetCard() != null + || fizzSA.getTargetPlayer() != null)) + { // If there is at least 1 target, fizzle switches because ALL targets need to be invalid fizzle = true; firstTarget = false; @@ -909,10 +964,12 @@ public class MagicStack extends MyObservable { fizzle &= !fizzSA.getTargetPlayer().canTarget(fizzSA); } - if (fizzSA.getSubAbility() != null) + if (fizzSA.getSubAbility() != null) { fizzSA = fizzSA.getSubAbility(); - else + } + else { break; + } } return fizzle; @@ -923,8 +980,8 @@ public class MagicStack extends MyObservable { * * @return a {@link forge.card.spellability.SpellAbility} object. */ - public SpellAbility pop() { - SpellAbility sp = stack.pop().getSpellAbility(); + public final SpellAbility pop() { + SpellAbility sp = getStack().pop().getSpellAbility(); decrementSplitSecond(sp); this.updateObservers(); return sp; @@ -938,8 +995,8 @@ public class MagicStack extends MyObservable { * @param index a int. * @return a {@link forge.card.spellability.SpellAbility_StackInstance} object. */ - public SpellAbility_StackInstance peekInstance(int index) { - return stack.get(index); + public final SpellAbility_StackInstance peekInstance(final int index) { + return getStack().get(index); } /** @@ -948,8 +1005,8 @@ public class MagicStack extends MyObservable { * @param index a int. * @return a {@link forge.card.spellability.SpellAbility} object. */ - public SpellAbility peekAbility(int index) { - return stack.get(index).getSpellAbility(); + public final SpellAbility peekAbility(final int index) { + return getStack().get(index).getSpellAbility(); } /** @@ -957,8 +1014,8 @@ public class MagicStack extends MyObservable { * * @return a {@link forge.card.spellability.SpellAbility_StackInstance} object. */ - public SpellAbility_StackInstance peekInstance() { - return stack.peek(); + public final SpellAbility_StackInstance peekInstance() { + return getStack().peek(); } /** @@ -966,8 +1023,8 @@ public class MagicStack extends MyObservable { * * @return a {@link forge.card.spellability.SpellAbility} object. */ - public SpellAbility peekAbility() { - return stack.peek().getSpellAbility(); + public final SpellAbility peekAbility() { + return getStack().peek().getSpellAbility(); } /** @@ -975,10 +1032,12 @@ public class MagicStack extends MyObservable { * * @param sa a {@link forge.card.spellability.SpellAbility} object. */ - public void remove(SpellAbility sa) { + public final void remove(final SpellAbility sa) { SpellAbility_StackInstance si = getInstanceFromSpellAbility(sa); - if (si == null) + + if (si == null) { return; + } remove(si); } @@ -988,11 +1047,11 @@ public class MagicStack extends MyObservable { * * @param si a {@link forge.card.spellability.SpellAbility_StackInstance} object. */ - public void remove(SpellAbility_StackInstance si) { - if (stack.remove(si)) { + public final void remove(final SpellAbility_StackInstance si) { + if (getStack().remove(si)) { decrementSplitSecond(si.getSpellAbility()); } - frozenStack.remove(si); + getFrozenStack().remove(si); this.updateObservers(); } @@ -1002,11 +1061,12 @@ public class MagicStack extends MyObservable { * @param sa a {@link forge.card.spellability.SpellAbility} object. * @return a {@link forge.card.spellability.SpellAbility_StackInstance} object. */ - public SpellAbility_StackInstance getInstanceFromSpellAbility(SpellAbility sa) { + public final SpellAbility_StackInstance getInstanceFromSpellAbility(final SpellAbility sa) { // TODO: Confirm this works! - for (SpellAbility_StackInstance si : stack) { - if (si.getSpellAbility().equals(sa)) + for (SpellAbility_StackInstance si : getStack()) { + if (si.getSpellAbility().equals(sa)) { return si; + } } return null; } @@ -1016,8 +1076,8 @@ public class MagicStack extends MyObservable { * * @return a boolean. */ - public boolean hasSimultaneousStackEntries() { - return simultaneousStackEntryList.size() > 0; + public final boolean hasSimultaneousStackEntries() { + return getSimultaneousStackEntryList().size() > 0; } /** @@ -1025,8 +1085,8 @@ public class MagicStack extends MyObservable { * * @param sa a {@link forge.card.spellability.SpellAbility} object. */ - public void addSimultaneousStackEntry(SpellAbility sa) { - simultaneousStackEntryList.add(sa); + public final void addSimultaneousStackEntry(final SpellAbility sa) { + getSimultaneousStackEntryList().add(sa); } /** @@ -1047,28 +1107,30 @@ public class MagicStack extends MyObservable { * * @param activePlayer a {@link forge.Player} object. */ - public void chooseOrderOfSimultaneousStackEntry(Player activePlayer) { - if (simultaneousStackEntryList.size() == 0) + public final void chooseOrderOfSimultaneousStackEntry(final Player activePlayer) { + if (getSimultaneousStackEntryList().size() == 0) { return; + } ArrayList