From 2c7876f26e5026460ab14b62c8c16b7a235152ef Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Thu, 8 Nov 2012 22:16:05 +0000 Subject: [PATCH] Spells giving mana work correctly --- src/main/java/forge/Card.java | 21 +++++----- src/main/java/forge/CardUtil.java | 9 ++-- src/main/java/forge/GameActionUtil.java | 5 +-- .../java/forge/card/CardCharacteristics.java | 5 +-- .../card/abilityfactory/CommonSpell.java | 6 +++ .../card/abilityfactory/SpellEffect.java | 3 +- src/main/java/forge/card/mana/ManaPool.java | 11 +++-- .../java/forge/card/spellability/Ability.java | 2 +- .../card/spellability/AbilityActivated.java | 2 +- .../java/forge/card/spellability/Spell.java | 2 +- .../forge/card/spellability/SpellAbility.java | 8 +++- .../StaticAbilityCantBeCast.java | 2 +- .../control/input/InputPayManaCostUtil.java | 17 ++++---- .../java/forge/game/player/ComputerUtil.java | 41 +++++++++---------- src/main/java/forge/game/zone/MagicStack.java | 4 +- 15 files changed, 70 insertions(+), 68 deletions(-) diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index 86868a246f2..f96f4bd780f 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -44,7 +44,6 @@ import forge.card.cost.Cost; import forge.card.mana.ManaCost; import forge.card.replacement.ReplacementEffect; import forge.card.replacement.ReplacementResult; -import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.AbilityTriggered; import forge.card.spellability.Spell; @@ -2676,7 +2675,7 @@ public class Card extends GameEntity implements Comparable { * * @return a {@link java.util.ArrayList} object. */ - public final List getManaAbility() { + public final List getManaAbility() { return Collections.unmodifiableList(this.getCharacteristics().getManaAbility()); } @@ -2688,9 +2687,9 @@ public class Card extends GameEntity implements Comparable { * * @return a {@link java.util.ArrayList} object. */ - public final ArrayList getAIPlayableMana() { - final ArrayList res = new ArrayList(); - for (final AbilityActivated a : this.getManaAbility()) { + public final ArrayList getAIPlayableMana() { + final ArrayList res = new ArrayList(); + for (final SpellAbility a : this.getManaAbility()) { // if a mana ability has a mana cost the AI will miscalculate final Cost cost = a.getPayCosts(); @@ -2716,9 +2715,9 @@ public class Card extends GameEntity implements Comparable { * * @return a {@link java.util.ArrayList} object. */ - public final List getBasicMana() { - final List res = new ArrayList(); - for (final AbilityActivated a : this.getManaAbility()) { + public final List getBasicMana() { + final List res = new ArrayList(); + for (final SpellAbility a : this.getManaAbility()) { if (a.getManaPart().isBasic() && !res.contains(a)) { res.add(a); } @@ -2802,8 +2801,8 @@ public class Card extends GameEntity implements Comparable { public final void addSpellAbility(final SpellAbility a) { a.setSourceCard(this); - if (a.getManaPart() != null) { - this.getCharacteristics().getManaAbility().add((AbilityActivated) a); + if (a.isManaAbility()) { + this.getCharacteristics().getManaAbility().add(a); } else { this.getCharacteristics().getSpellAbility().add(a); } @@ -2819,7 +2818,7 @@ public class Card extends GameEntity implements Comparable { * a {@link forge.card.spellability.SpellAbility} object. */ public final void removeSpellAbility(final SpellAbility a) { - if (a.getManaPart() != null) { + if (a.isManaAbility()) { // if (a.isExtrinsic()) //never remove intrinsic mana abilities, is // this the way to go?? this.getCharacteristics().getManaAbility().remove(a); diff --git a/src/main/java/forge/CardUtil.java b/src/main/java/forge/CardUtil.java index eebcb91fd30..bae8120c7e7 100644 --- a/src/main/java/forge/CardUtil.java +++ b/src/main/java/forge/CardUtil.java @@ -38,7 +38,6 @@ import forge.card.CardManaCost; import forge.card.EditionInfo; import forge.card.abilityfactory.AbilityFactory; import forge.card.mana.ManaCost; -import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.SpellAbility; import forge.control.input.InputPayManaCostUtil; @@ -988,16 +987,16 @@ public final class CardUtil { colors.add(Constant.Color.COLORLESS); } } else if (reflectProperty.equals("Produce")) { - final ArrayList abilities = new ArrayList(); + final ArrayList abilities = new ArrayList(); for (final Card c : cards) { abilities.addAll(c.getManaAbility()); } // currently reflected mana will ignore other reflected mana // abilities - final ArrayList reflectAbilities = new ArrayList(); + final ArrayList reflectAbilities = new ArrayList(); - for (final AbilityActivated ab : abilities) { + for (final SpellAbility ab : abilities) { if (maxChoices == colors.size()) { break; } @@ -1016,7 +1015,7 @@ public final class CardUtil { } } - for (final AbilityActivated ab : reflectAbilities) { + for (final SpellAbility ab : reflectAbilities) { if (maxChoices == colors.size()) { break; } diff --git a/src/main/java/forge/GameActionUtil.java b/src/main/java/forge/GameActionUtil.java index bcc9cbb00ec..7d7475ad6f2 100644 --- a/src/main/java/forge/GameActionUtil.java +++ b/src/main/java/forge/GameActionUtil.java @@ -41,7 +41,6 @@ import forge.card.cost.CostReturn; import forge.card.cost.CostSacrifice; import forge.card.cost.CostUtil; import forge.card.spellability.Ability; -import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilitySub; import forge.card.spellability.Spell; import forge.card.spellability.SpellAbility; @@ -1324,12 +1323,12 @@ public final class GameActionUtil { produces.put("Plains", "W"); produces.put("Swamp", "B"); - List lands = Singletons.getModel().getGame().getCardsInGame(); + List lands = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield); lands = CardLists.filter(lands, Presets.LANDS); // remove all abilities granted by this Command for (final Card land : lands) { - List manaAbs = Lists.newArrayList(land.getManaAbility()); + List manaAbs = Lists.newArrayList(land.getManaAbility()); // will get comodification exception without a different list for (final SpellAbility sa : manaAbs) { if (sa.getType().equals("BasicLandTypeMana")) { diff --git a/src/main/java/forge/card/CardCharacteristics.java b/src/main/java/forge/card/CardCharacteristics.java index a7d7f9edfdb..85b1bbd668d 100644 --- a/src/main/java/forge/card/CardCharacteristics.java +++ b/src/main/java/forge/card/CardCharacteristics.java @@ -24,7 +24,6 @@ import java.util.TreeMap; import forge.CardColor; import forge.card.replacement.ReplacementEffect; -import forge.card.spellability.AbilityActivated; import forge.card.spellability.SpellAbility; import forge.card.staticability.StaticAbility; import forge.card.trigger.Trigger; @@ -44,7 +43,7 @@ public class CardCharacteristics { private ArrayList intrinsicKeyword = new ArrayList(); private ArrayList spellAbility = new ArrayList(); private ArrayList intrinsicAbility = new ArrayList(); - private final List manaAbility = new ArrayList(); + private final List manaAbility = new ArrayList(); private ArrayList triggers = new ArrayList(); private ArrayList replacementEffects = new ArrayList(); private ArrayList staticAbilities = new ArrayList(); @@ -250,7 +249,7 @@ public class CardCharacteristics { * * @return the manaAbility */ - public final List getManaAbility() { + public final List getManaAbility() { return this.manaAbility; } diff --git a/src/main/java/forge/card/abilityfactory/CommonSpell.java b/src/main/java/forge/card/abilityfactory/CommonSpell.java index 39d62aa9913..fe730abc9e9 100644 --- a/src/main/java/forge/card/abilityfactory/CommonSpell.java +++ b/src/main/java/forge/card/abilityfactory/CommonSpell.java @@ -5,7 +5,10 @@ import java.util.Map; import forge.Card; import forge.card.abilityfactory.effects.ChangeZoneAllEffect; import forge.card.abilityfactory.effects.ChangeZoneEffect; +import forge.card.abilityfactory.effects.ManaEffect; +import forge.card.abilityfactory.effects.ManaReflectedEffect; import forge.card.cost.Cost; +import forge.card.spellability.AbilityManaPart; import forge.card.spellability.Spell; import forge.card.spellability.Target; @@ -21,6 +24,9 @@ public class CommonSpell extends Spell { effect = effect0; ai = ai0; + if ( effect0 instanceof ManaEffect || effect0 instanceof ManaReflectedEffect ) + this.setManaPart(new AbilityManaPart(sourceCard, params)); + if ( effect0 instanceof ChangeZoneEffect || effect0 instanceof ChangeZoneAllEffect ) AbilityFactory.adjustChangeZoneTarget(params, this); } diff --git a/src/main/java/forge/card/abilityfactory/SpellEffect.java b/src/main/java/forge/card/abilityfactory/SpellEffect.java index fd93c28f487..350f0397d6f 100644 --- a/src/main/java/forge/card/abilityfactory/SpellEffect.java +++ b/src/main/java/forge/card/abilityfactory/SpellEffect.java @@ -37,8 +37,7 @@ import forge.game.player.Player; // if mana production has any type of SubAbility, undoable=false final AbilitySub abSub = sa.getSubAbility(); if (abSub != null) { - if ( sa.getManaPart() != null ) - sa.setUndoable(false); + sa.setUndoable(false); AbilityFactory.resolve(abSub, false); } } diff --git a/src/main/java/forge/card/mana/ManaPool.java b/src/main/java/forge/card/mana/ManaPool.java index 519ce54ff8a..9c664716873 100644 --- a/src/main/java/forge/card/mana/ManaPool.java +++ b/src/main/java/forge/card/mana/ManaPool.java @@ -24,7 +24,6 @@ import java.util.Map; import forge.Constant; import forge.Singletons; -import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.SpellAbility; import forge.control.input.InputPayManaCostUtil; @@ -480,14 +479,14 @@ public class ManaPool { * a {@link forge.card.spellability.AbilityMana} object. * @return a {@link forge.card.mana.ManaCost} object. */ - public final ManaCost payManaFromAbility(final SpellAbility sa, ManaCost manaCost, final AbilityActivated ma) { + public final ManaCost payManaFromAbility(final SpellAbility sa, ManaCost manaCost, final SpellAbility ma) { if (manaCost.isPaid() || this.isEmpty()) { return manaCost; } // Mana restriction must be checked before this method is called - final List paidAbs = sa.getPayingManaAbilities(); + final List paidAbs = sa.getPayingManaAbilities(); final List manaPaid = sa.getPayingMana(); paidAbs.add(ma); // assumes some part on the mana produced by the ability will get used @@ -526,7 +525,7 @@ public class ManaPool { * a boolean. */ public final void clearManaPaid(final SpellAbility ability, final boolean refund) { - final List abilitiesUsedToPay = ability.getPayingManaAbilities(); + final List abilitiesUsedToPay = ability.getPayingManaAbilities(); final List manaPaid = ability.getPayingMana(); abilitiesUsedToPay.clear(); @@ -609,10 +608,10 @@ public class ManaPool { public final void refundManaPaid(final SpellAbility sa, final boolean untap) { // TODO having some crash in here related to undo and not tracking // abilities properly - final List payAbs = sa.getPayingManaAbilities(); + final List payAbs = sa.getPayingManaAbilities(); // go through paidAbilities if they are undoable - for (final AbilityActivated am : payAbs) { + for (final SpellAbility am : payAbs) { AbilityManaPart m = am.getManaPart(); if (am.isUndoable()) { if (this.accountFor(sa, m)) { diff --git a/src/main/java/forge/card/spellability/Ability.java b/src/main/java/forge/card/spellability/Ability.java index b0546c52da0..8cd08d7594e 100644 --- a/src/main/java/forge/card/spellability/Ability.java +++ b/src/main/java/forge/card/spellability/Ability.java @@ -68,7 +68,7 @@ public abstract class Ability extends SpellAbility { /** {@inheritDoc} */ @Override public boolean canPlay() { - if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack() && null == this.getManaPart()) { + if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack() && !this.isManaAbility()) { return false; } diff --git a/src/main/java/forge/card/spellability/AbilityActivated.java b/src/main/java/forge/card/spellability/AbilityActivated.java index ea4a67a92f1..e11cb7f7048 100644 --- a/src/main/java/forge/card/spellability/AbilityActivated.java +++ b/src/main/java/forge/card/spellability/AbilityActivated.java @@ -81,7 +81,7 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S /** {@inheritDoc} */ @Override public boolean canPlay() { - if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack() && null == this.getManaPart()) { + if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack() && !this.isManaAbility()) { return false; } diff --git a/src/main/java/forge/card/spellability/Spell.java b/src/main/java/forge/card/spellability/Spell.java index b9cb718ece2..793b52983ce 100644 --- a/src/main/java/forge/card/spellability/Spell.java +++ b/src/main/java/forge/card/spellability/Spell.java @@ -86,7 +86,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable /** {@inheritDoc} */ @Override public boolean canPlay() { - if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack() && null == this.getManaPart()) { + if (Singletons.getModel().getGame().getStack().isSplitSecondOnStack()) { return false; } diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index 55b7929d033..0d0d07bf2b5 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -102,7 +102,7 @@ public abstract class SpellAbility { protected ApiType api = null; private final ArrayList payingMana = new ArrayList(); - private final List paidAbilities = new ArrayList(); + private final List paidAbilities = new ArrayList(); private ArrayList optionalAdditionalCosts = new ArrayList(); private HashMap> paidLists = new HashMap>(); @@ -124,6 +124,10 @@ public abstract class SpellAbility { public final AbilityManaPart getManaPart() { return manaPart; } + public final boolean isManaAbility() { + return manaPart != null && isAbility(); + } + public final void setManaPart(AbilityManaPart manaPart) { this.manaPart = manaPart; @@ -759,7 +763,7 @@ public abstract class SpellAbility { * * @return a {@link java.util.ArrayList} object. */ - public List getPayingManaAbilities() { + public List getPayingManaAbilities() { return this.paidAbilities; } diff --git a/src/main/java/forge/card/staticability/StaticAbilityCantBeCast.java b/src/main/java/forge/card/staticability/StaticAbilityCantBeCast.java index db6a4ab1332..9cb20b8063b 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityCantBeCast.java +++ b/src/main/java/forge/card/staticability/StaticAbilityCantBeCast.java @@ -97,7 +97,7 @@ public class StaticAbilityCantBeCast { return false; } - if (params.containsKey("NonMana") && (spellAbility.getManaPart() != null )) { + if (params.containsKey("NonMana") && (spellAbility.isManaAbility())) { return false; } diff --git a/src/main/java/forge/control/input/InputPayManaCostUtil.java b/src/main/java/forge/control/input/InputPayManaCostUtil.java index 296b7381100..5dbe1bd0510 100644 --- a/src/main/java/forge/control/input/InputPayManaCostUtil.java +++ b/src/main/java/forge/control/input/InputPayManaCostUtil.java @@ -31,7 +31,6 @@ import forge.card.cost.CostMana; import forge.card.cost.CostPayment; import forge.card.mana.ManaCost; import forge.card.mana.ManaPool; -import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.SpellAbility; import forge.game.zone.PlayerZone; @@ -85,10 +84,10 @@ public class InputPayManaCostUtil { } } - List abilities = new ArrayList(); + List abilities = new ArrayList(); // you can't remove unneeded abilities inside a for(am:abilities) loop :( - for(AbilityActivated ma : card.getManaAbility()) { + for(SpellAbility ma : card.getManaAbility()) { ma.setActivatingPlayer(Singletons.getControl().getPlayer()); AbilityManaPart m = ma.getManaPart(); if (!ma.canPlay()) { @@ -151,9 +150,9 @@ public class InputPayManaCostUtil { if (!skipExpress) { // express Mana Choice - final ArrayList colorMatches = new ArrayList(); + final ArrayList colorMatches = new ArrayList(); - for (final AbilityActivated am : abilities) { + for (final SpellAbility am : abilities) { AbilityManaPart m = am.getManaPart(); if (m.isReflectedMana()) { final List reflectableColors = CardUtil.getReflectableManaColors(am, am, new ArrayList(), new ArrayList()); @@ -191,10 +190,10 @@ public class InputPayManaCostUtil { } } - AbilityActivated chosen = abilities.get(0); + SpellAbility chosen = abilities.get(0); if ((1 < abilities.size()) && choice) { - final Map ability = new HashMap(); - for (final AbilityActivated am : abilities) { + final Map ability = new HashMap(); + for (final SpellAbility am : abilities) { ability.put(am.toString(), am); } chosen = GuiChoose.one("Choose mana ability", abilities); @@ -246,7 +245,7 @@ public class InputPayManaCostUtil { * a {@link java.lang.String} object. * @return a boolean. */ - public static boolean canMake(final AbilityActivated am, final String mana) { + public static boolean canMake(final SpellAbility am, final String mana) { if (mana.contains("1")) { return true; } diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index f3a1155bf57..3daf69ac326 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -49,7 +49,6 @@ import forge.card.cost.CostPayment; import forge.card.cost.CostUtil; import forge.card.mana.ManaCost; import forge.card.mana.ManaPool; -import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityManaPart; import forge.card.spellability.AbilityStatic; import forge.card.spellability.SpellAbility; @@ -609,9 +608,9 @@ public class ComputerUtil { } // get map of mana abilities - final Map> manaAbilityMap = ComputerUtil.mapManaSources(ai, checkPlayable); + final Map> manaAbilityMap = ComputerUtil.mapManaSources(ai, checkPlayable); // initialize ArrayList list for mana needed - final List> partSources = new ArrayList>(); + final List> partSources = new ArrayList>(); final List partPriority = new ArrayList(); final String[] costParts = cost.toString().replace("X ", "").split(" "); boolean foundAllSources = findManaSources(ai, manaAbilityMap, partSources, partPriority, costParts); @@ -635,7 +634,7 @@ public class ComputerUtil { final int nPart = partPriority.get(nPriority); final ManaCost costPart = new ManaCost(costParts[nPart]); // Loop over mana abilities that can be used to current mana cost part - for (final AbilityActivated ma : partSources.get(nPart)) { + for (final SpellAbility ma : partSources.get(nPart)) { final Card sourceCard = ma.getSourceCard(); // Check if source has already been used @@ -781,8 +780,8 @@ public class ComputerUtil { * @param foundAllSources * @return Were all mana sources found? */ - private static boolean findManaSources(final Player ai, final Map> manaAbilityMap, - final List> partSources, final List partPriority, + private static boolean findManaSources(final Player ai, final Map> manaAbilityMap, + final List> partSources, final List partPriority, final String[] costParts) { final String[] shortColors = { "W", "U", "B", "R", "G" }; boolean foundAllSources; @@ -792,7 +791,7 @@ public class ComputerUtil { foundAllSources = true; // loop over cost parts for (int nPart = 0; nPart < costParts.length; nPart++) { - final List srcFound = new ArrayList(); + final List srcFound = new ArrayList(); // Test for: // 1) Colorless // 2) Split e.g. 2/G @@ -947,7 +946,7 @@ public class ComputerUtil { @Override public boolean apply(final Card c) { if (checkPlayable) { - for (final AbilityActivated am : c.getAIPlayableMana()) { + for (final SpellAbility am : c.getAIPlayableMana()) { am.setActivatingPlayer(ai); if (am.canPlay()) { return true; @@ -988,9 +987,9 @@ public class ComputerUtil { int usableManaAbilities = 0; boolean needsLimitedResources = false; boolean producesAnyColor = false; - final ArrayList manaAbilities = card.getAIPlayableMana(); + final ArrayList manaAbilities = card.getAIPlayableMana(); - for (final AbilityActivated m : manaAbilities) { + for (final SpellAbility m : manaAbilities) { if (m.getManaPart().isAnyMana()) { producesAnyColor = true; @@ -1066,16 +1065,16 @@ public class ComputerUtil { * @param checkPlayable TODO * @return HashMap> */ - public static Map> mapManaSources(final Player ai, boolean checkPlayable) { - final Map> manaMap = new HashMap>(); + public static Map> mapManaSources(final Player ai, boolean checkPlayable) { + final Map> manaMap = new HashMap>(); - final List whiteSources = new ArrayList(); - final List blueSources = new ArrayList(); - final List blackSources = new ArrayList(); - final List redSources = new ArrayList(); - final List greenSources = new ArrayList(); - final List colorlessSources = new ArrayList(); - final List snowSources = new ArrayList(); + final List whiteSources = new ArrayList(); + final List blueSources = new ArrayList(); + final List blackSources = new ArrayList(); + final List redSources = new ArrayList(); + final List greenSources = new ArrayList(); + final List colorlessSources = new ArrayList(); + final List snowSources = new ArrayList(); // Get list of current available mana sources final List manaSources = ComputerUtil.getAvailableMana(ai, checkPlayable); @@ -1083,10 +1082,10 @@ public class ComputerUtil { // Loop over all mana sources for (int i = 0; i < manaSources.size(); i++) { final Card sourceCard = manaSources.get(i); - final ArrayList manaAbilities = sourceCard.getAIPlayableMana(); + final ArrayList manaAbilities = sourceCard.getAIPlayableMana(); // Loop over all mana abilities for a source - for (final AbilityActivated m : manaAbilities) { + for (final SpellAbility m : manaAbilities) { m.setActivatingPlayer(ai); if (!m.canPlay() && checkPlayable) { continue; diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index 4d7323cf910..2300ba52cbb 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -305,7 +305,7 @@ public class MagicStack extends MyObservable { } else { // TODO: make working triggered abilities! - if (sp.getManaPart() != null || (sp instanceof AbilityTriggered)) { + if (sp.isManaAbility() || (sp instanceof AbilityTriggered)) { sp.resolve(); } else { this.push(sp); @@ -419,7 +419,7 @@ public class MagicStack extends MyObservable { public final void add(final SpellAbility sp) { final ArrayList chosenTargets = sp.getAllTargetChoices(); - if (sp.getManaPart() != null) { // Mana Abilities go straight through + if (sp.isManaAbility()) { // Mana Abilities go straight through sp.resolve(); sp.resetOnceResolved(); game.getGameLog().add("Mana", sp.getSourceCard() + " - " + sp.getDescription(), 4);