From 347d08298f16dc6f699288593dc9d12432714ae7 Mon Sep 17 00:00:00 2001 From: spjspj Date: Thu, 11 May 2017 17:52:43 +1000 Subject: [PATCH] Allow sort by EDH Power level in Deck Editor --- .../java/mage/client/cards/DragCardGrid.java | 7 +- .../java/mage/client/constants/Constants.java | 3 +- .../util/CardViewEDHPowerLevelComparator.java | 525 ++++++++++++++++++ .../src/mage/deck/Commander.java | 22 +- 4 files changed, 544 insertions(+), 13 deletions(-) create mode 100644 Mage.Client/src/main/java/mage/client/util/CardViewEDHPowerLevelComparator.java diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index f2b3f9c808..343b847866 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -424,7 +424,8 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg CMC("Converted Mana Cost", new CardViewCostComparator()), COLOR("Color", new CardViewColorComparator()), COLOR_IDENTITY("Color Identity", new CardViewColorIdentityComparator()), - RARITY("Rarity", new CardViewRarityComparator()); + RARITY("Rarity", new CardViewRarityComparator()), + EDH_POWER_LEVEL("EDH Power Level", new CardViewEDHPowerLevelComparator()); Sort(String text, Comparator comparator) { this.comparator = comparator; @@ -566,7 +567,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg JButton analyseButton; JButton blingButton; - // Popup for toolbar final JPopupMenu filterPopup; JPopupMenu selectByTypePopup; @@ -1135,10 +1135,9 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg if (offsetIntoCol2 < GRID_PADDING) { --col2; } - + // avoids a null ref issue but only deals with symptom of problem. not sure how it gets to this state ever. see issue #3197 // if (selectionDragStartCards == null) return; - int curY = COUNT_LABEL_HEIGHT; for (int rowIndex = 0; rowIndex < cardGrid.size(); ++rowIndex) { int stackStartIndex; diff --git a/Mage.Client/src/main/java/mage/client/constants/Constants.java b/Mage.Client/src/main/java/mage/client/constants/Constants.java index 29456b65f6..6c65550a45 100644 --- a/Mage.Client/src/main/java/mage/client/constants/Constants.java +++ b/Mage.Client/src/main/java/mage/client/constants/Constants.java @@ -102,7 +102,8 @@ public final class Constants { COLOR_IDENTITY("Color Identity"), NAME("Name"), RARITY("Rarity"), - UNSORTED("Unsorted"); + UNSORTED("Unsorted"), + EDH_POWER_LEVEL("EDH Power Level"); private final String text; diff --git a/Mage.Client/src/main/java/mage/client/util/CardViewEDHPowerLevelComparator.java b/Mage.Client/src/main/java/mage/client/util/CardViewEDHPowerLevelComparator.java new file mode 100644 index 0000000000..bbaf4c7396 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/util/CardViewEDHPowerLevelComparator.java @@ -0,0 +1,525 @@ +/* + * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.client.util; + +import java.util.Comparator; +import mage.view.CardView; + +/** + * + * @author spjspj + */ +public class CardViewEDHPowerLevelComparator implements Comparator { + + public int getPowerLevel(CardView card) { + + int thisMaxPower = 0; + + boolean anyNumberOfTarget = false; + boolean annihilator = false; + boolean buyback = false; + boolean cascade = false; + boolean cantBe = false; + boolean copy = false; + boolean costLessEach = false; + boolean createToken = false; + boolean dredge = false; + boolean exile = false; + boolean exileAll = false; + boolean counter = false; + boolean destroy = false; + boolean destroyAll = false; + boolean each = false; + boolean exalted = false; + boolean doesntUntap = false; + boolean drawCards = false; + boolean evoke = false; + boolean extraTurns = false; + boolean flash = false; + boolean flashback = false; + boolean flicker = false; + boolean gainControl = false; + boolean hexproof = false; + boolean infect = false; + boolean lifeTotalBecomes = false; + boolean mayCastForFree = false; + boolean menace = false; + boolean miracle = false; + boolean overload = false; + boolean persist = false; + boolean preventDamage = false; + boolean proliferate = false; + boolean protection = false; + boolean putUnderYourControl = false; + boolean retrace = false; + boolean returnFromYourGY = false; + boolean sacrifice = false; + boolean shroud = false; + boolean skip = false; + boolean sliver = false; + boolean storm = false; + boolean trample = false; + boolean tutor = false; + boolean tutorBasic = false; + boolean twiceAs = false; + boolean unblockable = false; + boolean undying = false; + boolean untapTarget = false; + boolean wheneverEnters = false; + boolean whenCounterThatSpell = false; + boolean xCost = false; + boolean youControlTarget = false; + + for (String str : card.getRules()) { + String s = str.toLowerCase(); + annihilator |= s.contains("annihilator"); + anyNumberOfTarget |= s.contains("any number"); + buyback |= s.contains("buyback"); + cantBe |= s.contains("can't be"); + cascade |= s.contains("cascade"); + copy |= s.contains("copy"); + costLessEach |= s.contains("cost") || s.contains("less") || s.contains("each"); + counter |= s.contains("counter") && s.contains("target"); + createToken |= s.contains("create") && s.contains("token"); + destroy |= s.contains("destroy"); + destroyAll |= s.contains("destroy all"); + doesntUntap |= s.contains("doesn't untap"); + doesntUntap |= s.contains("don't untap"); + drawCards |= s.contains("draw cards"); + dredge |= s.contains("dredge"); + each |= s.contains("each"); + evoke |= s.contains("evoke"); + exalted |= s.contains("exalted"); + exile |= s.contains("exile"); + exileAll |= s.contains("exile") && s.contains(" all "); + extraTurns |= s.contains("extra turn"); + flicker |= s.contains("exile") && s.contains("return") && s.contains("to the battlefield under"); + flash |= s.contains("flash"); + flashback |= s.contains("flashback"); + gainControl |= s.contains("gain control"); + hexproof |= s.contains("hexproof"); + infect |= s.contains("infect"); + lifeTotalBecomes |= s.contains("life total becomes"); + mayCastForFree |= s.contains("may cast") && s.contains("without paying"); + menace |= s.contains("menace"); + miracle |= s.contains("miracle"); + overload |= s.contains("overload"); + persist |= s.contains("persist"); + preventDamage |= s.contains("prevent") && s.contains("all") && s.contains("damage"); + proliferate |= s.contains("proliferate"); + protection |= s.contains("protection"); + putUnderYourControl |= s.contains("put") && s.contains("under your control"); + retrace |= s.contains("retrace"); + returnFromYourGY |= s.contains("return") && s.contains("from your graveyard"); + sacrifice |= s.contains("sacrifice"); + shroud |= s.contains("shroud"); + skip |= s.contains("skip"); + sliver |= s.contains("sliver"); + storm |= s.contains("storm"); + trample |= s.contains("trample"); + tutor |= s.contains("search your library") && !s.contains("basic land"); + tutorBasic |= s.contains("search your library") && s.contains("basic land"); + twiceAs |= s.contains("twice that many") || s.contains("twice as much"); + unblockable |= s.contains("can't be blocked"); + undying |= s.contains("undying"); + untapTarget |= s.contains("untap target"); + whenCounterThatSpell |= s.contains("when") && s.contains("counter that spell"); + wheneverEnters |= s.contains("when") && s.contains("another") && s.contains("enters"); + youControlTarget |= s.contains("you control target"); + } + + if (extraTurns) { + thisMaxPower = Math.max(thisMaxPower, 7); + } + if (buyback) { + thisMaxPower = Math.max(thisMaxPower, 6); + } + if (tutor) { + thisMaxPower = Math.max(thisMaxPower, 6); + } + if (annihilator) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + if (costLessEach) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + if (infect) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + if (overload) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + if (twiceAs) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + if (cascade) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (doesntUntap) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (each) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (exileAll) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (flash) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (flashback) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (flicker) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (gainControl) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (lifeTotalBecomes) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (mayCastForFree) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (preventDamage) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (proliferate) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (protection) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (putUnderYourControl) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (returnFromYourGY) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (skip) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (storm) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (unblockable) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (whenCounterThatSpell) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (wheneverEnters) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (xCost) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (youControlTarget) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (anyNumberOfTarget) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (createToken) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (destroyAll) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (dredge) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (hexproof) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (shroud) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (undying) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (persist) { + thisMaxPower = Math.max(thisMaxPower, 3); + } + if (cantBe) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (evoke) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (exile) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (menace) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (miracle) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (sliver) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (sacrifice) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (untapTarget) { + thisMaxPower = Math.max(thisMaxPower, 2); + } + if (copy) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (counter) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (destroy) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (drawCards) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (exalted) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (retrace) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (trample) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + if (tutorBasic) { + thisMaxPower = Math.max(thisMaxPower, 1); + } + + if (card.getCardTypes().contains("Plainswalker")) { + if (card.getName().toLowerCase().equals("jace, the mind sculptor")) { + thisMaxPower = Math.max(thisMaxPower, 6); + } + if (card.getName().toLowerCase().equals("ugin, the spirit dragon")) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + thisMaxPower = Math.max(thisMaxPower, 4); + } + + String cn = card.getName().toLowerCase(); + if (cn.equals("ancient tomb") + || cn.equals("anafenza, the foremost") + || cn.equals("arcum dagsson") + || cn.equals("armageddon") + || cn.equals("aura shards") + || cn.equals("azami, lady of scrolls") + || cn.equals("azusa, lost but seeking") + || cn.equals("back to basics") + || cn.equals("bane of progress") + || cn.equals("basalt monolith") + || cn.equals("blightsteel collossus") + || cn.equals("blood moon") + || cn.equals("braids, cabal minion") + || cn.equals("cabal coffers") + || cn.equals("captain sisay") + || cn.equals("celestial dawn") + || cn.equals("child of alara") + || cn.equals("coalition relic") + || cn.equals("craterhoof behemoth") + || cn.equals("deepglow skate") + || cn.equals("derevi, empyrial tactician") + || cn.equals("dig through time") + || cn.equals("edric, spymaster of trest") + || cn.equals("elesh norn, grand cenobite") + || cn.equals("entomb") + || cn.equals("force of will") + || cn.equals("food chain") + || cn.equals("gaddock teeg") + || cn.equals("gaea's cradle") + || cn.equals("grand arbiter augustin iv") + || cn.equals("grim monolith") + || cn.equals("hermit druid") + || cn.equals("hokori, dust drinker") + || cn.equals("humility") + || cn.equals("imperial seal") + || cn.equals("iona, shield of emeria") + || cn.equals("jin-gitaxias, core augur") + || cn.equals("karador, ghost chieftain") + || cn.equals("karakas") + || cn.equals("kataki, war's wage") + || cn.equals("knowledge pool") + || cn.equals("linvala, keeper of silence") + || cn.equals("living death") + || cn.equals("llawan, cephalid empress") + || cn.equals("loyal retainers") + || cn.equals("maelstrom wanderer") + || cn.equals("malfegor") + || cn.equals("master of cruelties") + || cn.equals("mana crypt") + || cn.equals("mana drain") + || cn.equals("mana vault") + || cn.equals("michiko konda, truth seeker") + || cn.equals("nath of the gilt-leaf") + || cn.equals("natural order") + || cn.equals("necrotic ooze") + || cn.equals("nicol bolas") + || cn.equals("numot, the devastator") + || cn.equals("oath of druids") + || cn.equals("pattern of rebirth") + || cn.equals("protean hulk") + || cn.equals("purphoros, god of the forge") + || cn.equals("ravages of war") + || cn.equals("reclamation sage") + || cn.equals("sen triplets") + || cn.equals("serra's sanctum") + || cn.equals("sheoldred, whispering one") + || cn.equals("sol ring") + || cn.equals("spore frog") + || cn.equals("stasis") + || cn.equals("strip mine") + || cn.equals("the tabernacle at pendrell vale") + || cn.equals("tinker") + || cn.equals("treasure cruise") + || cn.equals("urabrask the hidden") + || cn.equals("vorinclex, voice of hunger") + || cn.equals("winter orb") + || cn.equals("zur the enchanter")) { + thisMaxPower = Math.max(thisMaxPower, 5); + } + + // Parts of infinite combos + if (cn.equals("animate artifact") || cn.equals("animar, soul of element") + || cn.equals("archaeomancer") + || cn.equals("ashnod's altar") || cn.equals("azami, lady of scrolls") + || cn.equals("aura flux") + || cn.equals("basalt monolith") || cn.equals("brago, king eternal") + || cn.equals("candelabra of tawnos") || cn.equals("cephalid aristocrat") + || cn.equals("cephalid illusionist") || cn.equals("changeling berserker") + || cn.equals("consecrated sphinx") + || cn.equals("cyclonic rift") + || cn.equals("the chain veil") + || cn.equals("cinderhaze wretch") || cn.equals("cryptic gateway") + || cn.equals("deadeye navigator") || cn.equals("derevi, empyrial tactician") + || cn.equals("doubling season") || cn.equals("dross scorpion") + || cn.equals("earthcraft") || cn.equals("erratic portal") + || cn.equals("enter the infinite") || cn.equals("omniscience") + || cn.equals("exquisite blood") || cn.equals("future sight") + || cn.equals("genesis chamber") + || cn.equals("ghave, guru of spores") + || cn.equals("grave pact") + || cn.equals("grave titan") || cn.equals("great whale") + || cn.equals("grim monolith") || cn.equals("gush") + || cn.equals("hellkite charger") || cn.equals("intruder alarm") + || cn.equals("hermit druid") + || cn.equals("humility") + || cn.equals("iona, shield of emeria") + || cn.equals("karn, silver golem") || cn.equals("kiki-jiki, mirror breaker") + || cn.equals("krark-clan ironworks") || cn.equals("krenko, mob boss") + || cn.equals("krosan restorer") || cn.equals("laboratory maniac") + || cn.equals("leovold, emissary of trest") + || cn.equals("leonin relic-warder") || cn.equals("leyline of the void") + || cn.equals("memnarch") || cn.equals("memnarch") + || cn.equals("meren of clan nel toth") || cn.equals("mikaeus, the unhallowed") + || cn.equals("mindcrank") || cn.equals("mindslaver") + || cn.equals("minion reflector") || cn.equals("mycosynth lattice") + || cn.equals("myr turbine") || cn.equals("narset, enlightened master") + || cn.equals("nekusar, the mindrazer") || cn.equals("norin the wary") + || cn.equals("notion thief") + || cn.equals("opalescence") || cn.equals("ornithopter") + || cn.equals("paradox engine") + || cn.equals("purphoros, god of the forge") + || cn.equals("peregrine drake") || cn.equals("palinchron") + || cn.equals("planar portal") || cn.equals("power artifact") + || cn.equals("rings of brighthearth") || cn.equals("rite of replication") + || cn.equals("sanguine bond") || cn.equals("sensei's divining top") + || cn.equals("splinter twin") || cn.equals("stony silence") + || cn.equals("sunder") + || cn.equals("storm cauldron") || cn.equals("teferi's puzzle box") + || cn.equals("tangle wire") + || cn.equals("teferi, mage of zhalfir") || cn.equals("teferi, mage of zhalfir") + || cn.equals("tezzeret the seeker") || cn.equals("time stretch") + || cn.equals("time warp") || cn.equals("training grounds") + || cn.equals("triskelavus") || cn.equals("triskelion") + || cn.equals("turnabout") || cn.equals("umbral mantle") + || cn.equals("uyo, silent prophet") || cn.equals("voltaic key") + || cn.equals("workhorse") || cn.equals("worldgorger dragon") + || cn.equals("worthy cause") || cn.equals("yawgmoth's will") + || cn.equals("zealous conscripts")) { + thisMaxPower = Math.max(thisMaxPower, 12); + } + + if (cn.equals("animar, soul of element") + || cn.equals("azami, lady of scrolls") + || cn.equals("braids, cabal minion") + || cn.equals("child of alara") + || cn.equals("derevi, empyrial tactician") + || cn.equals("edric, spymaster of trest") + || cn.equals("gaddock teeg") + || cn.equals("grand arbiter augustin iv") + || cn.equals("hokori, dust drinker") + || cn.equals("iona, shield of emeria") + || cn.equals("jin-gitaxias, core augur") + || cn.equals("kaalia of the vast") + || cn.equals("karador, ghost chieftain") + || cn.equals("leovold, emissary of trest") + || cn.equals("linvala, keeper of silence") + || cn.equals("llawan, cephalid empress") + || cn.equals("memnarch") + || cn.equals("meren of clan nel toth") + || cn.equals("michiko konda, truth seeker") + || cn.equals("narset, enlightened master") + || cn.equals("nekusar, the mindrazer") + || cn.equals("norin the wary") + || cn.equals("numot, the devastator") + || cn.equals("sheoldred, whispering one") + || cn.equals("teferi, mage of zhalfir") + || cn.equals("zur the enchanter")) { + thisMaxPower = Math.max(thisMaxPower, 12); + } + + if (cn.equals("anafenza, the foremost") + || cn.equals("arcum dagsson") + || cn.equals("azusa, lost but seeking") + || cn.equals("brago, king eternal") + || cn.equals("captain sisay") + || cn.equals("elesh norn, grand cenobite") + || cn.equals("malfegor") + || cn.equals("maelstrom wanderer") + || cn.equals("mikaeus the unhallowed") + || cn.equals("nath of the gilt-leaf") + || cn.equals("prossh, skyraider of kher") + || cn.equals("purphoros, god of the forge") + || cn.equals("sen triplets") + || cn.equals("urabrask the hidden") + || cn.equals("vorinclex, voice of hunger")) { + thisMaxPower = Math.max(thisMaxPower, 10); + } + return thisMaxPower; + } + + @Override + public int compare(CardView o1, CardView o2) { + return Integer.valueOf(getPowerLevel(o1)).compareTo(getPowerLevel(o2)); + } + +} diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java index ec0047bd1b..71da352004 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java @@ -40,7 +40,6 @@ import mage.cards.decks.Constructed; import mage.cards.decks.Deck; import mage.constants.SetType; import mage.filter.FilterMana; -import mage.util.CardUtil; /** * @@ -237,6 +236,8 @@ public class Commander extends Constructed { boolean drawCards = false; boolean evoke = false; boolean extraTurns = false; + boolean flash = false; + boolean flashback = false; boolean flicker = false; boolean gainControl = false; boolean hexproof = false; @@ -294,6 +295,8 @@ public class Commander extends Constructed { exileAll |= s.contains("exile") && s.contains(" all "); extraTurns |= s.contains("extra turn"); flicker |= s.contains("exile") && s.contains("return") && s.contains("to the battlefield under"); + flash |= s.contains("flash"); + flashback |= s.contains("flashback"); gainControl |= s.contains("gain control"); hexproof |= s.contains("hexproof"); infect |= s.contains("infect"); @@ -304,7 +307,7 @@ public class Commander extends Constructed { overload |= s.contains("overload"); persist |= s.contains("persist"); preventDamage |= s.contains("prevent") && s.contains("all") && s.contains("damage"); - proliferate |= s.contains("proliferate"); + proliferate |= s.contains("proliferate"); protection |= s.contains("protection"); putUnderYourControl |= s.contains("put") && s.contains("under your control"); retrace |= s.contains("retrace"); @@ -375,6 +378,12 @@ public class Commander extends Constructed { if (exileAll) { thisMaxPower = Math.max(thisMaxPower, 4); } + if (flash) { + thisMaxPower = Math.max(thisMaxPower, 4); + } + if (flashback) { + thisMaxPower = Math.max(thisMaxPower, 4); + } if (flicker) { thisMaxPower = Math.max(thisMaxPower, 4); } @@ -506,10 +515,6 @@ public class Commander extends Constructed { thisMaxPower = Math.max(thisMaxPower, 4); } - if (card.isLand()) { - thisMaxPower = 0; - } - String cn = card.getName().toLowerCase(); if (cn.equals("ancient tomb") || cn.equals("anafenza, the foremost") @@ -593,7 +598,7 @@ public class Commander extends Constructed { // Parts of infinite combos if (cn.equals("animate artifact") || cn.equals("animar, soul of element") - || cn.equals("archaeomancer") + || cn.equals("archaeomancer") || cn.equals("ashnod's altar") || cn.equals("azami, lady of scrolls") || cn.equals("aura flux") || cn.equals("basalt monolith") || cn.equals("brago, king eternal") @@ -608,6 +613,7 @@ public class Commander extends Constructed { || cn.equals("earthcraft") || cn.equals("erratic portal") || cn.equals("enter the infinite") || cn.equals("omniscience") || cn.equals("exquisite blood") || cn.equals("future sight") + || cn.equals("genesis chamber") || cn.equals("ghave, guru of spores") || cn.equals("grave pact") || cn.equals("grave titan") || cn.equals("great whale") @@ -663,7 +669,7 @@ public class Commander extends Constructed { } else { color = color.union(commander.getColor(null)); } - + FilterMana commanderColor = commander.getColorIdentity(); if (commanderColor.isWhite()) { color.setWhite(true);