diff --git a/.gitattributes b/.gitattributes index c07c5347199..2584c0e4636 100644 --- a/.gitattributes +++ b/.gitattributes @@ -43,6 +43,7 @@ res/cardsfolder/a/absorb_vis.txt svneol=native#text/plain res/cardsfolder/a/abu_jafar.txt -text res/cardsfolder/a/abuna_acolyte.txt svneol=native#text/plain res/cardsfolder/a/abunas_chant.txt -text +res/cardsfolder/a/abundance.txt -text res/cardsfolder/a/abundant_growth.txt -text res/cardsfolder/a/abyssal_gatekeeper.txt svneol=native#text/plain res/cardsfolder/a/abyssal_horror.txt svneol=native#text/plain @@ -63,10 +64,12 @@ res/cardsfolder/a/accumulated_knowledge.txt svneol=native#text/plain res/cardsfolder/a/accursed_centaur.txt svneol=native#text/plain res/cardsfolder/a/acid_rain.txt svneol=native#text/plain res/cardsfolder/a/acid_web_spider.txt svneol=native#text/plain +res/cardsfolder/a/acidic_dagger.txt -text res/cardsfolder/a/acidic_slime.txt svneol=native#text/plain res/cardsfolder/a/acidic_sliver.txt svneol=native#text/plain res/cardsfolder/a/acidic_soil.txt svneol=native#text/plain res/cardsfolder/a/acolyte_of_xathrid.txt svneol=native#text/plain +res/cardsfolder/a/acorn_catapult.txt -text res/cardsfolder/a/acorn_harvest.txt svneol=native#text/plain res/cardsfolder/a/acquire.txt svneol=native#text/plain res/cardsfolder/a/acridian.txt svneol=native#text/plain @@ -326,6 +329,7 @@ res/cardsfolder/a/anodet_lurker.txt svneol=native#text/plain res/cardsfolder/a/anoint.txt svneol=native#text/plain res/cardsfolder/a/anowon_the_ruin_sage.txt svneol=native#text/plain res/cardsfolder/a/ant_queen.txt svneol=native#text/plain +res/cardsfolder/a/anthem_of_rakdos.txt -text res/cardsfolder/a/anthroplasm.txt svneol=native#text/plain res/cardsfolder/a/antler_skulkin.txt svneol=native#text/plain res/cardsfolder/a/anurid_barkripper.txt svneol=native#text/plain @@ -343,6 +347,7 @@ res/cardsfolder/a/aphetto_runecaster.txt svneol=native#text/plain res/cardsfolder/a/aphetto_vulture.txt svneol=native#text/plain res/cardsfolder/a/aphotic_wisps.txt svneol=native#text/plain res/cardsfolder/a/apocalypse.txt svneol=native#text/plain +res/cardsfolder/a/apocalypse_chime.txt -text res/cardsfolder/a/apocalypse_hydra.txt svneol=native#text/plain res/cardsfolder/a/apostles_blessing.txt svneol=native#text/plain res/cardsfolder/a/apothecary_initiate.txt svneol=native#text/plain @@ -574,6 +579,7 @@ res/cardsfolder/a/avenger_of_zendikar.txt svneol=native#text/plain res/cardsfolder/a/avenging_angel.txt svneol=native#text/plain res/cardsfolder/a/avenging_druid.txt -text res/cardsfolder/a/avian_changeling.txt svneol=native#text/plain +res/cardsfolder/a/avizoa.txt -text res/cardsfolder/a/avoid_fate.txt svneol=native#text/plain res/cardsfolder/a/awakener_druid.txt svneol=native#text/plain res/cardsfolder/a/awakening.txt svneol=native#text/plain @@ -1552,6 +1558,7 @@ res/cardsfolder/c/cleanfall.txt svneol=native#text/plain res/cardsfolder/c/cleanse.txt svneol=native#text/plain res/cardsfolder/c/cleansing_beam.txt svneol=native#text/plain res/cardsfolder/c/clear.txt svneol=native#text/plain +res/cardsfolder/c/clear_the_land.txt -text res/cardsfolder/c/clearwater_goblet.txt svneol=native#text/plain res/cardsfolder/c/clergy_en_vec.txt svneol=native#text/plain res/cardsfolder/c/clickslither.txt svneol=native#text/plain @@ -2216,6 +2223,7 @@ res/cardsfolder/d/desert_nomads.txt svneol=native#text/plain res/cardsfolder/d/desert_sandstorm.txt svneol=native#text/plain res/cardsfolder/d/desert_twister.txt svneol=native#text/plain res/cardsfolder/d/deserted_temple.txt svneol=native#text/plain +res/cardsfolder/d/desertion.txt -text res/cardsfolder/d/desolate_lighthouse.txt -text res/cardsfolder/d/desolation_angel.txt svneol=native#text/plain res/cardsfolder/d/desolation_giant.txt svneol=native#text/plain @@ -2785,6 +2793,7 @@ res/cardsfolder/e/enraging_licid.txt -text res/cardsfolder/e/enshrined_memories.txt svneol=native#text/plain res/cardsfolder/e/enslave.txt svneol=native#text/plain res/cardsfolder/e/enslaved_dwarf.txt svneol=native#text/plain +res/cardsfolder/e/enslaved_horror.txt -text res/cardsfolder/e/enslaved_scout.txt svneol=native#text/plain res/cardsfolder/e/ensnare.txt svneol=native#text/plain res/cardsfolder/e/ensnaring_bridge.txt svneol=native#text/plain @@ -3600,6 +3609,7 @@ res/cardsfolder/g/gideons_lawkeeper.txt svneol=native#text/plain res/cardsfolder/g/gift_of_estates.txt svneol=native#text/plain res/cardsfolder/g/gift_of_granite.txt svneol=native#text/plain res/cardsfolder/g/gift_of_the_deity.txt svneol=native#text/plain +res/cardsfolder/g/gift_of_the_gargantuan.txt -text res/cardsfolder/g/gift_of_the_woods.txt svneol=native#text/plain res/cardsfolder/g/gigadrowse.txt svneol=native#text/plain res/cardsfolder/g/gigantomancer.txt svneol=native#text/plain @@ -4345,6 +4355,7 @@ res/cardsfolder/h/howling_fury.txt svneol=native#text/plain res/cardsfolder/h/howling_gale.txt svneol=native#text/plain res/cardsfolder/h/howling_mine.txt svneol=native#text/plain res/cardsfolder/h/howling_wolf.txt svneol=native#text/plain +res/cardsfolder/h/howltooth_hollow.txt -text res/cardsfolder/h/hua_tuo_honored_physician.txt svneol=native#text/plain res/cardsfolder/h/huang_zhong_shu_general.txt svneol=native#text/plain res/cardsfolder/h/hulking_cyclops.txt svneol=native#text/plain @@ -7954,6 +7965,7 @@ res/cardsfolder/s/second_wind.txt svneol=native#text/plain res/cardsfolder/s/secretkeeper.txt -text res/cardsfolder/s/secrets_of_the_dead.txt -text res/cardsfolder/s/security_detail.txt svneol=native#text/plain +res/cardsfolder/s/sedge_sliver.txt -text res/cardsfolder/s/sedge_troll.txt svneol=native#text/plain res/cardsfolder/s/sedraxis_alchemist.txt svneol=native#text/plain res/cardsfolder/s/sedraxis_specter.txt svneol=native#text/plain @@ -8109,6 +8121,7 @@ res/cardsfolder/s/shatterstorm.txt svneol=native#text/plain res/cardsfolder/s/shauku_endbringer.txt svneol=native#text/plain res/cardsfolder/s/shaukus_minion.txt svneol=native#text/plain res/cardsfolder/s/shell_skulkin.txt svneol=native#text/plain +res/cardsfolder/s/shelldock_isle.txt -text res/cardsfolder/s/shelter.txt -text res/cardsfolder/s/sheltered_valley.txt svneol=native#text/plain res/cardsfolder/s/sheltering_prayers.txt svneol=native#text/plain @@ -8726,6 +8739,7 @@ res/cardsfolder/s/spined_sliver.txt svneol=native#text/plain res/cardsfolder/s/spined_thopter.txt svneol=native#text/plain res/cardsfolder/s/spined_wurm.txt svneol=native#text/plain res/cardsfolder/s/spineless_thug.txt svneol=native#text/plain +res/cardsfolder/s/spinerock_knoll.txt -text res/cardsfolder/s/spinneret_sliver.txt svneol=native#text/plain res/cardsfolder/s/spiny_starfish.txt -text res/cardsfolder/s/spiraling_duelist.txt svneol=native#text/plain @@ -10617,6 +10631,7 @@ res/cardsfolder/w/withered_wretch.txt svneol=native#text/plain res/cardsfolder/w/withering_boon.txt svneol=native#text/plain res/cardsfolder/w/withering_gaze.txt svneol=native#text/plain res/cardsfolder/w/withering_hex.txt svneol=native#text/plain +res/cardsfolder/w/withering_wisps.txt -text res/cardsfolder/w/witherscale_wurm.txt -text svneol=unset#text/plain res/cardsfolder/w/withstand.txt svneol=native#text/plain res/cardsfolder/w/withstand_death.txt svneol=native#text/plain @@ -10845,37 +10860,12 @@ res/draft/uncommon.txt svneol=native#text/plain res/gamedata/NonStackingKWList.txt svneol=native#text/plain res/gamedata/TypeLists.txt svneol=native#text/plain res/gui/display_new_layout.xml -text svneol=unset#text/plain -res/images/deckeditor/filter_artifact_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_artifact_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_black_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_black_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_blue_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_blue_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_colorless_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_colorless_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_creature_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_creature_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_enchant_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_enchant_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_green_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_green_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_instant_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_instant_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_land_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_land_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_planeswalker_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_planeswalker_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_red_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_red_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_sorcery_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_sorcery_y.png -text svneol=unset#image/png -res/images/deckeditor/filter_white_n.png -text svneol=unset#image/png -res/images/deckeditor/filter_white_y.png -text svneol=unset#image/png res/lang/de.properties svneol=native#text/plain res/lang/en.properties svneol=native#text/plain res/lang/howTo/de.properties svneol=native#text/plain res/lang/howTo/en.properties svneol=native#text/plain res/lang/lang.properties svneol=native#text/plain +res/layouts/editor_default.xml -text res/layouts/match_default.xml -text res/licenses/java-yield-license.txt svneol=native#text/plain res/licenses/log4j-license.txt svneol=native#text/plain @@ -11080,6 +11070,8 @@ res/pics_product/tournamentpacks/SHM.jpg -text res/pics_product/tournamentpacks/TMP.jpg -text res/pics_product/tournamentpacks/TSP.jpg -text res/pics_product/tournamentpacks/USG.jpg -text +res/preferences/editor.preferences -text +res/preferences/main.properties -text res/product-images.txt -text res/quest/all-prices.txt svneol=native#text/plain res/quest/bazaar/ape_pet_l1.txt -text @@ -11369,6 +11361,7 @@ res/quest/duels/Professor[!!-~]X[!!-~]2.dck -text res/quest/duels/Professor[!!-~]X[!!-~]3.dck -text res/quest/duels/R2-D2[!!-~]3.dck -text res/quest/duels/Radagast[!!-~]2.dck -text +res/quest/duels/Radiant[!!-~]2.dck -text res/quest/duels/Radiant[!!-~]3.dck -text res/quest/duels/Radioactive[!!-~]Man[!!-~]3.dck -text res/quest/duels/Radioactive[!!-~]Man[!!-~]4.dck -text @@ -11600,7 +11593,6 @@ res/skins/the_simpsons/bg_texture.jpg -text res/skins/the_simpsons/font1.ttf -text res/skins/the_simpsons/sprite_avatars.png -text res/skins/the_simpsons/sprite_icons.png -text -res/sound/tap.mp3 -text svneol=unset#audio/mpeg res/token-images.txt -text src/main/config/Forge.icns -text src/main/config/backgroundImage.jpg -text svneol=unset#image/jpeg @@ -11637,7 +11629,6 @@ src/main/java/forge/GameEntity.java -text src/main/java/forge/GameLog.java -text src/main/java/forge/HandSizeOp.java svneol=native#text/plain src/main/java/forge/ImageCache.java svneol=native#text/plain -src/main/java/forge/MyObservable.java svneol=native#text/plain src/main/java/forge/NameChanger.java svneol=native#text/plain src/main/java/forge/Singletons.java svneol=native#text/plain src/main/java/forge/StaticEffect.java svneol=native#text/plain @@ -11926,34 +11917,47 @@ src/main/java/forge/gui/MultiLineLabelUI.java svneol=native#text/plain src/main/java/forge/gui/MultiPhaseProgressMonitorWithETA.java svneol=native#text/plain src/main/java/forge/gui/SOverlayUtils.java -text src/main/java/forge/gui/WrapLayout.java -text -src/main/java/forge/gui/deckeditor/DeckController.java -text -src/main/java/forge/gui/deckeditor/DeckEditorBase.java -text -src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/DeckEditorLimited.java -text -src/main/java/forge/gui/deckeditor/DeckEditorQuest.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/CDeckEditorUI.java -text src/main/java/forge/gui/deckeditor/DeckImport.java -text -src/main/java/forge/gui/deckeditor/DraftingProcess.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/MenuBase.java -text src/main/java/forge/gui/deckeditor/MenuCommon.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/MenuLimited.java -text -src/main/java/forge/gui/deckeditor/MenuQuest.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/PresetColumns.java -text -src/main/java/forge/gui/deckeditor/QuestCardShop.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java -text -src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java -text -src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java -text -src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java -text -src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java -text -src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java -text -src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java -text -src/main/java/forge/gui/deckeditor/elements/TableModel.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/TableSorter.java svneol=native#text/plain -src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java -text -src/main/java/forge/gui/deckeditor/elements/TableView.java -text -src/main/java/forge/gui/deckeditor/elements/package-info.java -text +src/main/java/forge/gui/deckeditor/SEditorIO.java -text +src/main/java/forge/gui/deckeditor/SEditorUtil.java -text +src/main/java/forge/gui/deckeditor/SFilterUtil.java -text +src/main/java/forge/gui/deckeditor/VDeckEditorUI.java -text +src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java -text +src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java -text +src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java -text +src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java -text +src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java -text +src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java -text +src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java -text +src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java -text +src/main/java/forge/gui/deckeditor/controllers/CFilters.java -text +src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java -text +src/main/java/forge/gui/deckeditor/controllers/CStatistics.java -text src/main/java/forge/gui/deckeditor/package-info.java -text +src/main/java/forge/gui/deckeditor/tables/DeckController.java -text +src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java -text +src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java -text +src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java -text +src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java -text +src/main/java/forge/gui/deckeditor/tables/TableModel.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/tables/TableSorter.java svneol=native#text/plain +src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java -text +src/main/java/forge/gui/deckeditor/tables/TableView.java -text +src/main/java/forge/gui/deckeditor/tables/package-info.java -text +src/main/java/forge/gui/deckeditor/views/ITableContainer.java -text +src/main/java/forge/gui/deckeditor/views/VAllDecks.java -text +src/main/java/forge/gui/deckeditor/views/VCardCatalog.java -text +src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java -text +src/main/java/forge/gui/deckeditor/views/VDeckgen.java -text +src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java -text +src/main/java/forge/gui/deckeditor/views/VFilters.java -text +src/main/java/forge/gui/deckeditor/views/VProbabilities.java -text +src/main/java/forge/gui/deckeditor/views/VStatistics.java -text src/main/java/forge/gui/download/GuiDownloadPicturesLQ.java svneol=native#text/plain src/main/java/forge/gui/download/GuiDownloadPrices.java svneol=native#text/plain src/main/java/forge/gui/download/GuiDownloadQuestImages.java -text @@ -11969,8 +11973,8 @@ src/main/java/forge/gui/framework/ILocalRepaint.java -text src/main/java/forge/gui/framework/IVDoc.java -text src/main/java/forge/gui/framework/IVTopLevelUI.java -text src/main/java/forge/gui/framework/SDisplayUtil.java -text -src/main/java/forge/gui/framework/SIOUtil.java -text src/main/java/forge/gui/framework/SLayoutConstants.java -text +src/main/java/forge/gui/framework/SLayoutIO.java -text src/main/java/forge/gui/framework/SOverflowUtil.java -text src/main/java/forge/gui/framework/SRearrangingUtil.java -text src/main/java/forge/gui/framework/SResizingUtil.java -text @@ -11990,7 +11994,7 @@ src/main/java/forge/gui/home/quest/CSubmenuQuestPrefs.java -text src/main/java/forge/gui/home/quest/IStatsAndPet.java -text src/main/java/forge/gui/home/quest/QuestFileLister.java -text src/main/java/forge/gui/home/quest/QuestPreferencesHandler.java -text -src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java -text +src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java -text src/main/java/forge/gui/home/quest/VSubmenuChallenges.java -text src/main/java/forge/gui/home/quest/VSubmenuDuels.java -text src/main/java/forge/gui/home/quest/VSubmenuQuestData.java -text @@ -12065,6 +12069,7 @@ src/main/java/forge/gui/toolbox/FRadioButton.java -text src/main/java/forge/gui/toolbox/FScrollPane.java -text src/main/java/forge/gui/toolbox/FSkin.java -text src/main/java/forge/gui/toolbox/FTextArea.java -text +src/main/java/forge/gui/toolbox/FTextField.java -text src/main/java/forge/gui/toolbox/SaveOpenDialog.java -text src/main/java/forge/gui/toolbox/package-info.java svneol=native#text/plain src/main/java/forge/item/BoosterPack.java -text @@ -12144,6 +12149,7 @@ src/main/java/forge/util/IStorageView.java -text src/main/java/forge/util/IgnoringXStream.java -text src/main/java/forge/util/LineReader.java -text src/main/java/forge/util/MultiplexOutputStream.java svneol=native#text/plain +src/main/java/forge/util/MyObservable.java svneol=native#text/plain src/main/java/forge/util/MyRandom.java svneol=native#text/plain src/main/java/forge/util/StorageImmediatelySerialized.java svneol=native#text/plain src/main/java/forge/util/StorageReaderFile.java -text @@ -12156,6 +12162,7 @@ src/main/java/forge/util/closures/Lambda.java svneol=native#text/plain src/main/java/forge/util/closures/Lambda0.java -text src/main/java/forge/util/closures/Lambda1.java svneol=native#text/plain src/main/java/forge/util/closures/Predicate.java -text +src/main/java/forge/util/closures/PredicateInteger.java -text src/main/java/forge/util/closures/PredicateString.java -text src/main/java/forge/util/closures/package-info.java -text svneol=native#text/plain src/main/java/forge/util/package-info.java -text diff --git a/.gitignore b/.gitignore index bd0d27ddc79..02a9b07b567 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /release.properties res/PerSetTrackingResults res/cardsfolder/cardsfolder.zip +res/cardsfolder/test_cards res/decks/30to1's[!!-~]Mine[!!-~]Combo.dck res/decks/A[!!-~]Real[!!-~]BoonNoggle[!!-~](Levi[!!-~]Howa).dck res/decks/AI_o1.dck @@ -268,7 +269,6 @@ res/decks/Zemox's[!!-~]Mono-Green[!!-~]Infect.dck res/decks/Zvi[!!-~]Mowshowitz's[!!-~]Mono-Black[!!-~]Control.dck res/decks/constructed/*.dck res/decks/o1.bdk -res/images/themes res/layouts/*.xml res/oracleScript.log res/pics @@ -289,6 +289,7 @@ res/pics/APC res/pics/ARB res/pics/ARN res/pics/ATQ +res/pics/AVR res/pics/BOK res/pics/CFX res/pics/CHK @@ -357,6 +358,8 @@ res/pics/ZEN res/pics/booster res/pics/icons res/pics/tokens/*.jpg +res/pics_product/*.jpg +res/preferences/forge.preferences res/quest/data res/quest/quest.preferences res/quest/questData.dat diff --git a/CHANGES.txt b/CHANGES.txt index 41afa4bd2c6..e6e3006d90c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,6 +5,26 @@ Forge Beta: 0#-##-2012 ver 1.2.8 10### cards in total. +The deck editors now use the new UI. The new deck editors include: + +* a better text search (can search for multiple terms, and "not" terms +* interval filters for P/T and CMC +* add/remove 4 +* better statistics and draw probabilities +* Toggle-able, sort-able, resize-able, move-able columns +* and of course uses the drag cell layout. + +With the update to the new deck editors several people have noticed an error when they run the snapshot build. We hope to have this fixed in the near future. This start up error states: + +Detailed error trace: +java.lang.NullPointerException +at forge.gui.deckeditor.controllers.CEditorPreferences.initialize(CEditorPreferences.java:45) +at forge.view.FView.initialize(FView.java:97) + + +The res/images/icons/ folder has been moved to res/pics/icons/. This folder holds the quest opponent icons, bazaar pets, and bazaar plants. If you have downloaded this content, it will still work, but the folder must be moved on your computer. + + Some people have noticed special quests do not have the start in play cards appearing. And some people have noticed that a match can start without any cards appearing in the players hands or in their libraries. A possible fix was submitted to the SVN for forge version 1.2.7. We have received several reports that the above bugs are still occuring. We hope to have this problem fixed at some point in the future. @@ -109,6 +129,86 @@ Fixes/Features: - Added a fluff piece to the changes.txt file. - Clear Simultaneous triggers at the end of the game - Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Fixed AI of Increasing Confusion. +- Replaced some instances of af.getHostCard() with sa.getSourceCard(). +- merge updates from Trunk 15508-15541 +- costmanaparser +- made it buildable (there were missing refs to VDock and FSkin) +- removed some obvious warnings +- Switched mana to ManaCostShards, removed special classes for each mana kind +- Fixed the ability costs for Ghave, Guru of Spores. +- Fixed Iceberg. +- Improved AI for Soulbond. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Reorganized some parts of digResolve (some more parameters now work together or without certain others). +- add check for empty cost string +- Fixed Endless Wurm. +- Fixed Inquisitor's Flail. +- ManaPaid back to Mana +- Merged ManaCost upgrade from branch into trunk (r15546-15556) +- remove warnings, removed manaparser +- adding RestrictValid parameter support to AbilityMana and InputPayMAnaCostUtil +- Fixed Trusted Advisor and similar cards. +- adding RestrictValid parameter support to ComputerUtil to check restriction for AI +- MyObservable - moved frequent calls to a variable, moved the very class to utils package +- Added the AI SVar "HasAttackEffect". +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Added "SVar:HasAttackEffect:TRUE" to some cards. +- Added "SVar:HasAttackEffect:TRUE" to two more cards. +- Updated some decks with new cards. +- Fixed a bug with initiatePossibleDefenders. +- More Cleanup in Combat class. +- Added a medium version of the Radiant deck. +- Updated three decks with new cards. +- Improved AI of AF Dig. +- Cleanup in AF Dig. +- Checkstyle fixes to CDock. +- CardCharacteristics stores manacost as CardManaCost instead of String +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Fixed Sludge Strider's 'leaves the battlefield' trigger. +- Quick fix for unless costs of zero mana. +- A triggered ability that fails targeting will no longer clear the whole frozen stack (only its own stack instance). +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Uploaded the Avacyn Restored set and token images. Updated scripts for token generators in the set to use set specific tokens. Updated token links. +- Added the optional parameter "ForgetRemembered" to AF Play. +- ActivationLimit can calculate values from svars now. +- Fixed typo in recently added cards (my commit comment was misspelled) +- Updated card prices. +- Updated two AI SVars. +- Replaced some instances of af.getHostCard() with sa.getSourceCard(). +- Fixed a lot of sloppily scripted SpellCast triggers (A-E). +- Fixed a lot of sloppily scripted SpellCast triggers (F-H). +- Fixed a lot of sloppily scripted SpellCast triggers (I-M). +- Fixed a lot of sloppily scripted SpellCast triggers (N-Z). +- Reordered trigger condition checks for better performance. +- Updated two AI SVars. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- The AI will now cast Equipments in Main1 if a possible attacker is present. +- Deck editor UI integration. +- Default layout file for editor added. +- Removed font scaling from FLabel. +- Updated Firebloom skin with improved icons and compressed background images (thanks WompWomp). +- Updated load/save layout icons. +- Removed some legacy accessors from VMatchUI. +- Updated document ID enum with more descriptive names. +- Rolling back last commit; unforeseen problems. +- Renamed "ForgeIcons" enum in FSkin to more accurate "InterfaceIcons". +- Fixed "Tapped" parameter in AF ChangeZone. +- Fixed and simplified Deadeye Navigator. +- Fixed a tooltip typo. +- Added the recent commit logs to changes.txt. +- Replaced two tooltips. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. +- Some preparations for better planeswalker attacking AI. +- Replaced finalizer method in main(), attempting to fix race condition at startup. +- Fixed dev mode toggle in preferences submenu/match UI. +- Updated card detail text area to always scroll to top. +- Fixed unlimited lands bug. +- Fixed a two more copies of the tooltip typo. +- reworked Mana object paradigm and ManaPool +- Fixed Tamiyo's (and Venser's) emblem image download link +- Check for null spellAbility source card in mana restrictions. Makes multikicker not payable with restricted mana. +- Added the recent commit logs to changes.txt. Preparing for the snapshot build release. Many people helped with this version. A special thank you goes out to them. (Attempted to list names alphabetically): @@ -142,6 +242,20 @@ Impelled Giant Merrow Bonegnawer Stigma Lasher Shaper Parasite +Clear the Land +Enslaved Horror +Gift of the Gargantuan +Abundance +Acorn Catapult +Howltooth Hollow +Shelldock Isle +Sedge Sliver +Withering Wisps +Anthem of Rakdos +Apocalypse Chime +Spinerock Knoll +Desertion +Avizoa end diff --git a/README.txt b/README.txt index 2d03ed61703..85a0c730cd1 100644 --- a/README.txt +++ b/README.txt @@ -6,9 +6,9 @@ Once the Forge archive has been decompressed you should then be able to launch F After downloading and installing a newer version of Forge you may want to move certain files from the older version over to the newer version of Forge. You should maintain your older version of Forge as a back up in case you make a mistake while installing the newer version. -1) The /res/pics/ folder contains the card pictures and token pictures (mtg card tokens and quest pet/plant tokens). Please note that the /res/pics/icons/ folder was moved out of this folder and placed in the /res/images/ folder. The booster package images were moved to the /res/pics_product/booster/ folder. +1) The /res/pics/ folder contains the card pictures, icons and token pictures (mtg card tokens and quest pet/plant tokens). Please note that the /res/images/icons/ folder was moved back to the /res/pics/icons/ folder. The forge /res/images/ folder no longer is used as of version 1.2.8. -The /res/images/icons/ folder contains the quest opponent icons, small quest pet/plant icons (non-tokens) and some icons that are used by forge's quest mode. While several of these pictures ship with the forge archive most of them have to be downloaded using the Home screen -> Utilities -> Download Quest Images command. +The /res/pics/icons/ folder contains the quest opponent icons, small quest pet/plant icons (non-tokens) and some icons that are used by forge's quest mode. While several of these pictures ship with the forge archive most of them have to be downloaded using the Home screen -> Utilities -> Download Quest Images command. 2) The /res/pics_product/ folder contains four folders which in turn contain pictures for the booster, fatpacks, precons and tournamentpacks products. diff --git a/forge.properties b/forge.properties index 27f98ca1aab..e6f0c145c8c 100644 --- a/forge.properties +++ b/forge.properties @@ -43,4 +43,4 @@ # this link includes the main properties file. you can move/rename etc. the res-folder. you just have to change # this single line -main--transparent-properties=res/main.properties \ No newline at end of file +main--transparent-properties=res/preferences/main.properties diff --git a/res/cardsfolder/a/abundance.txt b/res/cardsfolder/a/abundance.txt new file mode 100644 index 00000000000..d1134e37d1c --- /dev/null +++ b/res/cardsfolder/a/abundance.txt @@ -0,0 +1,15 @@ +Name:Abundance +ManaCost:2 G G +Types:Enchantment +Text:no text +R:Event$ Draw | ValidPlayer$ You | ReplaceWith$ AbundantChoice | Optional$ True | Description$ If you would draw a card, you may instead choose land or nonland and reveal cards from the top of your library until you reveal a card of the chosen kind. Put that card into your hand and put all other cards revealed this way on the bottom of your library in any order. +SVar:AbundantChoice:AB$ GenericChoice | Cost$ 0 | Choices$ DigLand,DigNonland | Defined$ You +SVar:DigLand:DB$ DigUntil | Valid$ Card.Land | ValidDescription$ land | FoundDestination$ Hand | RevealedDestination$ Library | RevealedLibraryPosition$ -1 | ChoiceDescription$ Land +SVar:DigNonland:DB$ DigUntil | Valid$ Card.nonLand | ValidDescription$ nonland | FoundDestination$ Hand | RevealedDestination$ Library | RevealedLibraryPosition$ -1 | ChoiceDescription$ nonLand +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/abundance.jpg +SetInfo:USG|Rare|http://magiccards.info/scans/en/us/229.jpg +SetInfo:10E|Rare|http://magiccards.info/scans/en/10e/249.jpg +Oracle:If you would draw a card, you may instead choose land or nonland and reveal cards from the top of your library until you reveal a card of the chosen kind. Put that card into your hand and put all other cards revealed this way on the bottom of your library in any order. +End \ No newline at end of file diff --git a/res/cardsfolder/a/acidic_dagger.txt b/res/cardsfolder/a/acidic_dagger.txt new file mode 100644 index 00000000000..8e89780163b --- /dev/null +++ b/res/cardsfolder/a/acidic_dagger.txt @@ -0,0 +1,16 @@ +Name:Acidic Dagger +ManaCost:4 +Types:Artifact +Text:no text +A:AB$ Effect | Cost$ 4 T | Name$ Acidic Dagger Effect | ValidTgts$ Creature | TgtPrompt$ Select target creature | Triggers$ TrigDam,TrigLeave | SVars$ TrigDestroy,TrigSac,ExileEffect | RememberObjects$ Targeted | ImprintCards$ Self | ActivationPhases$ Upkeep->Declare Attackers - Play Instants and Abilities | SpellDescription$ Whenever target creature deals combat damage to a non-Wall creature this turn, destroy that non-Wall creature. When the targeted creature leaves the battlefield this turn, sacrifice CARDNAME. Activate this ability only before blockers are declared. +SVar:TrigDam:Mode$ DamageDone | ValidSource$ Creature.IsRemembered | ValidTarget$ Creature.nonWall | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigDestroy | TriggerDescription$ Whenever targeted creature deals combat damage to a non-Wall creature this turn, destroy that non-Wall creature. +SVar:TrigLeave:Mode$ ChangesZone | ValidCard$ Creature.IsRemembered | Origin$ Battlefield | Destination$ Any | Execute$ TrigSac | TriggerDescription$ When the targeted creature leaves the battlefield this turn, sacrifice Acidic Dagger. +SVar:TrigDestroy:AB$Destroy | Cost$ 0 | Defined$ TriggeredTarget +SVar:TrigSac:DB$ SacrificeAll | Defined$ Imprinted | SubAbility$ ExileEffect +SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Exile | Static$ True +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/acidic_dagger.jpg +SetInfo:MIR|Rare|http://magiccards.info/scans/en/mr/256.jpg +Oracle:{4}, {T}: Whenever target creature deals combat damage to a non-Wall creature this turn, destroy that non-Wall creature. When the targeted creature leaves the battlefield this turn, sacrifice Acidic Dagger. Activate this ability only before blockers are declared. +End \ No newline at end of file diff --git a/res/cardsfolder/a/acorn_catapult.txt b/res/cardsfolder/a/acorn_catapult.txt new file mode 100644 index 00000000000..f0e68049ce6 --- /dev/null +++ b/res/cardsfolder/a/acorn_catapult.txt @@ -0,0 +1,13 @@ +Name:Acorn Catapult +ManaCost:4 +Types:Artifact +Text:no text +A:AB$ DealDamage | Cost$ 1 T | NumDmg$ 1 | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player | SubAbility$ SquirrelTokenCtrl | SpellDescription$ CARDNAME deals 1 damage to target creature or player. That creature's controller or that player puts a 1/1 green Squirrel creature token onto the battlefield. +SVar:SquirrelTokenCtrl:DB$Token | TokenAmount$ 1 | TokenName$ Squirrel | TokenTypes$ Creature,Squirrel | TokenOwner$ Targeted | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 | SubAbility$ SquirrelTokenPlayer | ConditionDefined$ Targeted | ConditionPresent$ Card.Creature | ConditionCompare$ EQ0 +SVar:SquirrelTokenPlayer:DB$Token | TokenAmount$ 1 | TokenName$ Squirrel | TokenTypes$ Creature,Squirrel | TokenOwner$ TargetedController | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 | ConditionDefined$ Targeted | ConditionPresent$ Card.Creature | ConditionCompare$ GE1 +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/acorn_catapult.jpg +SetInfo:COM|Rare|http://magiccards.info/scans/en/cmd/241.jpg +Oracle:{1}, {T}: Acorn Catapult deals 1 damage to target creature or player. That creature's controller or that player puts a 1/1 green Squirrel creature token onto the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/a/aether_barrier.txt b/res/cardsfolder/a/aether_barrier.txt index 14306a7b414..e1f95fd54b8 100644 --- a/res/cardsfolder/a/aether_barrier.txt +++ b/res/cardsfolder/a/aether_barrier.txt @@ -3,7 +3,8 @@ ManaCost:2 U Types:Enchantment Text:no text T:Mode$ SpellCast | ValidCard$ Creature | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ Whenever a player casts a creature spell, that player sacrifices a permanent unless he or she pays 1. -SVar:TrigSac:AB$Sacrifice | Cost$ 0 | UnlessCost$ 1 | UnlessPayer$ TriggeredPlayer | Defined$ TriggeredPlayer | SacValid$ Permanent +SVar:TrigSac:AB$Sacrifice | Cost$ 0 | UnlessCost$ 1 | UnlessPayer$ TriggeredActivator | Defined$ TriggeredActivator | SacValid$ Permanent +SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/aether_barrier.jpg SetInfo:NMS|Rare|http://magiccards.info/scans/en/ne/27.jpg diff --git a/res/cardsfolder/a/aether_sting.txt b/res/cardsfolder/a/aether_sting.txt index 3fce5c69c6b..68626cd3fb8 100644 --- a/res/cardsfolder/a/aether_sting.txt +++ b/res/cardsfolder/a/aether_sting.txt @@ -2,8 +2,8 @@ Name:AEther Sting ManaCost:3 R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Creature | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever an opponent casts a creature spell, CARDNAME deals 1 damage to that player. -SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Defined$ Opponent | NumDmg$ 1 +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever an opponent casts a creature spell, CARDNAME deals 1 damage to that player. +SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Defined$ TriggeredActivator | NumDmg$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/aether_sting.jpg SetInfo:UDS|Uncommon|http://magiccards.info/scans/en/ud/76.jpg diff --git a/res/cardsfolder/a/animar_soul_of_elements.txt b/res/cardsfolder/a/animar_soul_of_elements.txt index e8787573147..0b06670e9e0 100644 --- a/res/cardsfolder/a/animar_soul_of_elements.txt +++ b/res/cardsfolder/a/animar_soul_of_elements.txt @@ -5,7 +5,7 @@ Text:no text PT:1/1 K:Protection from white K:Protection from black -T:Mode$ SpellCast | ValidCard$ Card.Creature+YouCtrl | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, put a +1/+1 counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 K:CostChange:Player:Less:X:Spell:All:Creature:NoSpecial:Creature spells you cast cost 1 less to cast for each +1/+1 counter on Animar. SVar:X:Count$NumCounters.P1P1 diff --git a/res/cardsfolder/a/anthem_of_rakdos.txt b/res/cardsfolder/a/anthem_of_rakdos.txt new file mode 100644 index 00000000000..363907bdf78 --- /dev/null +++ b/res/cardsfolder/a/anthem_of_rakdos.txt @@ -0,0 +1,18 @@ +Name:Anthem of Rakdos +ManaCost:2 B R R +Types:Enchantment +Text:no text +T:Mode$ Attacks | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ AnthemPump | TriggerDescription$ Whenever a creature you control attacks, it gets +2/+0 until end of turn and CARDNAME deals 1 damage to you. +SVar:AnthemPump:AB$Pump | Cost$ 0 | Defined$ TriggeredAttacker | NumAtt$ +2 | SubAbility$ RakdosBurn +SVar:RakdosBurn:DB$ DealDamage | Defined$ You | NumDmg$ 1 +R:Event$ DamageDone | ValidSource$ Card.YouCtrl | ValidTarget$ Creature,Player | Hellbent$ True | ReplaceWith$ DmgTwice | IsCombat$ False | Description$ Hellbent - As long as you have no cards in hand, if a source you control would deal damage to a creature or player, it deals double that damage to that creature or player instead. +R:Event$ DamageDone | ValidSource$ Card.YouCtrl | ValidTarget$ Creature,Player | Hellbent$ True | ReplaceWith$ DmgTwiceCombat | IsCombat$ True | Secondary$ True | Description$ Hellbent - As long as you have no cards in hand, if a source you control would deal damage to a creature or player, it deals double that damage to that creature or player instead. +SVar:DmgTwice:AB$DealDamage | Cost$ 0 | Defined$ ReplacedTarget | DamageSource$ ReplacedSource | NumDmg$ X +SVar:DmgTwiceCombat:AB$DealDamage | Cost$ 0 | CombatDamage$ True | Defined$ ReplacedTarget | DamageSource$ ReplacedSource | NumDmg$ X +SVar:X:ReplaceCount$DamageAmount/Twice +SVar:PlayMain1:TRUE +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/anthem_of_rakdos.jpg +SetInfo:DIS|Rare|http://magiccards.info/scans/en/di/102.jpg +Oracle:Whenever a creature you control attacks, it gets +2/+0 until end of turn and Anthem of Rakdos deals 1 damage to you.\nHellbent - As long as you have no cards in hand, if a source you control would deal damage to a creature or player, it deals double that damage to that creature or player instead. +End \ No newline at end of file diff --git a/res/cardsfolder/a/apocalypse_chime.txt b/res/cardsfolder/a/apocalypse_chime.txt new file mode 100644 index 00000000000..309b321561a --- /dev/null +++ b/res/cardsfolder/a/apocalypse_chime.txt @@ -0,0 +1,11 @@ +Name:Apocalypse Chime +ManaCost:2 +Types:Artifact +Text:no text +A:AB$DestroyAll | Cost$ 2 T Sac<1/CARDNAME> | ValidCards$ Permanent.nonToken+setHML | NoRegen$ True | SpellDescription$ Destroy all nontoken permanents from the Homelands expansion. They can't be regenerated. +SVar:RemRandomDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/apocalypse_chime.jpg +SetInfo:HML|Rare|http://magiccards.info/scans/en/hl/126.jpg +Oracle:{2}, {T}, Sacrifice Apocalypse Chime: Destroy all nontoken permanents from the Homelands expansion. They can't be regenerated. +End \ No newline at end of file diff --git a/res/cardsfolder/a/argentum_armor.txt b/res/cardsfolder/a/argentum_armor.txt index 96ed6b0ba07..b1d607ea490 100644 --- a/res/cardsfolder/a/argentum_armor.txt +++ b/res/cardsfolder/a/argentum_armor.txt @@ -5,6 +5,8 @@ Text:Equipped creature gets +6/+6. K:eqPump 6:+6/+6 T:Mode$ Attacks | ValidCard$ Card.AttachedBy | Execute$ TrigDestroy | TriggerDescription$ Whenever equipped creature attacks, destroy target permanent. SVar:TrigDestroy:AB$Destroy | Cost$ 0 | ValidTgts$ Permanent | TgtPrompt$ Select target permanent +S:Mode$ Continuous | Affected$ Creature.AttachedBy | AddSVar$ AE +SVar:AE:SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/argentum_armor.jpg SetInfo:SOM|Rare|http://magiccards.info/scans/en/som/137.jpg diff --git a/res/cardsfolder/a/argothian_enchantress.txt b/res/cardsfolder/a/argothian_enchantress.txt index a5cf38fd340..d07cf956d80 100644 --- a/res/cardsfolder/a/argothian_enchantress.txt +++ b/res/cardsfolder/a/argothian_enchantress.txt @@ -4,7 +4,7 @@ Types:Creature Human Druid Text:no text PT:0/1 K:Shroud -T:Mode$ SpellCast | ValidCard$ Enchantment.YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. +T:Mode$ SpellCast | ValidCard$ Enchantment | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/argothian_enchantress.jpg diff --git a/res/cardsfolder/a/aurora_eidolon.txt b/res/cardsfolder/a/aurora_eidolon.txt index 772e5566899..8c2b9ef4c43 100644 --- a/res/cardsfolder/a/aurora_eidolon.txt +++ b/res/cardsfolder/a/aurora_eidolon.txt @@ -4,7 +4,7 @@ Types:Creature Spirit Text:no text PT:2/2 A:AB$ PreventDamage | Cost$ W Sac<1/CARDNAME> | ValidTgts$ Creature,Player | TgtPrompt$ Select target creature or player | Amount$ 3 | SpellDescription$ Prevent the next 3 damage that would be dealt to target creature or player this turn. -T:Mode$ SpellCast | ValidCard$ Card.MultiColor+YouCtrl | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Hand | Defined$ Self SVar:RemAIDeck:True SVar:Rarity:Common diff --git a/res/cardsfolder/a/avizoa.txt b/res/cardsfolder/a/avizoa.txt new file mode 100644 index 00000000000..800eb90053f --- /dev/null +++ b/res/cardsfolder/a/avizoa.txt @@ -0,0 +1,14 @@ +Name:Avizoa +ManaCost:3 U +Types:Creature Jellyfish +Text:no text +PT:2/2 +K:Flying +A:AB$ Pump | Cost$ 0 | NumAtt$ +2 | NumDef$ +2 | ActivationLimit$ 1 | SubAbility$ DBSkipTurn | SpellDescription$ CARDNAME gets +2/+2 until end of turn. You skip your next untap step. Activate this ability only once each turn. +SVar:DBSkipTurn:DB$ Pump | Defined$ You | KW$ Skip your next untap step. | Permanent$ True +SVar:RemAIDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/avizoa.jpg +SetInfo:WTH|Rare|http://magiccards.info/scans/en/wl/35.jpg +Oracle:Flying\n{0}: Avizoa gets +2/+2 until end of turn. You skip your next untap step. Activate this ability only once each turn. +End \ No newline at end of file diff --git a/res/cardsfolder/b/balefire_liege.txt b/res/cardsfolder/b/balefire_liege.txt index dfa98a3181c..b5235910b78 100644 --- a/res/cardsfolder/b/balefire_liege.txt +++ b/res/cardsfolder/b/balefire_liege.txt @@ -5,8 +5,8 @@ Text:no text PT:2/4 S:Mode$ Continuous | Affected$ Creature.Red+Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other red creatures you control get +1/+1. S:Mode$ Continuous | Affected$ Creature.White+Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other white creatures you control get +1/+1. -T:Mode$ SpellCast | ValidCard$ Card.Red+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a red spell, CARDNAME deals 3 damage to target player. -T:Mode$ SpellCast | ValidCard$ Card.White+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever you cast a white spell, you gain 3 life. +T:Mode$ SpellCast | ValidCard$ Card.Red | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a red spell, CARDNAME deals 3 damage to target player. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever you cast a white spell, you gain 3 life. SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Tgt$ TgtP | NumDmg$ 3 SVar:TrigGainLife:AB$GainLife | Cost$ 0 | Defined$ You | LifeAmount$ 3 SVar:PlayMain1:TRUE diff --git a/res/cardsfolder/b/ballynock_trapper.txt b/res/cardsfolder/b/ballynock_trapper.txt index e5d9fab8628..941897ce065 100644 --- a/res/cardsfolder/b/ballynock_trapper.txt +++ b/res/cardsfolder/b/ballynock_trapper.txt @@ -4,7 +4,7 @@ Types:Creature Kithkin Soldier Text:no text PT:2/2 A:AB$ Tap | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Tap target creature. -T:Mode$ SpellCast | ValidCard$ Card.White+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a white spell, you may untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a white spell, you may untap CARDNAME. SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/ballynock_trapper.jpg diff --git a/res/cardsfolder/b/battlewand_oak.txt b/res/cardsfolder/b/battlewand_oak.txt index cce6237de7f..742f9e6acd5 100644 --- a/res/cardsfolder/b/battlewand_oak.txt +++ b/res/cardsfolder/b/battlewand_oak.txt @@ -4,7 +4,7 @@ Types:Creature Treefolk Warrior Text:no text PT:1/3 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Forest.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever a Forest enters the battlefield under your control, CARDNAME gets +2/+2 until end of turn. -T:Mode$ SpellCast | ValidCard$ Treefolk.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a Treefolk spell, CARDNAME gets +2/+2 until end of turn. +T:Mode$ SpellCast | ValidCard$ Treefolk | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a Treefolk spell, CARDNAME gets +2/+2 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ Self | NumAtt$ 2 | NumDef$ 2 SVar:BuffedBy:Forest,Treefolk SVar:Rarity:Common diff --git a/res/cardsfolder/b/bloodbond_march.txt b/res/cardsfolder/b/bloodbond_march.txt index b4618688c68..93f25d3905d 100644 --- a/res/cardsfolder/b/bloodbond_march.txt +++ b/res/cardsfolder/b/bloodbond_march.txt @@ -1,12 +1,12 @@ -Name:Bloodbond March -ManaCost:2 B G -Types:Enchantment -Text:no text -T:Mode$ SpellCast | ValidCard$ Card.Creature | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ Whenever a player casts a creature spell, each player returns all cards with the same name as that spell from his or her graveyard to the battlefield. -SVar:TrigReturn:AB$ ChangeZoneAll | Cost$ 0 | ChangeType$ Triggered.sameName | Origin$ Graveyard | Destination$ Battlefield -SVar:RemRandomDeck:True -SVar:Rarity:Rare -SVar:Picture:http://www.wizards.com/global/images/magic/general/bloodbond_march.jpg -SetInfo:RAV|Rare|http://magiccards.info/scans/en/rav/192.jpg -Oracle:Whenever a player casts a creature spell, each player returns all cards with the same name as that spell from his or her graveyard to the battlefield. +Name:Bloodbond March +ManaCost:2 B G +Types:Enchantment +Text:no text +T:Mode$ SpellCast | ValidCard$ Creature | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ Whenever a player casts a creature spell, each player returns all cards with the same name as that spell from his or her graveyard to the battlefield. +SVar:TrigReturn:AB$ ChangeZoneAll | Cost$ 0 | ChangeType$ Triggered.sameName | Origin$ Graveyard | Destination$ Battlefield +SVar:RemRandomDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/bloodbond_march.jpg +SetInfo:RAV|Rare|http://magiccards.info/scans/en/rav/192.jpg +Oracle:Whenever a player casts a creature spell, each player returns all cards with the same name as that spell from his or her graveyard to the battlefield. End \ No newline at end of file diff --git a/res/cardsfolder/b/budoka_pupil_ichiga_who_topples_oaks.txt b/res/cardsfolder/b/budoka_pupil_ichiga_who_topples_oaks.txt index c3d4cdb55e9..15f507bd7a4 100644 --- a/res/cardsfolder/b/budoka_pupil_ichiga_who_topples_oaks.txt +++ b/res/cardsfolder/b/budoka_pupil_ichiga_who_topples_oaks.txt @@ -3,7 +3,7 @@ ManaCost:1 G G Types:Creature Human Monk Text:no text PT:2/2 -T:Mode$ SpellCast | ValidCard$ Card.Spirit,Card.Arcane | ValidControllingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Spirit,Arcane | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. T:Mode$ Phase | Phase$ End of Turn | IsPresent$ Card.Self+counters_GE2_KI | Execute$ TrigFlip | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of the end step, if there are two or more ki counters on Budoka Pupil, you may flip it. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ KI | CounterNum$ 1 SVar:TrigFlip:AB$SetState | Cost$ 0 | Defined$ Self | Mode$ Flip diff --git a/res/cardsfolder/b/burning_vengeance.txt b/res/cardsfolder/b/burning_vengeance.txt index b2263d592ca..6b051480268 100644 --- a/res/cardsfolder/b/burning_vengeance.txt +++ b/res/cardsfolder/b/burning_vengeance.txt @@ -2,8 +2,7 @@ Name:Burning Vengeance ManaCost:2 R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouOwn+wasCastFromGraveyard | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell from your graveyard, CARDNAME deals 2 damage to target creature or player. -#T:Mode$ ChangesZone | ValidCard$ Card.YouOwn | Origin$ Graveyard | Destination$ Stack | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell from your graveyard, CARDNAME deals 2 damage to target creature or player. +T:Mode$ SpellCast | ValidCard$ Card.wasCastFromGraveyard | ValidActivatingPlayer$ You | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell from your graveyard, CARDNAME deals 2 damage to target creature or player. SVar:TrigDamage:AB$ DealDamage | Cost$ 0| Tgt$ TgtCP | NumDmg$ 2 SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/c/callow_jushi_jaraku_the_interloper.txt b/res/cardsfolder/c/callow_jushi_jaraku_the_interloper.txt index aaa5eb79118..67f1eca8cca 100644 --- a/res/cardsfolder/c/callow_jushi_jaraku_the_interloper.txt +++ b/res/cardsfolder/c/callow_jushi_jaraku_the_interloper.txt @@ -3,7 +3,7 @@ ManaCost:1 U U Types:Creature Human Wizard Text:no text PT:2/2 -T:Mode$ SpellCast | ValidCard$ Card.Spirit,Card.Arcane | ValidControllingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Spirit,Arcane | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. T:Mode$ Phase | Phase$ End of Turn | IsPresent$ Card.Self+counters_GE2_KI | Execute$ TrigFlip | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of the end step, if there are two or more ki counters on CARDNAME, you may flip it. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ KI | CounterNum$ 1 SVar:TrigFlip:AB$SetState | Cost$ 0 | Defined$ Self | Mode$ Flip diff --git a/res/cardsfolder/c/chandra_the_firebrand.txt b/res/cardsfolder/c/chandra_the_firebrand.txt index 4c585bf55cd..8fbc4a613e5 100644 --- a/res/cardsfolder/c/chandra_the_firebrand.txt +++ b/res/cardsfolder/c/chandra_the_firebrand.txt @@ -6,7 +6,7 @@ Loyalty:3 A:AB$DealDamage | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Tgt$ TgtCP | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to target creature or player. A:AB$Effect | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Name$ Chandra, the Firebrand effect. | Image$ chandra_the_firebrand_effect | Triggers$ TrigCopy | SVars$ TrigCopyMain,DBCleanup | SpellDescription$ When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy. A:AB$DealDamage | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Tgt$ TgtCP | TargetMin$ 0 | TargetMax$ 6 | NumDmg$ 6 | SpellDescription$ CARDNAME deals 6 damage to each of up to six target creatures and/or players. -SVar:TrigCopy:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidControllingPlayer$ You | Execute$ TrigCopyMain | TriggerDescription$ When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy. +SVar:TrigCopy:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | Execute$ TrigCopyMain | TriggerDescription$ When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy. SVar:TrigCopyMain:AB$ CopySpell | Cost$ 0 | Defined$ TriggeredSpellAbility | SubAbility$ DBCleanup SVar:DBCleanup:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Graveyard SVar:Rarity:Mythic diff --git a/res/cardsfolder/c/charmbreaker_devils.txt b/res/cardsfolder/c/charmbreaker_devils.txt index a7eee58e9e7..0ff8f8da865 100644 --- a/res/cardsfolder/c/charmbreaker_devils.txt +++ b/res/cardsfolder/c/charmbreaker_devils.txt @@ -5,7 +5,7 @@ Text:no text PT:4/4 T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigChangeZone | TriggerDescription$ At the beginning of your upkeep, return an instant or sorcery card at random from your graveyard to your hand. SVar:TrigChangeZone:DB$ ChangeZone | ChangeType$ Instant.YouCtrl,Sorcery.YouCtrl | ChangeNum$ 1 | Hidden$ True | Origin$ Graveyard | AtRandom$ True | Destination$ Hand -T:Mode$ SpellCast | ValidCard$ Instant.YouCtrl,Sorcery.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a instant or sorcery spell, CARDNAME gets +4/+0 until end of turn. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a instant or sorcery spell, CARDNAME gets +4/+0 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | NumAtt$ +4 | NumDef$ +0 | Defined$ Self SVar:BuffedBy:Instant,Sorcery SVar:Rarity:Rare diff --git a/res/cardsfolder/c/citanul_druid.txt b/res/cardsfolder/c/citanul_druid.txt index 22e89702b96..1189b54b616 100644 --- a/res/cardsfolder/c/citanul_druid.txt +++ b/res/cardsfolder/c/citanul_druid.txt @@ -3,7 +3,7 @@ ManaCost:1 G Types:Creature Human Druid Text:no text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Artifact.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts an artifact spell, put a +1/+1 counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts an artifact spell, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/citanul_druid.jpg diff --git a/res/cardsfolder/c/clear_the_land.txt b/res/cardsfolder/c/clear_the_land.txt new file mode 100644 index 00000000000..254f2332ae7 --- /dev/null +++ b/res/cardsfolder/c/clear_the_land.txt @@ -0,0 +1,11 @@ +Name:Clear the Land +ManaCost:2 G +Types:Sorcery +Text:no text +A:SP$ Dig | Cost$ 2 G | DigNum$ 5 | Defined$ Each | Reveal$ True | ChangeNum$ All | ChangeValid$ Land | DestinationZone$ Battlefield | Tapped$ True | DestinationZone2$ Exile | SpellDescription$ Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest. +SVar:RemRandomDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/clear_the_land.jpg +SetInfo:MMQ|Rare|http://magiccards.info/scans/en/mm/235.jpg +Oracle:Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest. +End \ No newline at end of file diff --git a/res/cardsfolder/c/cloven_casting.txt b/res/cardsfolder/c/cloven_casting.txt index 6f0626ee790..731fa53cbbc 100644 --- a/res/cardsfolder/c/cloven_casting.txt +++ b/res/cardsfolder/c/cloven_casting.txt @@ -2,7 +2,7 @@ Name:Cloven Casting ManaCost:5 U R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Instant.MultiColor,Sorcery.MultiColor | ValidControllingPlayer$ You | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a multicolored instant or sorcery spell, you may pay 1. If you do, copy that spell. You may choose new targets for the copy. +T:Mode$ SpellCast | ValidCard$ Instant.MultiColor,Sorcery.MultiColor | ValidActivatingPlayer$ You | Execute$ TrigCopy | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a multicolored instant or sorcery spell, you may pay 1. If you do, copy that spell. You may choose new targets for the copy. SVar:TrigCopy:AB$ CopySpell | Cost$ 1 | Defined$ TriggeredSpellAbility SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/c/commanders_authority.txt b/res/cardsfolder/c/commanders_authority.txt index f4d2d65ef57..b40d8f8a58e 100644 --- a/res/cardsfolder/c/commanders_authority.txt +++ b/res/cardsfolder/c/commanders_authority.txt @@ -6,7 +6,7 @@ K:Enchant Creature A:SP$ Attach | Cost$ 4 W | ValidTgts$ Creature | AILogic$ Pump S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddTrigger$ CommanderTrig | AddSVar$ CommanderToken | Description$ Enchanted creature has "At the beginning of your upkeep, put a 1/1 white Human creature token onto the battlefield." SVar:CommanderTrig:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ CommanderToken | TriggerDescription$ At the beginning of your upkeep, put a 1/1 white Human creature token onto the battlefield. -SVar:CommanderToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Human | TokenTypes$ Creature,Human | TokenOwner$ You | TokenPower$ 1 | TokenToughness$ 1 | TokenColors$ White +SVar:CommanderToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Human | TokenTypes$ Creature,Human | TokenOwner$ You | TokenPower$ 1 | TokenToughness$ 1 | TokenColors$ White | TokenImage$ w 1 1 human avr SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/commanders_authority.jpg SetInfo:AVR|Uncommon|http://magiccards.info/scans/en/avr/13.jpg diff --git a/res/cardsfolder/c/contemplation.txt b/res/cardsfolder/c/contemplation.txt index 246e781ceb4..6edb5cb4b34 100644 --- a/res/cardsfolder/c/contemplation.txt +++ b/res/cardsfolder/c/contemplation.txt @@ -2,7 +2,7 @@ Name:Contemplation ManaCost:1 W W Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever you cast a spell, you gain 1 life. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigGainLife | TriggerDescription$ Whenever you cast a spell, you gain 1 life. SVar:TrigGainLife:AB$GainLife | Cost$ 0 | Defined$ You | LifeAmount$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/contemplation.jpg diff --git a/res/cardsfolder/c/cunning_bandit_azamuki_treachery_incarnate.txt b/res/cardsfolder/c/cunning_bandit_azamuki_treachery_incarnate.txt index 735ac5f8787..fb69a8fbb93 100644 --- a/res/cardsfolder/c/cunning_bandit_azamuki_treachery_incarnate.txt +++ b/res/cardsfolder/c/cunning_bandit_azamuki_treachery_incarnate.txt @@ -3,7 +3,7 @@ ManaCost:1 R R Types:Creature Human Warrior Text:no text PT:2/2 -T:Mode$ SpellCast | ValidCard$ Card.Spirit,Card.Arcane | ValidControllingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Spirit,Arcane | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. T:Mode$ Phase | Phase$ End of Turn | IsPresent$ Card.Self+counters_GE2_KI | Execute$ TrigFlip | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of the end step, if there are two or more ki counters on CARDNAME, you may flip it. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ KI | CounterNum$ 1 SVar:TrigFlip:AB$SetState | Cost$ 0 | Defined$ Self | Mode$ Flip diff --git a/res/cardsfolder/c/curse_of_wizardry.txt b/res/cardsfolder/c/curse_of_wizardry.txt index ac657c8e7ca..7bdcae092f0 100644 --- a/res/cardsfolder/c/curse_of_wizardry.txt +++ b/res/cardsfolder/c/curse_of_wizardry.txt @@ -5,7 +5,7 @@ Text:no text T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ ChooseColor | Static$ True| TriggerDescription$ As CARDNAME enters the battlefield, choose a color. SVar:ChooseColor:AB$ ChooseColor | Cost$ 0 | Defined$ You | AILogic$ MostProminentInHumanDeck T:Mode$ SpellCast | ValidCard$ Card.ChosenColor | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever a player casts a spell of the chosen color, that player loses 1 life. -SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | Defined$ TriggeredCardController | LifeAmount$ 1 +SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | Defined$ TriggeredActivator | LifeAmount$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/curse_of_wizardry.jpg SetInfo:ROE|Uncommon|http://magiccards.info/scans/en/roe/104.jpg diff --git a/res/cardsfolder/c/customs_depot.txt b/res/cardsfolder/c/customs_depot.txt index 4a34558aaa3..5a8a5adb7f4 100644 --- a/res/cardsfolder/c/customs_depot.txt +++ b/res/cardsfolder/c/customs_depot.txt @@ -2,7 +2,7 @@ Name:Customs Depot ManaCost:1 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | Execute$ TrigLoot | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, you may pay 1. If you do, draw a card, then discard a card. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigLoot | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell, you may pay 1. If you do, draw a card, then discard a card. SVar:TrigLoot:AB$Draw | Cost$ 1 | NumCards$ 1 | SubAbility$ DBDiscard SVar:DBDiscard:DB$Discard | Defined$ You | Mode$ TgtChoose | NumCards$ 1 SVar:RemAIDeck:True diff --git a/res/cardsfolder/d/deadeye_navigator.txt b/res/cardsfolder/d/deadeye_navigator.txt index 828d969fe7b..1bfe04a4c75 100644 --- a/res/cardsfolder/d/deadeye_navigator.txt +++ b/res/cardsfolder/d/deadeye_navigator.txt @@ -4,10 +4,9 @@ Types:Creature Spirit Text:no text PT:5/5 K:Soulbond -S:Mode$ Continuous | Affected$ Creature.PairedWith,Creature.Self+Paired | AddAbility$ DeadeyeFlicker | AddSVar$ DeadeyeReturn & DBCleanup | Description$ As long as CARDNAME is paired with another creature, both creatures have "1 U: Exile this creature, then return it to the battlefield under your control." -SVar:DeadeyeFlicker:AB$ChangeZone | Cost$ 1 U | Defined$ Self | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | SubAbility$ DeadeyeReturn | SpellDescription$ Exile this creature, then return it to the battlefield under your control. -SVar:DeadeyeReturn:DB$ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield | GainControl$ True | SubAbility$ DBCleanup -SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True +S:Mode$ Continuous | Affected$ Creature.PairedWith,Card.Self+Paired | AddAbility$ DeadeyeFlicker | AddSVar$ DeadeyeReturn | Description$ As long as CARDNAME is paired with another creature, both creatures have "1 U: Exile this creature, then return it to the battlefield under your control." +SVar:DeadeyeFlicker:AB$ChangeZone | Cost$ 1 U | Defined$ Self | Origin$ Battlefield | Destination$ Exile | SubAbility$ DeadeyeReturn | SpellDescription$ Exile this creature, then return it to the battlefield under your control. +SVar:DeadeyeReturn:DB$ChangeZone | Defined$ Self | Origin$ Exile | Destination$ Battlefield | GainControl$ True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/deadeye_navigator.jpg SetInfo:AVR|Rare|http://magiccards.info/scans/en/avr/47.jpg diff --git a/res/cardsfolder/d/deathbringer_liege.txt b/res/cardsfolder/d/deathbringer_liege.txt index ca39d1c16a3..2da2e51be08 100644 --- a/res/cardsfolder/d/deathbringer_liege.txt +++ b/res/cardsfolder/d/deathbringer_liege.txt @@ -5,8 +5,8 @@ Text:no text PT:3/4 S:Mode$ Continuous | Affected$ Creature.White+Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other white creatures you control get +1/+1. S:Mode$ Continuous | Affected$ Creature.Black+Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other black creatures you control get +1/+1. -T:Mode$ SpellCast | ValidCard$ Card.Black+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDestroy | OptionalDecider$ You | TriggerDescription$ Whenever you cast a black spell, you may destroy target creature if it's tapped. -T:Mode$ SpellCast | ValidCard$ Card.White+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigTap | OptionalDecider$ You | TriggerDescription$ Whenever you cast a white spell, you may tap target creature. +T:Mode$ SpellCast | ValidCard$ Card.Black | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDestroy | OptionalDecider$ You | TriggerDescription$ Whenever you cast a black spell, you may destroy target creature if it's tapped. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigTap | OptionalDecider$ You | TriggerDescription$ Whenever you cast a white spell, you may tap target creature. SVar:TrigTap:AB$ Tap | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature to tap SVar:TrigDestroy:AB$ Destroy | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature to destroy | ConditionDefined$ Targeted | ConditionPresent$ Creature.tapped SVar:BuffedBy:Card.White,Card.Black diff --git a/res/cardsfolder/d/deep_sea_kraken.txt b/res/cardsfolder/d/deep_sea_kraken.txt index bb63b50d046..9d569745ead 100644 --- a/res/cardsfolder/d/deep_sea_kraken.txt +++ b/res/cardsfolder/d/deep_sea_kraken.txt @@ -5,7 +5,7 @@ Text:no text PT:6/6 K:Unblockable K:Suspend:9:2 U -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | Execute$ TrigRemoveCounter | IsPresent$ Card.counters_GE1_TIME+Self | PresentZone$ Exile | TriggerDescription$ Whenever an opponent casts a spell, if CARDNAME is suspended, remove a time counter from it. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | Execute$ TrigRemoveCounter | IsPresent$ Card.counters_GE1_TIME+Self | PresentZone$ Exile | TriggerDescription$ Whenever an opponent casts a spell, if CARDNAME is suspended, remove a time counter from it. SVar:TrigRemoveCounter:AB$RemoveCounter | Cost$ 0 | Defined$ Self | CounterType$ TIME | CounterNum$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/deep_sea_kraken.jpg diff --git a/res/cardsfolder/d/demonic_rising.txt b/res/cardsfolder/d/demonic_rising.txt index 9e87b39b2af..056035288c4 100644 --- a/res/cardsfolder/d/demonic_rising.txt +++ b/res/cardsfolder/d/demonic_rising.txt @@ -3,7 +3,7 @@ ManaCost:3 B B Types:Enchantment Text:no text T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ EQ1 | Execute$ TrigToken | TriggerDescription$ At the beginning of your end step, if you control exactly one creature, put a 5/5 black Demon creature token with flying onto the battlefield. -SVar:TrigToken:AB$ Token | Cost$ 0 | TokenImage$ B 5 5 Demon | TokenAmount$ 1 | TokenName$ Demon | TokenTypes$ Creature,Demon | TokenOwner$ You | TokenColors$ Black | TokenPower$ 5 | TokenToughness$ 5 | TokenKeywords$ Flying +SVar:TrigToken:AB$ Token | Cost$ 0 | TokenImage$ B 5 5 Demon avr | TokenAmount$ 1 | TokenName$ Demon | TokenTypes$ Creature,Demon | TokenOwner$ You | TokenColors$ Black | TokenPower$ 5 | TokenToughness$ 5 | TokenKeywords$ Flying SVar:X:Count$Valid Creature.YouCtrl SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/demonic_rising.jpg diff --git a/res/cardsfolder/d/desertion.txt b/res/cardsfolder/d/desertion.txt new file mode 100644 index 00000000000..2dc8ddd8974 --- /dev/null +++ b/res/cardsfolder/d/desertion.txt @@ -0,0 +1,13 @@ +Name:Desertion +ManaCost:3 U U +Types:Instant +Text:no text +A:SP$ Counter | Cost$ 3 U U | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ0 | SubAbility$ DBCounter | SpellDescription$ Counter target spell. If an artifact or creature spell is countered this way, put that card onto the battlefield under your control instead of into its owner's graveyard. +SVar:DBCounter:DB$ Counter | Defined$ Targeted | Destination$ Battlefield | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 +SVar:X:Targeted$Valid Artifact,Creature +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/desertion.jpg +SetInfo:VIS|Rare|http://magiccards.info/scans/en/vi/30.jpg +SetInfo:6ED|Rare|http://magiccards.info/scans/en/6e/64.jpg +Oracle:Counter target spell. If an artifact or creature spell is countered this way, put that card onto the battlefield under your control instead of into its owner's graveyard. +End \ No newline at end of file diff --git a/res/cardsfolder/d/dovescape.txt b/res/cardsfolder/d/dovescape.txt index 60f4401c4b1..4047bf016ce 100644 --- a/res/cardsfolder/d/dovescape.txt +++ b/res/cardsfolder/d/dovescape.txt @@ -4,7 +4,7 @@ Types:Enchantment Text:no text T:Mode$ SpellCast | ValidCard$ Card.nonCreature | TriggerZones$ Battlefield | Execute$ TrigCounter | TriggerDescription$ Whenever a player casts a noncreature spell, counter that spell. That player puts X 1/1 white and blue Bird creature tokens with flying onto the battlefield, where X is the spell's converted mana cost. SVar:TrigCounter:AB$Counter | Cost$ 0 | Defined$ TriggeredSpellAbility | SubAbility$ DBToken -SVar:DBToken:DB$Token | TokenAmount$ X | TokenName$ Bird | TokenTypes$ Creature,Bird | TokenOwner$ TriggeredPlayer | TokenColors$ White,Blue | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying +SVar:DBToken:DB$Token | TokenAmount$ X | TokenName$ Bird | TokenTypes$ Creature,Bird | TokenOwner$ TriggeredActivator | TokenColors$ White,Blue | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying SVar:X:TriggeredCard$CardManaCost SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/dovescape.jpg diff --git a/res/cardsfolder/d/dwarven_patrol.txt b/res/cardsfolder/d/dwarven_patrol.txt index 1cd92c5b3f2..3af4891a16c 100644 --- a/res/cardsfolder/d/dwarven_patrol.txt +++ b/res/cardsfolder/d/dwarven_patrol.txt @@ -4,7 +4,7 @@ Types:Creature Dwarf Text:no text PT:4/2 K:CARDNAME doesn't untap during your untap step. -T:Mode$ SpellCast | ValidCard$ Spell.nonRed+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a nonred spell, untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card.nonRed | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a nonred spell, untap CARDNAME. SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/e/eiganjo_free_riders.txt b/res/cardsfolder/e/eiganjo_free_riders.txt index e4170ecbbf2..96f948147ca 100644 --- a/res/cardsfolder/e/eiganjo_free_riders.txt +++ b/res/cardsfolder/e/eiganjo_free_riders.txt @@ -5,8 +5,8 @@ Text:no text PT:3/4 K:Flying T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | IsPresent$ Creature.White | PresentZone$ Battlefield | PresentPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, return a white creature you control to its owner's hand. -SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target white creature | Mandatory$ True | ValidTgts$ Creature.White+YouCtrl -SVar:RemRandomDeck:True +SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target white creature | Mandatory$ True | Hidden$ True | ValidTgts$ Creature.White+YouCtrl +SVar:RemAIDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/eiganjo_free_riders.jpg SetInfo:SOK|Uncommon|http://magiccards.info/scans/en/sok/8.jpg diff --git a/res/cardsfolder/e/embersmith.txt b/res/cardsfolder/e/embersmith.txt index cbd6c0b46df..1db71ce44c7 100644 --- a/res/cardsfolder/e/embersmith.txt +++ b/res/cardsfolder/e/embersmith.txt @@ -3,7 +3,7 @@ ManaCost:1 R Types:Creature Human Artificer Text:no text PT:2/1 -T:Mode$ SpellCast | ValidCard$ Artifact.YouCtrl | Execute$ TrigDamage | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may pay 1. If you do, CARDNAME deals 1 damage to target creature or player. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigDamage | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may pay 1. If you do, CARDNAME deals 1 damage to target creature or player. SVar:TrigDamage:AB$DealDamage | Cost$ 1 | Tgt$ TgtCP | NumDmg$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/embersmith.jpg diff --git a/res/cardsfolder/e/emberstrike_duo.txt b/res/cardsfolder/e/emberstrike_duo.txt index 1fef6a83b42..4ad6b048c8b 100644 --- a/res/cardsfolder/e/emberstrike_duo.txt +++ b/res/cardsfolder/e/emberstrike_duo.txt @@ -3,8 +3,8 @@ ManaCost:1 BR Types:Creature Elemental Warrior Shaman Textno text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Card.Black+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a black spell, CARDNAME gets +1/+1 until end of turn. -T:Mode$ SpellCast | ValidCard$ Card.Red+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPumpFirstStrike | TriggerDescription$ Whenever you cast a red spell, CARDNAME gains first strike until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.Black | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a black spell, CARDNAME gets +1/+1 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.Red | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPumpFirstStrike | TriggerDescription$ Whenever you cast a red spell, CARDNAME gains first strike until end of turn. SVar:TrigPump11:AB$Pump | Cost$ 0 | NumAtt$ +1 | NumDef$ +1 | Defined$ Self SVar:TrigPumpFirstStrike:AB$Pump | Cost$ 0 | KW$ First Strike | Defined$ Self SVar:BuffedBy:Card.Black,Card.Red diff --git a/res/cardsfolder/e/enchantresss_presence.txt b/res/cardsfolder/e/enchantresss_presence.txt index 17db97a59ac..e00f722a2ca 100644 --- a/res/cardsfolder/e/enchantresss_presence.txt +++ b/res/cardsfolder/e/enchantresss_presence.txt @@ -2,7 +2,7 @@ Name:Enchantress's Presence ManaCost:2 G Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.Enchantment+YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. +T:Mode$ SpellCast | ValidCard$ Enchantment | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/e/endless_wurm.txt b/res/cardsfolder/e/endless_wurm.txt index 1304d6f7a79..91500f33a4d 100644 --- a/res/cardsfolder/e/endless_wurm.txt +++ b/res/cardsfolder/e/endless_wurm.txt @@ -6,7 +6,7 @@ PT:9/9 K:Trample T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, sacrifice CARDNAME unless you sacrifice an enchantment. SVar:TrigSac:AB$ Sacrifice | Cost$ 0 | Amount$ 1 | SacValid$ Enchantment | RememberSacrificed$ True | Optional$ True | SubAbility$ DBSacSelf -SVar:DBSac:DB$ Sacrifice | Cost$ 0 | Defined$ Self | SubAbility$ DBCleanup | ConditionCheckSVar$ X | ConditionSVarCompare$ LT1 +SVar:DBSacSelf:DB$ Sacrifice | Cost$ 0 | Defined$ Self | SubAbility$ DBCleanup | ConditionCheckSVar$ X | ConditionSVarCompare$ LT1 SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Remembered$Amount SVar:NeedsToPlay:Enchantment.YouCtrl diff --git a/res/cardsfolder/e/enigma_eidolon.txt b/res/cardsfolder/e/enigma_eidolon.txt index 53354d25a33..3d67b8d7eeb 100644 --- a/res/cardsfolder/e/enigma_eidolon.txt +++ b/res/cardsfolder/e/enigma_eidolon.txt @@ -4,8 +4,9 @@ Types:Creature Spirit Text:no text PT:2/2 A:AB$ Mill | Cost$ U Sac<1/CARDNAME> | NumCards$ 3 | ValidTgts$ Player | TgtPrompt$ Select target player | SpellDescription$ Target player puts the top three cards of his or her library into his or her graveyard. -T:Mode$ SpellCast | ValidCard$ Card.MultiColor+YouCtrl | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Hand | Defined$ Self +SVar:RemAIDeck:True SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/enigma_eidolon.jpg SetInfo:DIS|Common|http://magiccards.info/scans/en/di/24.jpg diff --git a/res/cardsfolder/e/enslaved_horror.txt b/res/cardsfolder/e/enslaved_horror.txt new file mode 100644 index 00000000000..100466f028e --- /dev/null +++ b/res/cardsfolder/e/enslaved_horror.txt @@ -0,0 +1,13 @@ +Name:Enslaved Horror +ManaCost:3 B +Types:Creature Horror +Text:no text +PT:4/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | TriggerDescription$ When CARDNAME enters the battlefield, each other player may return a creature card from his or her graveyard to the battlefield. +SVar:TrigChange:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.YouDontCtrl | DefinedPlayer$ Opponent | ChangeNum$ 1 | Hidden$ True | Optional$ True +SVar:RemAIDeck:True +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/enslaved_horror.jpg +SetInfo:MMQ|Uncommon|http://magiccards.info/scans/en/mm/134.jpg +Oracle:When Enslaved Horror enters the battlefield, each other player may return a creature card from his or her graveyard to the battlefield. +End \ No newline at end of file diff --git a/res/cardsfolder/e/entreat_the_angels.txt b/res/cardsfolder/e/entreat_the_angels.txt index 92e66d02766..90b11ebda25 100644 --- a/res/cardsfolder/e/entreat_the_angels.txt +++ b/res/cardsfolder/e/entreat_the_angels.txt @@ -2,7 +2,7 @@ Name:Entreat the Angels ManaCost:X X W W W Types:Sorcery Text:no text -A:SP$ Token | Cost$ X X W W W | TokenAmount$ X | TokenName$ Angel | TokenTypes$ Creature,Angel | TokenOwner$ You | TokenColors$ White | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Flying | SpellDescription$ Put X 4/4 white Angel creature tokens with flying onto the battlefield. +A:SP$ Token | Cost$ X X W W W | TokenAmount$ X | TokenName$ Angel | TokenTypes$ Creature,Angel | TokenOwner$ You | TokenColors$ White | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Flying | TokenImage$ w 4 4 angel avr | SpellDescription$ Put X 4/4 white Angel creature tokens with flying onto the battlefield. K:Miracle:X W W SVar:X:Count$xPaid SVar:Rarity:Rare diff --git a/res/cardsfolder/e/entropic_eidolon.txt b/res/cardsfolder/e/entropic_eidolon.txt index f5d43e3a48b..02826a1e03d 100644 --- a/res/cardsfolder/e/entropic_eidolon.txt +++ b/res/cardsfolder/e/entropic_eidolon.txt @@ -5,8 +5,9 @@ Text:no text PT:2/2 A:AB$ LoseLife | Cost$ B Sac<1/CARDNAME> | ValidTgts$ Player | TgtPrompt$ Select target player | LifeAmount$ 1 | SubAbility$ DBGainLife | SpellDescription$ Target player loses 1 life and you gain 1 life. SVar:DBGainLife:DB$GainLife | Defined$ You | LifeAmount$ 1 -T:Mode$ SpellCast | ValidCard$ Card.MultiColor+YouCtrl | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Hand | Defined$ Self +SVar:RemAIDeck:True SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/entropic_eidolon.jpg SetInfo:DIS|Common|http://magiccards.info/scans/en/di/45.jpg diff --git a/res/cardsfolder/e/erayo_soratami_ascendant_erayos_essence.txt b/res/cardsfolder/e/erayo_soratami_ascendant_erayos_essence.txt index 3e48b5e20a7..9109e023cc0 100644 --- a/res/cardsfolder/e/erayo_soratami_ascendant_erayos_essence.txt +++ b/res/cardsfolder/e/erayo_soratami_ascendant_erayos_essence.txt @@ -19,7 +19,7 @@ ManaCost:1 U Colors:blue Types:Legendary Enchantment Text:no text -T:Mode$ SpellCast | ValidControllingPlayer$ Opponent | CheckSVar$ NumOppCast | SVarCompare$ EQ1 | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a spell for the first time in a turn, counter that spell. +T:Mode$ SpellCast | ValidActivatingPlayer$ Opponent | CheckSVar$ NumOppCast | SVarCompare$ EQ1 | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a spell for the first time in a turn, counter that spell. SVar:TrigCounter:AB$Counter | Cost$ 0 | Defined$ TriggeredSpellAbility | Destination$ Graveyard SVar:NumOppCast:Count$ThisTurnCast_Card.YouDontCtrl SVar:Picture1:http://www.marc-fowler-design.com/cardforge/flippedcards/SOK/erayos_essence.jpg diff --git a/res/cardsfolder/e/extra_arms.txt b/res/cardsfolder/e/extra_arms.txt index aac8db3c146..f7e87e6d61d 100644 --- a/res/cardsfolder/e/extra_arms.txt +++ b/res/cardsfolder/e/extra_arms.txt @@ -6,6 +6,8 @@ K:Enchant creature A:SP$ Attach | Cost$ 4 R | ValidTgts$ Creature | AILogic$ Pump T:Mode$ Attacks | ValidCard$ Card.AttachedBy | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted creature attacks, it deals 2 damage to target creature or player. SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Tgt$ TgtCP | DamageSource$ TriggeredCard | NumDmg$ 2 +S:Mode$ Continuous | Affected$ Creature.AttachedBy | AddSVar$ AE +SVar:AE:SVar:HasAttackEffect:TRUE SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/extra_arms.jpg SetInfo:SCG|Uncommon|http://magiccards.info/scans/en/sc/92.jpg diff --git a/res/cardsfolder/e/eyes_of_the_watcher.txt b/res/cardsfolder/e/eyes_of_the_watcher.txt index 7adb7dbb4fa..47c1b333ac1 100644 --- a/res/cardsfolder/e/eyes_of_the_watcher.txt +++ b/res/cardsfolder/e/eyes_of_the_watcher.txt @@ -2,7 +2,7 @@ Name:Eyes of the Watcher ManaCost:2 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Instant.YouCtrl,Sorcery.YouCtrl | Execute$ TrigScry | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an instant or sorcery spell, you may pay 1. If you do, scry 2. (To scry 2, look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.) +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | Execute$ TrigScry | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an instant or sorcery spell, you may pay 1. If you do, scry 2. (To scry 2, look at the top two cards of your library, then put any number of them on the bottom of your library and the rest on top in any order.) SVar:TrigScry:AB$Scry | Cost$ 1 | ScryNum$ 2 SVar:RemAIDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/f/fable_of_wolf_and_owl.txt b/res/cardsfolder/f/fable_of_wolf_and_owl.txt index 1f0a388d836..05b4397fa8c 100644 --- a/res/cardsfolder/f/fable_of_wolf_and_owl.txt +++ b/res/cardsfolder/f/fable_of_wolf_and_owl.txt @@ -2,8 +2,8 @@ Name:Fable of Wolf and Owl ManaCost:3 GU GU GU Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.Green+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigWolf | TriggerDescription$ Whenever you cast a green spell, you may put a 2/2 green Wolf creature token onto the battlefield. -T:Mode$ SpellCast | ValidCard$ Card.Blue+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigBird | TriggerDescription$ Whenever you cast a blue spell, you may put a 1/1 blue Bird creature token with flying onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Card.Green | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigWolf | TriggerDescription$ Whenever you cast a green spell, you may put a 2/2 green Wolf creature token onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Card.Blue | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigBird | TriggerDescription$ Whenever you cast a blue spell, you may put a 1/1 blue Bird creature token with flying onto the battlefield. SVar:TrigWolf:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Wolf | TokenTypes$ Creature,Wolf | TokenOwner$ You | TokenColors$ Green | TokenPower$ 2 | TokenToughness$ 2 SVar:TrigBird:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Bird | TokenTypes$ Creature,Bird | TokenOwner$ You | TokenColors$ Blue | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying SVar:BuffedBy:Card.Green,Card.Blue diff --git a/res/cardsfolder/f/faithful_squire_kaiso_memory_of_loyalty.txt b/res/cardsfolder/f/faithful_squire_kaiso_memory_of_loyalty.txt index 768f1fa7159..0dffc73fc2b 100644 --- a/res/cardsfolder/f/faithful_squire_kaiso_memory_of_loyalty.txt +++ b/res/cardsfolder/f/faithful_squire_kaiso_memory_of_loyalty.txt @@ -3,7 +3,7 @@ ManaCost:1 W W Types:Creature Human Soldier Text:no text PT:2/2 -T:Mode$ SpellCast | ValidCard$ Card.Spirit,Card.Arcane | ValidControllingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Spirit,Arcane | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. T:Mode$ Phase | Phase$ End of Turn | IsPresent$ Card.Self+counters_GE2_KI | Execute$ TrigFlip | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of the end step, if there are two or more ki counters on CARDNAME, you may flip it. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ KI | CounterNum$ 1 SVar:TrigFlip:AB$SetState | Cost$ 0 | Defined$ Self | Mode$ Flip diff --git a/res/cardsfolder/f/fangren_firstborn.txt b/res/cardsfolder/f/fangren_firstborn.txt index c29677fae9f..10ee9609674 100644 --- a/res/cardsfolder/f/fangren_firstborn.txt +++ b/res/cardsfolder/f/fangren_firstborn.txt @@ -5,6 +5,7 @@ Text:no text PT:4/2 T:Mode$ Attacks | ValidCard$ Creature.Self | Execute$ TrigCounters | TriggerDescription$ Whenever CARDNAME attacks, put a +1/+1 counter on each attacking creature. SVar:TrigCounters:AB$PutCounterAll | Cost$ 0 | ValidCards$ Creature.attacking | CounterType$ P1P1 | CounterNum$ 1 +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/fangren_firstborn.jpg SetInfo:DST|Rare|http://magiccards.info/scans/en/ds/75.jpg diff --git a/res/cardsfolder/f/forced_fruition.txt b/res/cardsfolder/f/forced_fruition.txt index 8468b51dbef..f37a5447068 100644 --- a/res/cardsfolder/f/forced_fruition.txt +++ b/res/cardsfolder/f/forced_fruition.txt @@ -2,8 +2,8 @@ Name:Forced Fruition ManaCost:4 U U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a spell, that player draws seven cards. -SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ TriggeredPlayer | NumCards$ 7 +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a spell, that player draws seven cards. +SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ TriggeredActivator | NumCards$ 7 SVar:RemRandomDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/Forced_Fruition.jpg diff --git a/res/cardsfolder/f/frost_titan.txt b/res/cardsfolder/f/frost_titan.txt index 12c39ac2b10..abbb3f16c75 100644 --- a/res/cardsfolder/f/frost_titan.txt +++ b/res/cardsfolder/f/frost_titan.txt @@ -10,6 +10,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigTap | Secondary$ True | Tr SVar:TrigTap:AB$Tap | Cost$ 0 | ValidTgts$ Permanent | TgtPrompt$ Choose target permanent. | SubAbility$ DBPump SVar:DBPump:DB$Pump | Defined$ Targeted | Permanent$ True | KW$ HIDDEN This card doesn't untap during your next untap step. SVar:TrigCounter:AB$Counter | Cost$ 0 | Defined$ TriggeredSourceSA | UnlessCost$ 2 | UnlessPayer$ TriggeredSourceSAController +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/frost_titan.jpg SetInfo:M11|Mythic|http://magiccards.info/scans/en/m11/55.jpg diff --git a/res/cardsfolder/f/fugitive_druid.txt b/res/cardsfolder/f/fugitive_druid.txt index e17c199179c..1454f8e5cc1 100644 --- a/res/cardsfolder/f/fugitive_druid.txt +++ b/res/cardsfolder/f/fugitive_druid.txt @@ -3,7 +3,7 @@ ManaCost:3 G Types:Creature Human Druid Text:no text PT:3/2 -T:Mode$ SpellCast | TargetsValid$ Card.Self | ValidCard$ Enchantment.Aura | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME becomes the target of an Aura spell, you draw a card. +T:Mode$ SpellCast | TargetsValid$ Card.Self | ValidCard$ Aura | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME becomes the target of an Aura spell, you draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/fugitive_druid.jpg diff --git a/res/cardsfolder/f/furious_assault.txt b/res/cardsfolder/f/furious_assault.txt index cc7f3662cdd..0b7cb41a917 100644 --- a/res/cardsfolder/f/furious_assault.txt +++ b/res/cardsfolder/f/furious_assault.txt @@ -2,7 +2,7 @@ Name:Furious Assault ManaCost:2 R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a creature spell, CARDNAME deals 1 damage to target player. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a creature spell, CARDNAME deals 1 damage to target player. SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Tgt$ TgtP | NumDmg$ 1 SVar:BuffedBy:Creature SVar:Rarity:Common diff --git a/res/cardsfolder/g/gallows_at_willow_hill.txt b/res/cardsfolder/g/gallows_at_willow_hill.txt index 9380df609d1..245e3ff570f 100644 --- a/res/cardsfolder/g/gallows_at_willow_hill.txt +++ b/res/cardsfolder/g/gallows_at_willow_hill.txt @@ -3,7 +3,7 @@ ManaCost:3 Types:Artifact Text:no text A:AB$ Destroy | Cost$ 3 T tapXType<3/Human> | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ GhostToken | SpellDescription$ Destroy target creature. Its controller puts a 1/1 white Spirit creature token with flying onto the battlefield. -SVar:GhostToken:DB$Token | TokenAmount$ 1 | TokenName$ Spirit | TokenTypes$ Creature,Spirit | TokenOwner$ TargetedController | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying +SVar:GhostToken:DB$Token | TokenAmount$ 1 | TokenName$ Spirit | TokenTypes$ Creature,Spirit | TokenOwner$ TargetedController | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying | TokenImage$ w 1 1 spirit avr SVar:RemRandomDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/gallows_at_willow_hill.jpg diff --git a/res/cardsfolder/g/geist_of_saint_traft.txt b/res/cardsfolder/g/geist_of_saint_traft.txt index d4131fefb38..999218b073c 100644 --- a/res/cardsfolder/g/geist_of_saint_traft.txt +++ b/res/cardsfolder/g/geist_of_saint_traft.txt @@ -8,6 +8,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription SVar:TrigToken:AB$Token | Cost$ 0 | TokenImage$ W 4 4 Angel | TokenAmount$ 1 | TokenName$ Angel | TokenTypes$ Creature,Angel | TokenOwner$ You | TokenColors$ White | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Flying | TokenTapped$ True | TokenAttacking$ True | TokenTriggers$ DelTrig | TokenSVars$ TrigExile SVar:DelTrig:Mode$ Phase | Phase$ EndCombat | Execute$ TrigExile | TriggerDescription$ At end of combat, exile the Angel token. SVar:TrigExile:AB$ ChangeZone | Cost$ 0 | Defined$ Self | Origin$ Battlefield | Destination$ Exile +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/geist_of_saint_traft.jpg SetInfo:ISD|Mythic|http://magiccards.info/scans/en/isd/213.jpg diff --git a/res/cardsfolder/g/geist_snatch.txt b/res/cardsfolder/g/geist_snatch.txt index 06891433164..f8541a64123 100644 --- a/res/cardsfolder/g/geist_snatch.txt +++ b/res/cardsfolder/g/geist_snatch.txt @@ -3,7 +3,7 @@ ManaCost:2 U U Types:Instant Text:no text A:SP$ Counter | Cost$ 2 U U | TargetType$ Spell | TgtPrompt$ Select target Creature spell | ValidTgts$ Creature | SubAbility$ DBToken | SpellDescription$ Counter target creature spell. Put a 1/1 blue Spirit creature token with flying onto the battlefield. -SVar:DBToken:DB$ Token | Cost$ 0 | TokenImage$ U 1 1 Spirit | TokenAmount$ 1 | TokenName$ Spirit | TokenTypes$ Creature,Spirit | TokenOwner$ You | TokenColors$ Blue | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying +SVar:DBToken:DB$ Token | Cost$ 0 | TokenImage$ U 1 1 Spirit avr | TokenAmount$ 1 | TokenName$ Spirit | TokenTypes$ Creature,Spirit | TokenOwner$ You | TokenColors$ Blue | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Flying SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/geist_snatch.jpg SetInfo:AVR|Common|http://magiccards.info/scans/en/avr/55.jpg diff --git a/res/cardsfolder/g/gelectrode.txt b/res/cardsfolder/g/gelectrode.txt index dea154caba5..a3b3cc08cbe 100644 --- a/res/cardsfolder/g/gelectrode.txt +++ b/res/cardsfolder/g/gelectrode.txt @@ -4,7 +4,7 @@ Types:Creature Weird Text:no text PT:0/1 A:AB$ DealDamage | Cost$ T | Tgt$ TgtCP | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to target creature or player. -T:Mode$ SpellCast | ValidCard$ Card.Instant+YouCtrl,Card.Sorcery+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigUntap | OptionalDecider$ You | TriggerDescription$ Whenever you cast an instant or sorcery spell, you may untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigUntap | OptionalDecider$ You | TriggerDescription$ Whenever you cast an instant or sorcery spell, you may untap CARDNAME. SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/gelectrode.jpg diff --git a/res/cardsfolder/g/gemini_engine.txt b/res/cardsfolder/g/gemini_engine.txt index 428b3ebcd26..c59b5221269 100644 --- a/res/cardsfolder/g/gemini_engine.txt +++ b/res/cardsfolder/g/gemini_engine.txt @@ -9,6 +9,7 @@ SVar:TrigSac:Mode$ Phase | Phase$ EndCombat | Execute$ TrigSacrifice | TriggerDe SVar:TrigSacrifice:AB$ Sacrifice | Cost$ 0 | SacValid$ Self | Mandatory$ True SVar:X:Count$CardPower SVar:Y:Count$CardToughness +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/gemini_engine.jpg SetInfo:DST|Rare|http://magiccards.info/scans/en/ds/121.jpg diff --git a/res/cardsfolder/g/ghave_guru_of_spores.txt b/res/cardsfolder/g/ghave_guru_of_spores.txt index ddc18eaf593..3f0d8846c46 100644 --- a/res/cardsfolder/g/ghave_guru_of_spores.txt +++ b/res/cardsfolder/g/ghave_guru_of_spores.txt @@ -4,8 +4,8 @@ Types:Legendary Creature Fungus Shaman Text:no text PT:0/0 K:etbCounter:P1P1:5 -A:AB$ Token | Cost$ SubCounter<1/P1P1/Creature.YouCtrl/Creature you Control> | TokenAmount$ 1 | TokenName$ Saproling | TokenTypes$ Creature,Saproling | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Put a 1/1 green Saproling creature token onto the battlefield. -A:AB$ PutCounter | Cost$ Sac<1/Creature> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. +A:AB$ Token | Cost$ 1 SubCounter<1/P1P1/Creature.YouCtrl/Creature you Control> | TokenAmount$ 1 | TokenName$ Saproling | TokenTypes$ Creature,Saproling | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 | SpellDescription$ Put a 1/1 green Saproling creature token onto the battlefield. +A:AB$ PutCounter | Cost$ 1 Sac<1/Creature> | ValidTgts$ Creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. SVar:RemAIDeck:True SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/ghave_guru_of_spores.jpg diff --git a/res/cardsfolder/g/gift_of_the_gargantuan.txt b/res/cardsfolder/g/gift_of_the_gargantuan.txt new file mode 100644 index 00000000000..cdee6d06546 --- /dev/null +++ b/res/cardsfolder/g/gift_of_the_gargantuan.txt @@ -0,0 +1,10 @@ +Name:Gift of the Gargantuan +ManaCost:2 G +Types:Sorcery +Text:no text +A:SP$ Dig | Cost$ 2 G | DigNum$ 4 | ChangeValid$ Creature | AndOrValid$ Land | ChangeNum$ 2 | SpellDescription$ Look at the top four cards of your library. You may reveal a creature card and/or a land card from among them and put the revealed cards into your hand. Put the rest on the bottom of your library in any order. +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/gift_of_the_gargantuan.jpg +SetInfo:ALA|Common|http://magiccards.info/scans/en/ala/132.jpg +Oracle:Look at the top four cards of your library. You may reveal a creature card and/or a land card from among them and put the revealed cards into your hand. Put the rest on the bottom of your library in any order. +End \ No newline at end of file diff --git a/res/cardsfolder/g/gilt_leaf_archdruid.txt b/res/cardsfolder/g/gilt_leaf_archdruid.txt index fa5a695681b..3877f19dcae 100644 --- a/res/cardsfolder/g/gilt_leaf_archdruid.txt +++ b/res/cardsfolder/g/gilt_leaf_archdruid.txt @@ -3,7 +3,7 @@ ManaCost:3 G G Types:Creature Elf Druid Text:no text PT:3/3 -T:Mode$ SpellCast | ValidCard$ Card.Druid+YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a Druid spell, you may draw a card. +T:Mode$ SpellCast | ValidCard$ Druid | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a Druid spell, you may draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 A:AB$ ChangeZoneAll | Cost$ tapXType<7/Druid> | Origin$ Battlefield | Destination$ Battlefield | ValidTgts$ Player | TgtPrompt$ Select target player | ChangeType$ Land | GainControl$ True | CostDesc$ Tap seven untapped Druids you control: | SpellDescription$ Gain control of all lands target player controls. SVar:Rarity:Rare diff --git a/res/cardsfolder/g/glimpse_of_nature.txt b/res/cardsfolder/g/glimpse_of_nature.txt index 0ebe06c3d7a..0ea20b34dc0 100644 --- a/res/cardsfolder/g/glimpse_of_nature.txt +++ b/res/cardsfolder/g/glimpse_of_nature.txt @@ -3,7 +3,7 @@ ManaCost:G Types:Sorcery Text:no text A:SP$ Effect | Cost$ G | Name$ Glimpse of Nature Effect | Triggers$ CreatureSpell | SVars$ TrigDraw | SpellDescription$ Whenever you cast a creature spell this turn, draw a card. -SVar:CreatureSpell:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell this turn, draw a card. +SVar:CreatureSpell:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a creature spell this turn, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True SVar:PlayMain1:TRUE diff --git a/res/cardsfolder/g/gloryscale_viashino.txt b/res/cardsfolder/g/gloryscale_viashino.txt index 45a8390ee61..bd590775bb4 100644 --- a/res/cardsfolder/g/gloryscale_viashino.txt +++ b/res/cardsfolder/g/gloryscale_viashino.txt @@ -3,7 +3,7 @@ ManaCost:1 R G W Types:Creature Viashino Soldier Text:no text PT:3/3 -T:Mode$ SpellCast | ValidCard$ Card.MultiColor+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a multicolored spell, CARDNAME gets +3/+3 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a multicolored spell, CARDNAME gets +3/+3 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | NumAtt$ +3 | NumDef$ +3 | Defined$ Self SVar:BuffedBy:Card.MultiColor SVar:Picture:http://www.wizards.com/global/images/magic/general/gloryscale_viashino.jpg diff --git a/res/cardsfolder/g/golem_foundry.txt b/res/cardsfolder/g/golem_foundry.txt index 8668af3cf7f..b2a1ef985ae 100644 --- a/res/cardsfolder/g/golem_foundry.txt +++ b/res/cardsfolder/g/golem_foundry.txt @@ -2,7 +2,7 @@ Name:Golem Foundry ManaCost:3 Types:Artifact Text:no text -T:Mode$ SpellCast | ValidCard$ Artifact.YouCtrl | Execute$ TrigPutCounter | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an artifact spell, you may put a charge counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an artifact spell, you may put a charge counter on CARDNAME. A:AB$ Token | Cost$ SubCounter<3/CHARGE> | TokenAmount$ 1 | TokenName$ Golem | TokenTypes$ Artifact,Creature,Golem | TokenOwner$ You | TokenColors$ Colorless | TokenPower$ 3 | TokenToughness$ 3 | SpellDescription$ Put a 3/3 colorless Golem artifact creature token onto the battlefield. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterNum$ 1 | CounterType$ CHARGE SVar:Rarity:Common diff --git a/res/cardsfolder/g/grave_titan.txt b/res/cardsfolder/g/grave_titan.txt index ea270fed9eb..7ab981c94d2 100644 --- a/res/cardsfolder/g/grave_titan.txt +++ b/res/cardsfolder/g/grave_titan.txt @@ -7,6 +7,7 @@ K:Deathtouch T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME enters the battlefield, put two 2/2 black Zombie creature tokens onto the battlefield. T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, put two 2/2 black Zombie creature tokens onto the battlefield. SVar:TrigToken:AB$Token | Cost$ 0 | TokenImage$ B 2 2 Zombie | TokenName$ Zombie | TokenColors$ Black | TokenTypes$ Creature,Zombie | TokenPower$ 2 | TokenToughness$ 2 | TokenOwner$ You | TokenAmount$ 2 +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/grave_titan.jpg SetInfo:M11|Mythic|http://magiccards.info/scans/en/m11/97.jpg diff --git a/res/cardsfolder/g/gravelgill_duo.txt b/res/cardsfolder/g/gravelgill_duo.txt index bc7a4595466..12f1409dc11 100644 --- a/res/cardsfolder/g/gravelgill_duo.txt +++ b/res/cardsfolder/g/gravelgill_duo.txt @@ -3,8 +3,8 @@ ManaCost:2 UB Types:Creature Merfolk Rogue Warrior Text:no text PT:2/1 -T:Mode$ SpellCast | ValidCard$ Card.Blue+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a blue spell, CARDNAME gets +1/+1 until end of turn. -T:Mode$ SpellCast | ValidCard$ Card.Black+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPumpFear | TriggerDescription$ Whenever you cast a black spell, CARDNAME gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.) +T:Mode$ SpellCast | ValidCard$ Card.Blue | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a blue spell, CARDNAME gets +1/+1 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.Black | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPumpFear | TriggerDescription$ Whenever you cast a black spell, CARDNAME gains fear until end of turn. (It can't be blocked except by artifact creatures and/or black creatures.) SVar:TrigPump11:AB$Pump | Cost$ 0 | NumAtt$ +1 | NumDef$ +1 | Defined$ Self SVar:TrigPumpFear:AB$Pump | Cost$ 0 | KW$ Fear | Defined$ Self SVar:BuffedBy:Card.Blue,Card.Black diff --git a/res/cardsfolder/g/grimgrin_corpse_born.txt b/res/cardsfolder/g/grimgrin_corpse_born.txt index 1673ca64dec..adbadf07e3f 100644 --- a/res/cardsfolder/g/grimgrin_corpse_born.txt +++ b/res/cardsfolder/g/grimgrin_corpse_born.txt @@ -11,6 +11,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDestroy | TriggerDescripti SVar:TrigDestroy:AB$Destroy | Cost$ 0 | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature | SubAbility$ DBPutCounter SVar:DBPutCounter:DB$PutCounter | Cost$ 0 | CounterType$ P1P1 | CounterNum$1 SVar:RemAIDeck:True +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/grimgrin_corpse_born.jpg SetInfo:ISD|Mythic|http://magiccards.info/scans/en/isd/214.jpg diff --git a/res/cardsfolder/h/hand_of_the_praetors.txt b/res/cardsfolder/h/hand_of_the_praetors.txt index adceeab6756..0b64ef65094 100644 --- a/res/cardsfolder/h/hand_of_the_praetors.txt +++ b/res/cardsfolder/h/hand_of_the_praetors.txt @@ -5,7 +5,7 @@ Text:no text PT:3/2 K:Infect S:Mode$ Continuous | Affected$ Creature.withInfect+Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other creatures you control with infect get +1/+1. -T:Mode$ SpellCast | ValidCard$ Creature.withInfect+YouCtrl | Execute$ TrigPoison | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell with infect, target player gets a poison counter. +T:Mode$ SpellCast | ValidCard$ Card.withInfect | ValidActivatingPlayer$ You | Execute$ TrigPoison | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell with infect, target player gets a poison counter. SVar:TrigPoison:AB$Poison | Cost$ 0 | ValidTgts$ Player | TgtPrompt$ Select target player | Num$ 1 SVar:PlayMain1:TRUE SVar:Rarity:Rare diff --git a/res/cardsfolder/h/havoc.txt b/res/cardsfolder/h/havoc.txt index 1faf9eb2fdd..c51b9edbf65 100644 --- a/res/cardsfolder/h/havoc.txt +++ b/res/cardsfolder/h/havoc.txt @@ -2,7 +2,7 @@ Name:Havoc ManaCost:1 R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.White+YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever an opponent casts a white spell, he or she loses 2 life. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever an opponent casts a white spell, he or she loses 2 life. SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | Defined$ Opponent | LifeAmount$ 2 SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/h/heartwood_storyteller.txt b/res/cardsfolder/h/heartwood_storyteller.txt index bdf02b9d91a..f4d5b9440ff 100644 --- a/res/cardsfolder/h/heartwood_storyteller.txt +++ b/res/cardsfolder/h/heartwood_storyteller.txt @@ -3,8 +3,8 @@ ManaCost:1 G G Types:Creature Treefolk Text:no text PT:2/3 -T:Mode$ SpellCast | TriggerZones$ Battlefield | ValidCard$ Spell.nonCreature+YouDontCtrl | Execute$ TrigDrawYou | OptionalDecider$ You |TriggerDescription$ Whenever a player casts a noncreature spell, each of that player's opponents may draw a card. -T:Mode$ SpellCast | TriggerZones$ Battlefield | ValidCard$ Spell.nonCreature+YouCtrl | Execute$ TrigDrawOpp | OptionalDecider$ Opponent |TriggerDescription$ Whenever a player casts a noncreature spell, each of that player's opponents may draw a card. | Secondary$ True +T:Mode$ SpellCast | TriggerZones$ Battlefield | ValidCard$ Spell.nonCreature | ValidActivatingPlayer$ Opponent | Execute$ TrigDrawYou | OptionalDecider$ You |TriggerDescription$ Whenever a player casts a noncreature spell, each of that player's opponents may draw a card. +T:Mode$ SpellCast | TriggerZones$ Battlefield | ValidCard$ Spell.nonCreature | ValidActivatingPlayer$ You | Execute$ TrigDrawOpp | OptionalDecider$ Opponent |TriggerDescription$ Whenever a player casts a noncreature spell, each of that player's opponents may draw a card. | Secondary$ True SVar:TrigDrawYou:AB$ Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:TrigDrawOpp:AB$ Draw | Cost$ 0 | Defined$ Opponent | NumCards$ 1 SVar:Rarity:Rare diff --git a/res/cardsfolder/h/herald_of_war.txt b/res/cardsfolder/h/herald_of_war.txt index ac8a5c2b55a..fe5e085090a 100644 --- a/res/cardsfolder/h/herald_of_war.txt +++ b/res/cardsfolder/h/herald_of_war.txt @@ -8,6 +8,7 @@ T:Mode$ Attacks | ValidCard$ Creature.Self | Execute$ HeraldsWarCry | TriggerDes SVar:HeraldsWarCry:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 K:CostChange:Player:Less:X:Spell:All:Angel/Human:OnlyOneBonus:Angels and Humans you cast cost 1 less for each +1/+1 counter on CARDNAME. SVar:X:Count$NumCounters.P1P1 +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/herald_of_war.jpg SetInfo:AVR|Rare|http://magiccards.info/scans/en/avr/24.jpg diff --git a/res/cardsfolder/h/hero_of_bladehold.txt b/res/cardsfolder/h/hero_of_bladehold.txt index e92ac0d864e..f2df23dd05f 100644 --- a/res/cardsfolder/h/hero_of_bladehold.txt +++ b/res/cardsfolder/h/hero_of_bladehold.txt @@ -7,6 +7,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ Tr T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME attacks, put two 1/1 white Soldier creature tokens onto the battlefield tapped and attacking. SVar:TrigBattleCry:AB$PumpAll | Cost$ 0 | ValidCards$ Creature.attacking+Other | NumAtt$ 1 SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 2 | TokenName$ Soldier | TokenTypes$ Creature,Soldier | TokenOwner$ You | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenTapped$ True | TokenAttacking$ True +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/hero_of_bladehold.jpg SetInfo:MBS|Mythic|http://magiccards.info/scans/en/mbs/8.jpg diff --git a/res/cardsfolder/h/hired_muscle_scarmaker.txt b/res/cardsfolder/h/hired_muscle_scarmaker.txt index d4f5c5b38dd..c3524e0ff5e 100644 --- a/res/cardsfolder/h/hired_muscle_scarmaker.txt +++ b/res/cardsfolder/h/hired_muscle_scarmaker.txt @@ -3,7 +3,7 @@ ManaCost:1 B B Types:Creature Human Warrior Text:no text PT:2/2 -T:Mode$ SpellCast | ValidCard$ Card.Spirit,Card.Arcane | ValidControllingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card.Spirit,Card.Arcane | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, you may put a ki counter on CARDNAME. T:Mode$ Phase | Phase$ End of Turn | IsPresent$ Card.Self+counters_GE2_KI | Execute$ TrigFlip | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of the end step, if there are two or more ki counters on CARDNAME, you may flip it. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ KI | CounterNum$ 1 SVar:TrigFlip:AB$SetState | Cost$ 0 | Defined$ Self | Mode$ Flip diff --git a/res/cardsfolder/h/howltooth_hollow.txt b/res/cardsfolder/h/howltooth_hollow.txt new file mode 100644 index 00000000000..8ea0d1710ce --- /dev/null +++ b/res/cardsfolder/h/howltooth_hollow.txt @@ -0,0 +1,16 @@ +Name:Howltooth Hollow +ManaCost:no cost +Types:Land +Text:no text +K:Hideaway +T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library. +SVar:TrigDig:AB$ Dig | Cost$ 0 | Defined$ You | DigNum$ 4 | DestinationZone$ Exile | ExileFaceDown$ True | RememberChanged$ True +A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add B to your mana pool. +A:AB$ Play | Cost$ B T | Defined$ Remembered | Controller$ You | WithoutManaCost$ True | Optional$ True | ConditionCheckSVar$ Hands | ConditionSVarCompare$ EQ0 | ForgetRemembered$ True | SpellDescription$ You may play the exiled card without paying its mana cost if each player has no cards in hand. +SVar:Hands:Count$NumInAllHands +SVar:RemRandomDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/howltooth_hollow.jpg +SetInfo:LRW|Rare|http://magiccards.info/scans/en/lw/269.jpg +Oracle:Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.)\n{T}: Add {B} to your mana pool.\n{B}, {T}: You may play the exiled card without paying its mana cost if each player has no cards in hand. +End \ No newline at end of file diff --git a/res/cardsfolder/h/hunting_grounds.txt b/res/cardsfolder/h/hunting_grounds.txt index 46eb6fd0542..0c1b6c8b7ed 100644 --- a/res/cardsfolder/h/hunting_grounds.txt +++ b/res/cardsfolder/h/hunting_grounds.txt @@ -2,7 +2,7 @@ Name:Hunting Grounds ManaCost:G W Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Spell.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigChangeZone | OptionalDecider$ You | Threshold$ True | TriggerDescription$ Threshold - Whenever an opponent casts a spell, you may put a creature card from your hand onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigChangeZone | OptionalDecider$ You | Threshold$ True | TriggerDescription$ Threshold - Whenever an opponent casts a spell, you may put a creature card from your hand onto the battlefield. SVar:TrigChangeZone:AB$ ChangeZone | Cost$ 0 | ChangeType$ Creature | ChangeNum$ 1 | Origin$ Hand | Destination$ Battlefield SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/hunting_grounds.jpg diff --git a/res/cardsfolder/i/iceberg.txt b/res/cardsfolder/i/iceberg.txt index a2972153e53..06c6d7052bd 100644 --- a/res/cardsfolder/i/iceberg.txt +++ b/res/cardsfolder/i/iceberg.txt @@ -2,7 +2,7 @@ Name:Iceberg ManaCost:X U U Types:Enchantment Text:no text -K:etbCounter:P1P1:X +K:etbCounter:ICE:X SVar:X:Count$xPaid A:AB$ PutCounter | Cost$ 3 | CounterType$ ICE | CounterNum$ 1 | SpellDescription$ Put an ice counter on CARDNAME. A:AB$ Mana | Cost$ SubCounter<1/ICE> | Produced$ 1 | SpellDescription$ Add 1 to your mana pool. diff --git a/res/cardsfolder/i/ichneumon_druid.txt b/res/cardsfolder/i/ichneumon_druid.txt index 08c946e7575..adf151d701c 100644 --- a/res/cardsfolder/i/ichneumon_druid.txt +++ b/res/cardsfolder/i/ichneumon_druid.txt @@ -3,7 +3,7 @@ ManaCost:1 G G Types:Creature Human Druid Text:no text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Instant | ValidControllingPlayer$ Opponent | CheckSVar$ X | SVarCompare$ GT1 | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent casts an instant spell other than the first instant spell that player casts each turn, CARDNAME deals 4 damage to him or her. +T:Mode$ SpellCast | ValidCard$ Instant | ValidActivatingPlayer$ Opponent | CheckSVar$ X | SVarCompare$ GT1 | TriggerZones$ Battlefield | Execute$ TrigDmg | TriggerDescription$ Whenever an opponent casts an instant spell other than the first instant spell that player casts each turn, CARDNAME deals 4 damage to him or her. SVar:TrigDmg:AB$DealDamage | Cost$ 0 | Defined$ TriggeredPlayer | NumDmg$ 4 SVar:X:Count$ThisTurnCast_Instant SVar:RemRandomDeck:True diff --git a/res/cardsfolder/i/illusory_demon.txt b/res/cardsfolder/i/illusory_demon.txt index 0d66256f9c2..85361b6bfc6 100644 --- a/res/cardsfolder/i/illusory_demon.txt +++ b/res/cardsfolder/i/illusory_demon.txt @@ -4,7 +4,7 @@ Types:Creature Demon Illusion Text:no text PT:4/3 K:Flying -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When you cast a spell, sacrifice CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When you cast a spell, sacrifice CARDNAME. SVar:TrigSac:AB$Sacrifice | Cost$ 0 | SacValid$ Self SVar:RemAIDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/i/in_the_eye_of_chaos.txt b/res/cardsfolder/i/in_the_eye_of_chaos.txt index 83e6fab4087..e18535cce70 100644 --- a/res/cardsfolder/i/in_the_eye_of_chaos.txt +++ b/res/cardsfolder/i/in_the_eye_of_chaos.txt @@ -3,7 +3,7 @@ ManaCost:2 U Types:World Enchantment Text:no text T:Mode$ SpellCast | ValidCard$ Instant | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts an instant spell, counter it unless that player pays X, where X is its converted mana cost. -SVar:TrigCounter:AB$Counter | Cost$ 0 | Defined$ TriggerSpellAbility | UnlessCost$ X | UnlessPayer$ TriggeredCardController +SVar:TrigCounter:AB$Counter | Cost$ 0 | Defined$ TriggerSpellAbility | UnlessCost$ X | UnlessPayer$ TriggeredActivator SVar:X:TriggeredCard$CardManaCost SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/i/inexorable_tide.txt b/res/cardsfolder/i/inexorable_tide.txt index 19783d54e68..23afa2d7f62 100644 --- a/res/cardsfolder/i/inexorable_tide.txt +++ b/res/cardsfolder/i/inexorable_tide.txt @@ -2,7 +2,7 @@ Name:Inexorable Tide ManaCost:3 U U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | Execute$ TrigProliferate | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, proliferate. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigProliferate | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, proliferate. SVar:TrigProliferate:AB$Proliferate | Cost$ 0 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/inexorable_tide.jpg diff --git a/res/cardsfolder/i/infectious_horror.txt b/res/cardsfolder/i/infectious_horror.txt index e59532b41d4..4317ce85956 100644 --- a/res/cardsfolder/i/infectious_horror.txt +++ b/res/cardsfolder/i/infectious_horror.txt @@ -5,6 +5,7 @@ Text:no text PT:2/2 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigLoseLife | TriggerDescription$ Whenever CARDNAME attacks, each opponent loses 2 life. SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | Defined$ Opponent | LifeAmount$ 2 +SVar:HasAttackEffect:TRUE SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/infectious_horror.jpg SetInfo:CFX|Common|http://magiccards.info/scans/en/cfx/47.jpg diff --git a/res/cardsfolder/i/infernal_genesis.txt b/res/cardsfolder/i/infernal_genesis.txt index ac1b0d7cd0a..604e0b2ee77 100644 --- a/res/cardsfolder/i/infernal_genesis.txt +++ b/res/cardsfolder/i/infernal_genesis.txt @@ -7,6 +7,7 @@ SVar:TrigMill:AB$ Mill | Cost$ 0 | Defined$ TriggeredPlayer | NumCards$ 1 | Reme SVar:TrigToken:DB$ Token | TokenAmount$ X | TokenName$ Minion | TokenTypes$ Creature,Minion | TokenOwner$ TriggeredPlayer | TokenColors$ Black | TokenPower$ 1 | TokenToughness$ 1 | SubAbility$ DBCleanup SVar:DBCleanup:DB$Cleanup | ClearRemembered$ True SVar:X:Remembered$CardManaCost +SVar:RemRandomDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/infernal_genesis.jpg SetInfo:PCY|Rare|http://magiccards.info/scans/en/pr/68.jpg diff --git a/res/cardsfolder/i/infernal_kirin.txt b/res/cardsfolder/i/infernal_kirin.txt index 2435e2a94cd..43d6b9b9ce6 100644 --- a/res/cardsfolder/i/infernal_kirin.txt +++ b/res/cardsfolder/i/infernal_kirin.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Kirin Spirit Text:no text PT:3/3 K:Flying -T:Mode$ SpellCast | ValidCard$ Spirit,Arcane | ValidControllingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, target player reveals his or her hand and discards all cards with that spell's converted mana cost. +T:Mode$ SpellCast | ValidCard$ Spirit,Arcane | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ Whenever you cast a Spirit or Arcane spell, target player reveals his or her hand and discards all cards with that spell's converted mana cost. SVar:TrigDiscard:AB$Discard | Cost$ 0 | ValidTgts$ Player | Mode$ RevealDiscardAll | DiscardValid$ Card.cmcEQX SVar:X:TriggeredCard$CardManaCost SVar:Rarity:Rare diff --git a/res/cardsfolder/i/inferno_titan.txt b/res/cardsfolder/i/inferno_titan.txt index 609142a07bf..b4b684d76c0 100644 --- a/res/cardsfolder/i/inferno_titan.txt +++ b/res/cardsfolder/i/inferno_titan.txt @@ -9,6 +9,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ Dmg1 | Secondary$ True | Trigg SVar:Dmg1:AB$DealDamage | Cost$ 0 | Tgt$ TgtCP | TgtPrompt$ Select target creature or player (1) | NumDmg$ 1 | SubAbility$ Dmg2 SVar:Dmg2:DB$DealDamage | Tgt$ TgtCP | TgtPrompt$ Select target creature or player (2) | NumDmg$ 1 | SubAbility$ Dmg3 SVar:Dmg3:DB$DealDamage | Tgt$ TgtCP | TgtPrompt$ Select target creature or player (3) | NumDmg$ 1 +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/inferno_titan.jpg SetInfo:M11|Mythic|http://magiccards.info/scans/en/m11/146.jpg diff --git a/res/cardsfolder/i/infested_roothold.txt b/res/cardsfolder/i/infested_roothold.txt index 61473c95d60..65d418823aa 100644 --- a/res/cardsfolder/i/infested_roothold.txt +++ b/res/cardsfolder/i/infested_roothold.txt @@ -5,7 +5,7 @@ Text:no text PT:0/3 K:Defender K:Protection from artifacts -T:Mode$ SpellCast | ValidCard$ Artifact.YouDontCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigToken | TriggerDescription$ Whenever an opponent casts an artifact spell, you may put a 1/1 green Insect creature token onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigToken | TriggerDescription$ Whenever an opponent casts an artifact spell, you may put a 1/1 green Insect creature token onto the battlefield. SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Insect | TokenTypes$ Creature,Insect | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/infested_roothold.jpg diff --git a/res/cardsfolder/i/inquisitors_flail.txt b/res/cardsfolder/i/inquisitors_flail.txt index 2ccf804beef..f991533c9c1 100644 --- a/res/cardsfolder/i/inquisitors_flail.txt +++ b/res/cardsfolder/i/inquisitors_flail.txt @@ -5,7 +5,7 @@ Text:no text A:AB$ Attach | Cost$ 2 | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SorcerySpeed$ True | PrecostDesc$ Equip - | SpellDescription$ Attach CARDNAME to target creature you control. R:Event$ DamageDone | ValidSource$ Creature.EquippedBy | ReplaceWith$ DmgTimes2 | IsCombat$ True | Description$ If equipped creature would deal combat damage, it deals double that damage instead. R:Event$ DamageDone | ValidTarget$ Creature.EquippedBy | ValidSource$ Creature.Other | ReplaceWith$ DmgTimes2 | IsCombat$ True | Description$ If another creature would deal combat damage to equipped creature, it deals double that damage to equipped creature instead. -SVar:DmgTimes2:AB$ DealDamage | Cost$ 0 | Defined$ ReplacedTarget | DamageSource$ ReplacedSource | NumDmg$ X +SVar:DmgTimes2:AB$ DealDamage | Cost$ 0 | CombatDamage$ True | Defined$ ReplacedTarget | DamageSource$ ReplacedSource | NumDmg$ X SVar:X:ReplaceCount$DamageAmount/Times.2 SVar:Picture:http://www.wizards.com/global/images/magic/general/inquisitors_flail.jpg SetInfo:ISD|Uncommon|http://magiccards.info/scans/en/isd/227.jpg diff --git a/res/cardsfolder/i/insight.txt b/res/cardsfolder/i/insight.txt index 507edcc43a2..ad968efb338 100644 --- a/res/cardsfolder/i/insight.txt +++ b/res/cardsfolder/i/insight.txt @@ -2,7 +2,7 @@ Name:Insight ManaCost:2 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.Green+YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a green spell, you draw a card. +T:Mode$ SpellCast | ValidCard$ Card.Green | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a green spell, you draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/i/insist.txt b/res/cardsfolder/i/insist.txt index d8a7e34c467..6cb152689bf 100644 --- a/res/cardsfolder/i/insist.txt +++ b/res/cardsfolder/i/insist.txt @@ -4,7 +4,7 @@ Types:Sorcery Text:no text A:SP$Effect | Cost$ G | Name$ Insist effect | Triggers$ SpellCastTrig | SVars$ Insistence,DBCleanup | SubAbility$ DBDraw | SpellDescription$ The next creature spell you cast this turn can't be countered by spells or abilities. SVar:DBDraw:DB$Draw | NumCards$ 1 | SpellDescription$ Draw a card. -SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Creature | ValidControllingPlayer$ You | Execute$ Insistence | TriggerDescription$ The next creature spell you cast this turn can't be countered by spells or abilities. +SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ Insistence | TriggerDescription$ The next creature spell you cast this turn can't be countered by spells or abilities. SVar:Insistence:AB$ Pump | Cost$ 0 | Defined$ TriggeredCard | KW$ HIDDEN CARDNAME can't be countered. | PumpZone$ Stack | SubAbility$ DBCleanup SVar:DBCleanup:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Graveyard SVar:RemAIDeck:True diff --git a/res/cardsfolder/i/inspired_sprite.txt b/res/cardsfolder/i/inspired_sprite.txt index b0becdddb20..96684696ea7 100644 --- a/res/cardsfolder/i/inspired_sprite.txt +++ b/res/cardsfolder/i/inspired_sprite.txt @@ -5,7 +5,7 @@ Text:no text PT:2/2 K:Flash K:Flying -T:Mode$ SpellCast | ValidCard$ Wizard.YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a Wizard spell, you may untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Wizard | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a Wizard spell, you may untap CARDNAME. A:AB$ Draw | Cost$ T | NumCards$ 1 | SpellDescription$ Draw a card, then discard a card. | SubAbility$ DBDiscard SVar:DBDiscard:DB$Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self diff --git a/res/cardsfolder/i/ishi_ishi_akki_crackshot.txt b/res/cardsfolder/i/ishi_ishi_akki_crackshot.txt index 824a164b8f8..3bd890f3972 100644 --- a/res/cardsfolder/i/ishi_ishi_akki_crackshot.txt +++ b/res/cardsfolder/i/ishi_ishi_akki_crackshot.txt @@ -3,7 +3,7 @@ ManaCost:1 R Types:Legendary Creature Goblin Warrior Text:no text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Spirit.YouDontCtrl,Arcane.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever an opponent casts a Spirit or Arcane spell, CARDNAME deals 2 damage to that player. +T:Mode$ SpellCast | ValidCard$ Spirit,Arcane | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever an opponent casts a Spirit or Arcane spell, CARDNAME deals 2 damage to that player. SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Defined$ TriggeredCardController | NumDmg$ 2 SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/i/isolation_cell.txt b/res/cardsfolder/i/isolation_cell.txt index c59490a4da2..fd1d085c4c4 100644 --- a/res/cardsfolder/i/isolation_cell.txt +++ b/res/cardsfolder/i/isolation_cell.txt @@ -2,7 +2,7 @@ Name:Isolation Cell ManaCost:4 Types:Artifact Text:no text -T:Mode$ SpellCast | ValidCard$ Creature | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigLose | TriggerDescription$ Whenever an opponent casts a creature spell, that player loses 2 life unless he or she pays 2. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigLose | TriggerDescription$ Whenever an opponent casts a creature spell, that player loses 2 life unless he or she pays 2. SVar:TrigLose:AB$LoseLife | Cost$ 0 | Defined$ TriggeredCardController | LifeAmount$ 2 | UnlessCost$ 2 | UnlessPayer$ TriggeredCardController SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/isolation_cell.jpg diff --git a/res/cardsfolder/j/jackalope_herd.txt b/res/cardsfolder/j/jackalope_herd.txt index 63abbd69ccf..91e192301f0 100644 --- a/res/cardsfolder/j/jackalope_herd.txt +++ b/res/cardsfolder/j/jackalope_herd.txt @@ -3,7 +3,7 @@ ManaCost:3 G Types:Creature Rabbit Beast Text:no text PT:4/5 -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ When you cast a spell, return CARDNAME to its owner's hand. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ When you cast a spell, return CARDNAME to its owner's hand. SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | Defined$ Self SVar:RemAIDeck:True SVar:Rarity:Common diff --git a/res/cardsfolder/j/juju_bubble.txt b/res/cardsfolder/j/juju_bubble.txt index 789768cfb22..0db486debc7 100644 --- a/res/cardsfolder/j/juju_bubble.txt +++ b/res/cardsfolder/j/juju_bubble.txt @@ -4,7 +4,7 @@ Types:Artifact Text:no text K:Cumulative upkeep:1 A:AB$ GainLife | Cost$ 2 | Defined$ You | LifeAmount$ 1 | SpellDescription$ You gain 1 life. -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When you play a card, sacrifice CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When you play a card, sacrifice CARDNAME. T:Mode$ LandPlayed | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSac | Secondary$ True | TriggerDescription$ When you play a card, sacrifice CARDNAME. SVar:TrigSac:AB$Sacrifice | Cost$ 0 SVar:RemAIDeck:True diff --git a/res/cardsfolder/k/kaervek_the_merciless.txt b/res/cardsfolder/k/kaervek_the_merciless.txt index d5b5aeaf5b3..f211d90a721 100644 --- a/res/cardsfolder/k/kaervek_the_merciless.txt +++ b/res/cardsfolder/k/kaervek_the_merciless.txt @@ -3,7 +3,7 @@ ManaCost:5 B R Types:Legendary Creature Human Shaman Text:no text PT:5/4 -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever an opponent casts a spell, CARDNAME deals damage to target creature or player equal to that spell's converted mana cost. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever an opponent casts a spell, CARDNAME deals damage to target creature or player equal to that spell's converted mana cost. SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Tgt$ TgtCP | NumDmg$ X SVar:X:TriggeredCard$CardManaCost SVar:Rarity:Rare diff --git a/res/cardsfolder/k/kessig_cagebreakers.txt b/res/cardsfolder/k/kessig_cagebreakers.txt index 76a5ce64e47..eee8cb172b0 100644 --- a/res/cardsfolder/k/kessig_cagebreakers.txt +++ b/res/cardsfolder/k/kessig_cagebreakers.txt @@ -6,6 +6,7 @@ PT:3/4 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME attacks, put a 2/2 green Wolf creature token onto the battlefield tapped and attacking for each creature card in your graveyard. SVar:TrigToken:AB$Token | Cost$ 0 | TokenImage$ G 2 2 Wolf | TokenAmount$ X | TokenName$ Wolf | TokenTypes$ Creature,Wolf | TokenOwner$ You | TokenColors$ Green | TokenPower$ 2 | TokenToughness$ 2 | TokenTapped$ True | TokenAttacking$ True SVar:X:Count$TypeInYourYard.Creature +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/kessig_cagebreakers.jpg SetInfo:ISD|Rare|http://magiccards.info/scans/en/isd/189.jpg diff --git a/res/cardsfolder/k/kiln_fiend.txt b/res/cardsfolder/k/kiln_fiend.txt index a66072caa31..fcc950da16a 100644 --- a/res/cardsfolder/k/kiln_fiend.txt +++ b/res/cardsfolder/k/kiln_fiend.txt @@ -3,7 +3,7 @@ ManaCost:1 R Types:Creature Elemental Beast Text:no text PT:1/2 -T:Mode$ SpellCast | ValidCard$ Instant.YouCtrl,Sorcery.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a instant or sorcery spell, CARDNAME gets +3/+0 until end of turn. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a instant or sorcery spell, CARDNAME gets +3/+0 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | NumAtt$ +3 | NumDef$ +0 | Defined$ Self SVar:BuffedBy:Instant,Sorcery SVar:Rarity:Common diff --git a/res/cardsfolder/k/kor_spiritdancer.txt b/res/cardsfolder/k/kor_spiritdancer.txt index 1e64bc65291..106dd79d5a0 100644 --- a/res/cardsfolder/k/kor_spiritdancer.txt +++ b/res/cardsfolder/k/kor_spiritdancer.txt @@ -3,7 +3,7 @@ ManaCost:1 W Types:Creature Kor Wizard Text:no text PT:0/2 -T:Mode$ SpellCast | ValidCard$ Card.Aura+YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an Aura spell, you may draw a card. +T:Mode$ SpellCast | ValidCard$ Aura | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an Aura spell, you may draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 S:Mode$ Continuous | Affected$ Card.Self | AddPower$ X | AddToughness$ X | Description$ CARDNAME gets +2/+2 for each Aura attached to it. SVar:X:Count$Valid Aura.Attached/Times.2 diff --git a/res/cardsfolder/k/kurgadon.txt b/res/cardsfolder/k/kurgadon.txt index 935f9eb3611..f80b771065f 100644 --- a/res/cardsfolder/k/kurgadon.txt +++ b/res/cardsfolder/k/kurgadon.txt @@ -3,7 +3,7 @@ ManaCost:4 G Types:Creature Beast Text:no text PT:3/3 -T:Mode$ SpellCast | ValidCard$ Creature.cmcGE6+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a creature spell with converted mana cost 6 or more, put three +1/+1 counters on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Creature.cmcGE6 | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a creature spell with converted mana cost 6 or more, put three +1/+1 counters on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 3 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/kurgadon.jpg diff --git a/res/cardsfolder/l/leap_of_faith.txt b/res/cardsfolder/l/leap_of_faith.txt index 2c9524a2f60..e080a089c7a 100644 --- a/res/cardsfolder/l/leap_of_faith.txt +++ b/res/cardsfolder/l/leap_of_faith.txt @@ -3,7 +3,6 @@ ManaCost:2 W Types:Instant Text:no text A:SP$ Pump | Cost$ 2 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ Flying & HIDDEN Prevent all damage that would be dealt to CARDNAME. | SpellDescription$ Target creature gains flying until end of turn. Prevent all damage that would be dealt to that creature this turn. -SVar:RemAIDeck:True SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/leap_of_faith.jpg SetInfo:AVR|Common|http://magiccards.info/scans/en/avr/26.jpg diff --git a/res/cardsfolder/l/leering_emblem.txt b/res/cardsfolder/l/leering_emblem.txt index 857bf9c08bd..1ec085e8bfa 100644 --- a/res/cardsfolder/l/leering_emblem.txt +++ b/res/cardsfolder/l/leering_emblem.txt @@ -3,7 +3,7 @@ ManaCost:2 Types:Artifact Equipment Text:no text K:eqPump 2:+0/+0 -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a spell, equipped creature gets +2/+2 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a spell, equipped creature gets +2/+2 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ Equipped | NumAtt$ +2 | NumDef$ +2 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/leering_emblem.jpg diff --git a/res/cardsfolder/l/leonin_battlemage.txt b/res/cardsfolder/l/leonin_battlemage.txt index 7284adee420..ec2105e285c 100644 --- a/res/cardsfolder/l/leonin_battlemage.txt +++ b/res/cardsfolder/l/leonin_battlemage.txt @@ -3,7 +3,7 @@ ManaCost:3 W Types:Creature Cat Wizard Text:no text PT:2/3 -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a spell, you may untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a spell, you may untap CARDNAME. A:AB$ Pump | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +1 | NumDef$ +1 | SpellDescription$ Target creature gets +1/+1 until end of turn. SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self SVar:RemAIDeck:True diff --git a/res/cardsfolder/l/leshracs_sigil.txt b/res/cardsfolder/l/leshracs_sigil.txt index f4349088b76..f350f4fdd5e 100644 --- a/res/cardsfolder/l/leshracs_sigil.txt +++ b/res/cardsfolder/l/leshracs_sigil.txt @@ -3,7 +3,7 @@ ManaCost:B B Types:Enchantment Text:no text A:AB$ ChangeZone | Cost$ B B | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return CARDNAME to its owner's hand. -T:Mode$ SpellCast | ValidCard$ Card.Green+YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigDiscard | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a green spell, you may pay B B. If you do, look at that player's hand and choose a card from it. The player discards that card. +T:Mode$ SpellCast | ValidCard$ Card.Green | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDiscard | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a green spell, you may pay B B. If you do, look at that player's hand and choose a card from it. The player discards that card. SVar:TrigDiscard:AB$Discard | Cost$ B B | Defined$ Opponent | NumCards$ 1 | Mode$ RevealYouChoose SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/l/leyline_of_lightning.txt b/res/cardsfolder/l/leyline_of_lightning.txt index 5ae6a664328..26e3dfd3445 100644 --- a/res/cardsfolder/l/leyline_of_lightning.txt +++ b/res/cardsfolder/l/leyline_of_lightning.txt @@ -2,7 +2,7 @@ Name:Leyline of Lightning ManaCost:2 R R Types:Enchantment Text:If Leyline of Lightning is in your opening hand, you may begin the game with it on the battlefield. -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a spell, you may pay 1. If you do, CARDNAME deals 1 damage to target player. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a spell, you may pay 1. If you do, CARDNAME deals 1 damage to target player. SVar:TrigDealDamage:AB$DealDamage | Cost$ 1 | Tgt$ TgtP | NumDmg$ 1 SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/l/lifesmith.txt b/res/cardsfolder/l/lifesmith.txt index 13a52535646..a685f6f6c26 100644 --- a/res/cardsfolder/l/lifesmith.txt +++ b/res/cardsfolder/l/lifesmith.txt @@ -3,7 +3,7 @@ ManaCost:1 G Types:Creature Human Artificer Text:no text PT:2/1 -T:Mode$ SpellCast | ValidCard$ Artifact.YouCtrl | Execute$ TrigGainLife | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may pay 1. If you do, you gain 3 life. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigGainLife | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may pay 1. If you do, you gain 3 life. SVar:TrigGainLife:AB$GainLife | Cost$ 1 | Defined$ You | LifeAmount$ 3 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/lifesmith.jpg diff --git a/res/cardsfolder/l/loyal_gyrfalcon.txt b/res/cardsfolder/l/loyal_gyrfalcon.txt index bb45c45e089..82cdbdef011 100644 --- a/res/cardsfolder/l/loyal_gyrfalcon.txt +++ b/res/cardsfolder/l/loyal_gyrfalcon.txt @@ -5,7 +5,7 @@ Text:no text PT:3/3 K:Flying K:Defender -T:Mode$ SpellCast | ValidCard$ Card.White | ValidControllingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDebuff | TriggerDescription$ Whenever you cast a white spell, CARDNAME loses defender until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDebuff | TriggerDescription$ Whenever you cast a white spell, CARDNAME loses defender until end of turn. SVar:TrigDebuff:AB$ Debuff | Cost$ 0 | Defined$ Self | Keywords$ Defender SVar:BuffedBy:Card.White SVar:Rarity:Uncommon diff --git a/res/cardsfolder/l/lurking_predators.txt b/res/cardsfolder/l/lurking_predators.txt index 12110c74b1c..688c32e9fad 100644 --- a/res/cardsfolder/l/lurking_predators.txt +++ b/res/cardsfolder/l/lurking_predators.txt @@ -2,7 +2,7 @@ Name:Lurking Predators ManaCost:4 G G Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ Whenever an opponent casts a spell, reveal the top card of your library. If it's a creature card, put it onto the battlefield. Otherwise, you may put that card on the bottom of your library. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDig | TriggerDescription$ Whenever an opponent casts a spell, reveal the top card of your library. If it's a creature card, put it onto the battlefield. Otherwise, you may put that card on the bottom of your library. SVar:TrigDig:DB$ Dig | DigNum$ 1 | Reveal$ True | ChangeNum$ All | ChangeValid$ Creature | DestinationZone$ Battlefield | LibraryPosition2$ 0 | RememberChanged$ True | SubAbility$ DBDig SVar:DBDig:DB$ Dig | DigNum$ 1 | DestinationZone$ Library | Optional$ True | LibraryPosition$ -1 | LibraryPosition2$ 0 | CheckSVar$ X | SVarCompare$ EQ0 | SubAbility$ DBCleanup SVar:X:Remembered$Amount diff --git a/res/cardsfolder/l/lys_alana_huntmaster.txt b/res/cardsfolder/l/lys_alana_huntmaster.txt index f2204a8a66b..8dd2e62b713 100644 --- a/res/cardsfolder/l/lys_alana_huntmaster.txt +++ b/res/cardsfolder/l/lys_alana_huntmaster.txt @@ -3,7 +3,7 @@ ManaCost:2 G G Types:Creature Elf Warrior Text:no text PT:3/3 -T:Mode$ SpellCast | ValidCard$ Elf.YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigToken | TriggerDescription$ Whenever you cast an Elf spell, you may put a 1/1 green Elf Warrior creature token onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Elf | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigToken | TriggerDescription$ Whenever you cast an Elf spell, you may put a 1/1 green Elf Warrior creature token onto the battlefield. SVar:TrigToken:AB$Token | Cost$ 0 | TokenImage$ G 1 1 Elf Warrior | TokenAmount$ 1 | TokenName$ Elf Warrior | TokenTypes$ Creature,Elf,Warrior | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/lys_alana_huntmaster.jpg diff --git a/res/cardsfolder/m/mage_slayer.txt b/res/cardsfolder/m/mage_slayer.txt index f57a39f2831..5b04fdf85d1 100644 --- a/res/cardsfolder/m/mage_slayer.txt +++ b/res/cardsfolder/m/mage_slayer.txt @@ -6,6 +6,8 @@ K:eqPump 3:0/0 T:Mode$ Attacks | ValidCard$ Card.AttachedBy | Execute$ TrigDamage | TriggerDescription$ Whenever equipped creature attacks, it deals damage equal to its power to defending player. SVar:TrigDamage:AB$DealDamage | Cost$ 0 | ValidTgts$ Opponent,Planeswalker.YouDontCtrl | DamageSource$ Equipped | TgtPrompt$ Select target opponent or planeswalker | NumDmg$ X SVar:X:TriggeredAttacker$CardPower +S:Mode$ Continuous | Affected$ Creature.AttachedBy | AddSVar$ AE +SVar:AE:SVar:HasAttackEffect:TRUE SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/mage_slayer.jpg SetInfo:ARB|Uncommon|http://magiccards.info/scans/en/pch/91.jpg diff --git a/res/cardsfolder/m/mana_breach.txt b/res/cardsfolder/m/mana_breach.txt index 68844e63513..be466ac19dc 100644 --- a/res/cardsfolder/m/mana_breach.txt +++ b/res/cardsfolder/m/mana_breach.txt @@ -2,8 +2,8 @@ Name:Mana Breach ManaCost:2 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigBounceYou | TriggerDescription$ Whenever a player casts a spell, that player returns a land he or she controls to its owner's hand. -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigBounceOpp | Secondary$ True | TriggerDescription$ Whenever a player casts a spell, that player returns a land he or she controls to its owner's hand. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigBounceYou | TriggerDescription$ Whenever a player casts a spell, that player returns a land he or she controls to its owner's hand. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigBounceOpp | Secondary$ True | TriggerDescription$ Whenever a player casts a spell, that player returns a land he or she controls to its owner's hand. SVar:TrigBounceYou:AB$ ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | ChangeNum$ 1 | ChangeType$ Land.YouCtrl | Mandatory$ True | DefinedPlayer$ You | Hidden$ True SVar:TrigBounceOpp:AB$ ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | ChangeNum$ 1 | ChangeType$ Land.YouDontCtrl | Mandatory$ True | DefinedPlayer$ Opponent | Hidden$ True SVar:RemRandomDeck:True diff --git a/res/cardsfolder/m/manaplasm.txt b/res/cardsfolder/m/manaplasm.txt index 3a9a4b5011d..77402b2f4dd 100644 --- a/res/cardsfolder/m/manaplasm.txt +++ b/res/cardsfolder/m/manaplasm.txt @@ -3,7 +3,7 @@ ManaCost:2 G Types:Creature Ooze Text:no text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a spell, CARDNAME gets +X/+X until end of turn, where X is that spell's converted mana cost. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a spell, CARDNAME gets +X/+X until end of turn, where X is that spell's converted mana cost. SVar:TrigPump:AB$Pump | Cost$ 0 | NumAtt$ +X | NumDef$ +X SVar:X:TriggeredCard$CardManaCost SVar:BuffedBy:Card diff --git a/res/cardsfolder/m/masked_admirers.txt b/res/cardsfolder/m/masked_admirers.txt index 3e85305a252..7b811e337a3 100644 --- a/res/cardsfolder/m/masked_admirers.txt +++ b/res/cardsfolder/m/masked_admirers.txt @@ -4,7 +4,7 @@ Types:Creature Elf Shaman Text:no text PT:3/2 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When CARDNAME enters the battlefield, draw a card. -T:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a creature spell, you may pay G G. If you do, return CARDNAME from your graveyard to your hand. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a creature spell, you may pay G G. If you do, return CARDNAME from your graveyard to your hand. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:TrigReturn:AB$ChangeZone | Cost$ G G | Defined$ Self | Origin$ Graveyard | Destination$ Hand SVar:Rarity:Rare diff --git a/res/cardsfolder/m/merrow_bonegnawer.txt b/res/cardsfolder/m/merrow_bonegnawer.txt index 95cfe9e31d5..a6f6af8f19c 100644 --- a/res/cardsfolder/m/merrow_bonegnawer.txt +++ b/res/cardsfolder/m/merrow_bonegnawer.txt @@ -4,7 +4,7 @@ Types:Creature Merfolk Rogue Text:no text PT:1/1 A:AB$ ChangeZone | Cost$ T | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Player | Mandatory$ True | ChangeType$ Card | ChangeNum$ 1 | Hidden$ True | IsCurse$ True | Chooser$ Targeted | SpellDescription$ Target player exiles a card from his or her graveyard. -T:Mode$ SpellCast | ValidCard$ Card.Black+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a black spell, you may untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card.Black | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a black spell, you may untap CARDNAME. SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/merrow_bonegnawer.jpg diff --git a/res/cardsfolder/m/merrow_reejerey.txt b/res/cardsfolder/m/merrow_reejerey.txt index 5bf527a6e28..67cccf693b0 100644 --- a/res/cardsfolder/m/merrow_reejerey.txt +++ b/res/cardsfolder/m/merrow_reejerey.txt @@ -4,7 +4,7 @@ Types:Creature Merfolk Soldier Text:no text PT:2/2 S:Mode$ Continuous | Affected$ Creature.Merfolk+Other+YouCtrl | AddPower$ 1 | AddToughness$ 1 | Description$ Other Merfolk creatures you control get +1/+1. -T:Mode$ SpellCast | ValidCard$ Card.Merfolk+YouCtrl | Execute$ TrigTapOrUntap | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Merfolk spell, you may tap or untap target permanent. +T:Mode$ SpellCast | ValidCard$ Merfolk | ValidActivatingPlayer$ You | Execute$ TrigTapOrUntap | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a Merfolk spell, you may tap or untap target permanent. SVar:TrigTapOrUntap:AB$TapOrUntap | Cost$ 0 | ValidTgts$ Permanent | TgtPrompt$ Select target permanent SVar:PlayMain1:TRUE SVar:BuffedBy:Merfolk diff --git a/res/cardsfolder/m/mesa_enchantress.txt b/res/cardsfolder/m/mesa_enchantress.txt index cafc533e1da..1ba5596b86f 100644 --- a/res/cardsfolder/m/mesa_enchantress.txt +++ b/res/cardsfolder/m/mesa_enchantress.txt @@ -3,7 +3,7 @@ ManaCost:1 W W Types:Creature Human Druid Text:no text PT:0/2 -T:Mode$ SpellCast | ValidCard$ Card.Enchantment+YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. +T:Mode$ SpellCast | ValidCard$ Enchantment | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/m/mindmoil.txt b/res/cardsfolder/m/mindmoil.txt index f9ff685a0e8..b20950d4f0e 100644 --- a/res/cardsfolder/m/mindmoil.txt +++ b/res/cardsfolder/m/mindmoil.txt @@ -2,7 +2,7 @@ Name:Mindmoil ManaCost:4 R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | Execute$ TrigChangeZone | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, put the cards in your hand on the bottom of your library in any order, then draw that many cards. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigChangeZone | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, put the cards in your hand on the bottom of your library in any order, then draw that many cards. SVar:TrigChangeZone:AB$ ChangeZone | Cost$ 0 | Origin$ Hand | Destination$ Library | ChangeType$ Card | ChangeNum$ Tossed | RememberChanged$ True | LibraryPosition$ -1 | SubAbility$ DBDraw SVar:DBDraw:DB$ Draw | NumCards$ RemTossed | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True diff --git a/res/cardsfolder/m/mirran_spy.txt b/res/cardsfolder/m/mirran_spy.txt index 2865ffb24aa..81024285a85 100644 --- a/res/cardsfolder/m/mirran_spy.txt +++ b/res/cardsfolder/m/mirran_spy.txt @@ -4,7 +4,7 @@ Types:Creature Drone Text:no text PT:1/3 K:Flying -T:Mode$ SpellCast | ValidCard$ Artifact | ValidControllingPlayer$ You | Execute$ TrigUntap | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may untap target creature. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigUntap | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may untap target creature. SVar:TrigUntap:AB$Untap | Cost$ 0 | ValidTgts$ Creature SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/mirran_spy.jpg diff --git a/res/cardsfolder/m/mishra_artificer_prodigy.txt b/res/cardsfolder/m/mishra_artificer_prodigy.txt index e3c54940e71..600acaca50f 100644 --- a/res/cardsfolder/m/mishra_artificer_prodigy.txt +++ b/res/cardsfolder/m/mishra_artificer_prodigy.txt @@ -3,7 +3,7 @@ ManaCost:1 U B R Types:Legendary Creature Human Artificer Text:no text PT:4/4 -T:Mode$ SpellCast | ValidCard$ Card.Artifact | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigChangeZone | TriggerDescription$ Whenever you cast an artifact spell, you may search your graveyard, hand, and/or library for a card with the same name as that spell and put it onto the battlefield. If you search your library this way, shuffle it. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigChangeZone | TriggerDescription$ Whenever you cast an artifact spell, you may search your graveyard, hand, and/or library for a card with the same name as that spell and put it onto the battlefield. If you search your library this way, shuffle it. SVar:TrigChangeZone:DB$ ChangeZone | Hidden$ True | Origin$ Library | OriginChoice$ True | OriginAlternative$ Graveyard,Hand | AlternativeMessage$ Would you like to search your library with this ability? If you do, your library will be shuffled. | Destination$ Battlefield | ChangeType$ Triggered.sameName SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/mishra_artificer_prodigy.jpg diff --git a/res/cardsfolder/m/mogg_sentry.txt b/res/cardsfolder/m/mogg_sentry.txt index ba0fc19aa7e..902d00136dc 100644 --- a/res/cardsfolder/m/mogg_sentry.txt +++ b/res/cardsfolder/m/mogg_sentry.txt @@ -3,7 +3,7 @@ ManaCost:R Types:Creature Goblin Warrior Text:no text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever an opponent casts a spell, CARDNAME gets +2/+2 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever an opponent casts a spell, CARDNAME gets +2/+2 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ Self | NumAtt$ 2 | NumDef$ 2 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/mogg_sentry.jpg diff --git a/res/cardsfolder/m/mold_adder.txt b/res/cardsfolder/m/mold_adder.txt index afb960d35f8..57318a12bb7 100644 --- a/res/cardsfolder/m/mold_adder.txt +++ b/res/cardsfolder/m/mold_adder.txt @@ -3,7 +3,7 @@ ManaCost:G Types:Creature Fungus Snake Text:no text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Card.Blue+YouDontCtrl,Card.Black+YouDontCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts a blue or black spell, you may put a +1/+1 counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card.Blue,Card.Black | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts a blue or black spell, you may put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/mold_adder.jpg diff --git a/res/cardsfolder/m/mondronen_shaman_tovolars_magehunter.txt b/res/cardsfolder/m/mondronen_shaman_tovolars_magehunter.txt index b68088b3fce..5eff3194c02 100644 --- a/res/cardsfolder/m/mondronen_shaman_tovolars_magehunter.txt +++ b/res/cardsfolder/m/mondronen_shaman_tovolars_magehunter.txt @@ -20,7 +20,7 @@ Colors:Red Types:Creature Werewolf Text:no text PT:5/5 -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever an opponent casts a spell, CARDNAME deals 2 damage to that player. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever an opponent casts a spell, CARDNAME deals 2 damage to that player. SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Defined$ TriggeredPlayer | NumDmg$ 2 T:Mode$Phase | Phase$ Upkeep | WerewolfUntransformCondition$ True | TriggerZones$ Battlefield | Execute$ TrigTransform | TriggerDescription$ At the beginning of each upkeep, if a player cast two or more spells last turn, transform CARDNAME. SVar:Picture1:http://www.wizards.com/global/images/magic/general/tovolars_magehunter.jpg diff --git a/res/cardsfolder/m/moonsilver_spear.txt b/res/cardsfolder/m/moonsilver_spear.txt index 0728cb99421..fe9a66817ab 100644 --- a/res/cardsfolder/m/moonsilver_spear.txt +++ b/res/cardsfolder/m/moonsilver_spear.txt @@ -4,7 +4,9 @@ Types:Artifact Equipment Text:Equipped creature has first strike. K:eqPump 4:+0/+0/First Strike T:Mode$ Attacks | ValidCard$ Card.AttachedBy | Execute$ TrigAngelToken | TriggerDescription$ Whenever equipped creature attacks, put a 4/4 white Angel token with flying onto the battlefield. -SVar:TrigAngelToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Angel | TokenTypes$ Creature,Angel | TokenOwner$ You | TokenColors$ White | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Flying +SVar:TrigAngelToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Angel | TokenTypes$ Creature,Angel | TokenOwner$ You | TokenColors$ White | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Flying | TokenImage$ w 4 4 angel avr +S:Mode$ Continuous | Affected$ Creature.AttachedBy | AddSVar$ AE +SVar:AE:SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/moonsilver_spear.jpg SetInfo:AVR|Rare|http://magiccards.info/scans/en/avr/217.jpg diff --git a/res/cardsfolder/m/myrsmith.txt b/res/cardsfolder/m/myrsmith.txt index 15dfa9516ee..c8e27a19187 100644 --- a/res/cardsfolder/m/myrsmith.txt +++ b/res/cardsfolder/m/myrsmith.txt @@ -3,7 +3,7 @@ ManaCost:1 W Types:Creature Human Artificer Text:no text PT:2/1 -T:Mode$ SpellCast | ValidCard$ Artifact.YouCtrl | Execute$ TrigToken | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may pay 1. If you do, put a 1/1 colorless Myr artifact creature token onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigToken | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may pay 1. If you do, put a 1/1 colorless Myr artifact creature token onto the battlefield. SVar:TrigToken:AB$Token | Cost$ 1 | TokenImage$ C 1 1 Myr | TokenAmount$ 1 | TokenName$ Myr | TokenTypes$ Artifact,Creature,Myr | TokenOwner$ You | TokenColors$ Colorless | TokenPower$ 1 | TokenToughness$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/myrsmith.jpg diff --git a/res/cardsfolder/m/mystic_remora.txt b/res/cardsfolder/m/mystic_remora.txt index ac5aaca8023..ebadc743ed7 100644 --- a/res/cardsfolder/m/mystic_remora.txt +++ b/res/cardsfolder/m/mystic_remora.txt @@ -3,7 +3,7 @@ ManaCost:U Types:Enchantment Text:no text K:Cumulative upkeep:1 -T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a noncreature spell, you may draw a card unless that player pays 4. +T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a noncreature spell, you may draw a card unless that player pays 4. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | UnlessCost$ 4 | UnlessPayer$ TriggeredPlayer | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Common diff --git a/res/cardsfolder/n/nefashu.txt b/res/cardsfolder/n/nefashu.txt index 17eede4f7a0..1dc23948aac 100644 --- a/res/cardsfolder/n/nefashu.txt +++ b/res/cardsfolder/n/nefashu.txt @@ -5,6 +5,7 @@ Text:no text PT:5/3 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigShrink | TriggerDescription$ Whenever CARDNAME attacks, up to five target creatures each get -1/-1 until end of turn. SVar:TrigShrink:AB$Pump | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature | TargetMin$ 0 | TargetMax$ 5 | NumAtt$ -1 | NumDef$ -1 | IsCurse$ True +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/nefashu.jpg SetInfo:SCG|Rare|http://magiccards.info/scans/en/sc/70.jpg diff --git a/res/cardsfolder/n/nemesis_of_reason.txt b/res/cardsfolder/n/nemesis_of_reason.txt index 160a77b576a..6336a1b397f 100644 --- a/res/cardsfolder/n/nemesis_of_reason.txt +++ b/res/cardsfolder/n/nemesis_of_reason.txt @@ -5,6 +5,7 @@ Text:no text PT:3/7 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ Whenever CARDNAME attacks, defending player puts the top ten cards of his or her library into his or her graveyard. SVar:TrigMill:AB$Mill | Cost$ 0 | Defined$ Opponent | NumCards$ 10 +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/nemesis_of_reason.jpg SetInfo:ARB|Rare|http://magiccards.info/scans/en/arb/28.jpg diff --git a/res/cardsfolder/n/nettle_sentinel.txt b/res/cardsfolder/n/nettle_sentinel.txt index 3f87d48f7c2..326469f1635 100644 --- a/res/cardsfolder/n/nettle_sentinel.txt +++ b/res/cardsfolder/n/nettle_sentinel.txt @@ -4,7 +4,7 @@ Types:Creature Elf Warrior Text:no text PT:2/2 K:CARDNAME doesn't untap during your untap step. -T:Mode$ SpellCast | ValidCard$ Card.Green+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a green spell, you may untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card.Green | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a green spell, you may untap CARDNAME. SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/nettle_sentinel.jpg diff --git a/res/cardsfolder/n/null_profusion.txt b/res/cardsfolder/n/null_profusion.txt index b12c8f1c1d5..5c2818f5549 100644 --- a/res/cardsfolder/n/null_profusion.txt +++ b/res/cardsfolder/n/null_profusion.txt @@ -4,7 +4,7 @@ Types:Enchantment Text:no text S:Mode$ Continuous | Affected$ You | AddKeyword$ Skip your draw step. | Description$ Skip your draw step. S:Mode$ Continuous | Affected$ You | SetMaxHandSize$ 2 | Description$ Your maximum hand size is 2. -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you play a card, draw a card. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you play a card, draw a card. T:Mode$ LandPlayed | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | Secondary$ True | TriggerDescription$ Whenever you play a card, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True diff --git a/res/cardsfolder/o/oni_of_wild_places.txt b/res/cardsfolder/o/oni_of_wild_places.txt index 7b7f0cda8ef..3d45877be45 100644 --- a/res/cardsfolder/o/oni_of_wild_places.txt +++ b/res/cardsfolder/o/oni_of_wild_places.txt @@ -5,7 +5,7 @@ Text:no text PT:6/5 K:Haste T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, return a red creature you control to its owner's hand. -SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target red creature | Mandatory$ True | ValidTgts$ Creature.Red+YouCtrl +SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target red creature | Mandatory$ True | Hidden$ True | ValidTgts$ Creature.Red+YouCtrl SVar:RemAIDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/oni_of_wild_places.jpg diff --git a/res/cardsfolder/o/onslaught.txt b/res/cardsfolder/o/onslaught.txt index 170132ad276..5de8dbb9435 100644 --- a/res/cardsfolder/o/onslaught.txt +++ b/res/cardsfolder/o/onslaught.txt @@ -2,7 +2,7 @@ Name:Onslaught ManaCost:R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever you cast a creature spell, tap target creature. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigTap | TriggerDescription$ Whenever you cast a creature spell, tap target creature. SVar:TrigTap:AB$Tap | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature SVar:BuffedBy:Creature SVar:Rarity:Common diff --git a/res/cardsfolder/o/oppression.txt b/res/cardsfolder/o/oppression.txt index 06979b90cb2..d854294367f 100644 --- a/res/cardsfolder/o/oppression.txt +++ b/res/cardsfolder/o/oppression.txt @@ -3,7 +3,7 @@ ManaCost:1 B B Types:Enchantment Text:no text T:Mode$ SpellCast | ValidCard$ Card | TriggerZones$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ Whenever a player casts a spell, that player discards a card. -SVar:TrigDiscard:AB$Discard | Cost$ 0 | Defined$ TriggeredCardController | NumCards$ 1 | Mode$ TgtChoose +SVar:TrigDiscard:AB$Discard | Cost$ 0 | Defined$ TriggeredActivator | NumCards$ 1 | Mode$ TgtChoose SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/oppression.jpg diff --git a/res/cardsfolder/o/overmaster.txt b/res/cardsfolder/o/overmaster.txt index f539faeaeb0..30218879ed4 100644 --- a/res/cardsfolder/o/overmaster.txt +++ b/res/cardsfolder/o/overmaster.txt @@ -4,7 +4,7 @@ Types:Sorcery Text:no text A:SP$Effect | Cost$ R | Name$ Overmaster effect | Triggers$ SpellCastTrig | SVars$ Mastery,DBCleanup | SubAbility$ DBDraw | SpellDescription$ The next instant or sorcery spell you cast this turn can't be countered by spells or abilities. SVar:DBDraw:DB$Draw | NumCards$ 1 | SpellDescription$ Draw a card. -SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidControllingPlayer$ You | Execute$ Mastery | TriggerDescription$ The next instant or sorcery spell you cast this turn can't be countered by spells or abilities. +SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | Execute$ Mastery | TriggerDescription$ The next instant or sorcery spell you cast this turn can't be countered by spells or abilities. SVar:Mastery:AB$ Pump | Cost$ 0 | Defined$ TriggeredCard | KW$ HIDDEN CARDNAME can't be countered. | PumpZone$ Stack | SubAbility$ DBCleanup SVar:DBCleanup:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Graveyard SVar:RemAIDeck:True diff --git a/res/cardsfolder/p/painsmith.txt b/res/cardsfolder/p/painsmith.txt index 65ca7c88925..f7e9f09848b 100644 --- a/res/cardsfolder/p/painsmith.txt +++ b/res/cardsfolder/p/painsmith.txt @@ -3,7 +3,7 @@ ManaCost:1 B Types:Creature Human Artificer Text:no text PT:2/1 -T:Mode$ SpellCast | ValidCard$ Artifact.YouCtrl | Execute$ TrigPump | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may have target creature get +2/+0 and gain deathtouch until end of turn. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may have target creature get +2/+0 and gain deathtouch until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 2 | KW$ Deathtouch SVar:BuffedBy:Artifact SVar:Rarity:Uncommon diff --git a/res/cardsfolder/p/pardic_dragon.txt b/res/cardsfolder/p/pardic_dragon.txt index 625c1865c75..8d24d83c2d9 100644 --- a/res/cardsfolder/p/pardic_dragon.txt +++ b/res/cardsfolder/p/pardic_dragon.txt @@ -6,7 +6,7 @@ PT:4/4 K:Flying K:Suspend:2:R R A:AB$ Pump | Cost$ R | NumAtt$ +1 | SpellDescription$ CARDNAME gets +1/+0 until end of turn. -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | TriggerZones$ Exile | IsPresent$ Card.counters_GE1_TIME+Self | PresentZone$ Exile | OptionalDecider$ Opponent | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts a spell, if CARDNAME is suspended, that player may put a time counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Exile | IsPresent$ Card.counters_GE1_TIME+Self | PresentZone$ Exile | OptionalDecider$ Opponent | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts a spell, if CARDNAME is suspended, that player may put a time counter on CARDNAME. SVar:TrigPutCounter:AB$ PutCounter | Cost$ 0 | Defined$ Self | CounterType$ TIME | CounterNum$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/pardic_dragon.jpg diff --git a/res/cardsfolder/p/planar_chaos.txt b/res/cardsfolder/p/planar_chaos.txt index 28b2a35a670..999c61f6343 100644 --- a/res/cardsfolder/p/planar_chaos.txt +++ b/res/cardsfolder/p/planar_chaos.txt @@ -6,7 +6,7 @@ T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigFlipUpkeep | Tri SVar:TrigFlipUpkeep:AB$ FlipACoin | Cost$ 0 | LoseSubAbility$ DBSacrifice SVar:DBSacrifice:DB$ Sacrifice | Cost$ 0 | Defined$ Self T:Mode$ SpellCast | ValidCard$ Card | TriggerZones$ Battlefield | Execute$ TrigFlipYouCast | TriggerDescription$ Whenever a player casts a spell, that player flips a coin. If he or she loses the flip, counter that spell. -SVar:TrigFlipYouCast:AB$ FlipACoin | Cost$ 0 | LoseSubAbility$ DBCounter | Caller$ TriggeredCardController +SVar:TrigFlipYouCast:AB$ FlipACoin | Cost$ 0 | LoseSubAbility$ DBCounter | Caller$ TriggeredActivator SVar:DBCounter:DB$ Counter | Cost$ 0 | Defined$ TriggeredSpellAbility SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/p/predator_ooze.txt b/res/cardsfolder/p/predator_ooze.txt index dfe1e6263aa..cc200ea25af 100644 --- a/res/cardsfolder/p/predator_ooze.txt +++ b/res/cardsfolder/p/predator_ooze.txt @@ -7,6 +7,7 @@ K:Indestructible K:Whenever a creature dealt damage by CARDNAME this turn is put into a graveyard, put a +1/+1 counter on CARDNAME. T:Mode$ Attacks | ValidCard$ Creature.Self | Execute$ TrigPutCounter | TriggerDescription$ Whenever CARDNAME attacks, put a +1/+1 counter on it. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/predator_ooze.jpg SetInfo:DKA|Rare|http://magiccards.info/scans/en/dka/124.jpg diff --git a/res/cardsfolder/p/predatory_hunger.txt b/res/cardsfolder/p/predatory_hunger.txt index 72ee52a5346..e0f23c128f5 100644 --- a/res/cardsfolder/p/predatory_hunger.txt +++ b/res/cardsfolder/p/predatory_hunger.txt @@ -4,7 +4,7 @@ Types:Enchantment Aura Text:no text K:Enchant creature A:SP$ Attach | Cost$ G | ValidTgts$ Creature | AILogic$ Pump -T:Mode$ SpellCast | ValidCard$ Creature.YouDontCtrl | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a creature spell, put a +1/+1 counter on enchanted creature. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ Opponent | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever an opponent casts a creature spell, put a +1/+1 counter on enchanted creature. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Enchanted | CounterType$ P1P1 | CounterNum$ 1 SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/predatory_hunger.jpg diff --git a/res/cardsfolder/p/presence_of_the_master.txt b/res/cardsfolder/p/presence_of_the_master.txt index 12e6dcf9a5b..4354cb662f1 100644 --- a/res/cardsfolder/p/presence_of_the_master.txt +++ b/res/cardsfolder/p/presence_of_the_master.txt @@ -2,7 +2,7 @@ Name:Presence of the Master ManaCost:3 W Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.Enchantment | TriggerZones$ Battlefield | Execute$ TrigCounter | TriggerDescription$ Whenever a player casts an enchantment spell, counter it. +T:Mode$ SpellCast | ValidCard$ Enchantment | TriggerZones$ Battlefield | Execute$ TrigCounter | TriggerDescription$ Whenever a player casts an enchantment spell, counter it. SVar:TrigCounter:AB$Counter | Cost$ 0 | Defined$ TriggeredSpellAbility SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/p/primeval_titan.txt b/res/cardsfolder/p/primeval_titan.txt index eaf7d2188db..7c7533fbf55 100644 --- a/res/cardsfolder/p/primeval_titan.txt +++ b/res/cardsfolder/p/primeval_titan.txt @@ -7,6 +7,7 @@ K:Trample T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may search your library for up to two land cards, put them onto the battlefield tapped, then shuffle your library. T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may search your library for up to two land cards, put them onto the battlefield tapped, then shuffle your library. SVar:TrigChange:AB$ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Battlefield | Tapped$ True | ChangeType$ Land | ChangeNum$ 2 +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/primeval_titan.jpg SetInfo:M11|Mythic|http://magiccards.info/scans/en/m11/192.jpg diff --git a/res/cardsfolder/p/primordial_sage.txt b/res/cardsfolder/p/primordial_sage.txt index 92c96438bc3..e8e0aa9098b 100644 --- a/res/cardsfolder/p/primordial_sage.txt +++ b/res/cardsfolder/p/primordial_sage.txt @@ -3,7 +3,7 @@ ManaCost:4 G G Types:Creature Spirit Text:no text PT:4/5 -T:Mode$ SpellCast | ValidCard$ Card.Creature+YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a creature spell, you may draw a card. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a creature spell, you may draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/primordial_sage.jpg diff --git a/res/cardsfolder/p/pristine_angel.txt b/res/cardsfolder/p/pristine_angel.txt index 3aa7b71a552..2cdfdf7422f 100644 --- a/res/cardsfolder/p/pristine_angel.txt +++ b/res/cardsfolder/p/pristine_angel.txt @@ -5,7 +5,7 @@ Text:no text PT:4/4 K:Flying S:Mode$ Continuous | Affected$ Card.Self+untapped | AddKeyword$ Protection from artifacts & Protection from white & Protection from blue & Protection from black & Protection from red & Protection from green | Description$ As long as CARDNAME is untapped, it has protection from artifacts and from all colors. -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a spell, you may untap CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a spell, you may untap CARDNAME. SVar:TrigUntap:AB$Untap | Cost$ 0 | Defined$ Self SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/pristine_angel.jpg diff --git a/res/cardsfolder/p/pulse_tracker.txt b/res/cardsfolder/p/pulse_tracker.txt index 9e218fffe32..d18cc89d6ef 100644 --- a/res/cardsfolder/p/pulse_tracker.txt +++ b/res/cardsfolder/p/pulse_tracker.txt @@ -5,6 +5,7 @@ Text:no text PT:1/1 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDrain | TriggerDescription$ Whenever CARDNAME attacks, each opponent loses 1 life. SVar:TrigDrain:AB$LoseLife | Cost$ 0 | Defined$ Opponent | LifeAmount$ 1 +SVar:HasAttackEffect:TRUE SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/pulse_tracker.jpg SetInfo:WWK|Common|http://magiccards.info/scans/en/wwk/62.jpg diff --git a/res/cardsfolder/p/pure_reflection.txt b/res/cardsfolder/p/pure_reflection.txt index 0ef95d1f865..75f96f5889c 100644 --- a/res/cardsfolder/p/pure_reflection.txt +++ b/res/cardsfolder/p/pure_reflection.txt @@ -4,7 +4,7 @@ Types:Enchantment Text:no text T:Mode$ SpellCast | ValidCard$ Creature | Execute$ TrigDestroy | ValidActivatingPlayer$ Player | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a creature spell, destroy all Reflections. Then that player puts an X/X white Reflection creature token onto the battlefield, where X is the converted mana cost of that spell. SVar:TrigDestroy:AB$ DestroyAll | Cost$ 0 | ValidCards$ Reflection | SubAbility$ DBToken | SpellDescription$ Destroy all Reflections -SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenPower$ X | TokenToughness$ X | TokenName$ Reflection | TokenTypes$ Creature,Reflection | TokenColors$ White | TokenOwner$ TriggeredCardController +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenPower$ X | TokenToughness$ X | TokenName$ Reflection | TokenTypes$ Creature,Reflection | TokenColors$ White | TokenOwner$ TriggeredActivator SVar:X:TriggeredCard$CardManaCost SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/pure_reflection.jpg diff --git a/res/cardsfolder/p/putrefaction.txt b/res/cardsfolder/p/putrefaction.txt index 77a674b625e..4d4f359ca25 100644 --- a/res/cardsfolder/p/putrefaction.txt +++ b/res/cardsfolder/p/putrefaction.txt @@ -3,7 +3,7 @@ ManaCost:4 B Types:Enchantment Text:no text T:Mode$ SpellCast | ValidCard$ Card.Green,Card.White | Execute$ TrigDiscard | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a green or white spell, that player discards a card. -SVar:TrigDiscard:AB$Discard | Cost$ 0 | Defined$ TriggeredCardController | NumCards$ 1 | Mode$ TgtChoose +SVar:TrigDiscard:AB$Discard | Cost$ 0 | Defined$ TriggeredActivator | NumCards$ 1 | Mode$ TgtChoose SVar:RemRandomDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/putrefaction.jpg diff --git a/res/cardsfolder/p/pyrostatic_pillar.txt b/res/cardsfolder/p/pyrostatic_pillar.txt index ae21407754d..7f8f43548bf 100644 --- a/res/cardsfolder/p/pyrostatic_pillar.txt +++ b/res/cardsfolder/p/pyrostatic_pillar.txt @@ -3,7 +3,7 @@ ManaCost:1 R Types:Enchantment Text:no text T:Mode$ SpellCast | ValidCard$ Card.cmcLE3 | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever a player casts a spell with converted mana cost 3 or less, CARDNAME deals 2 damage to that player. -SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Defined$ TriggeredCardController | NumDmg$ 2 +SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Defined$ TriggeredActivator | NumDmg$ 2 SVar:RemRandomDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/pyrostatic_pillar.jpg diff --git a/res/cardsfolder/q/quicken.txt b/res/cardsfolder/q/quicken.txt index a173ff6e7bd..ba548cc49ef 100644 --- a/res/cardsfolder/q/quicken.txt +++ b/res/cardsfolder/q/quicken.txt @@ -5,7 +5,7 @@ Text:no text A:SP$Effect | Cost$ U | Name$ Quicken effect | StaticAbilities$ QuickenStA | Triggers$ SpellCastTrig | SVars$ Quickened | SubAbility$ DBDraw | SpellDescription$ The next sorcery card you cast this turn can be cast as though it had flash. SVar:DBDraw:DB$Draw | NumCards$ 1 | SpellDescription$ Draw a card. SVar:QuickenStA:Mode$ Continuous | Affected$ Sorcery.YouCtrl | AffectedZone$ Hand,Graveyard,Exile | AddHiddenKeyword$ HIDDEN Flash -SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Sorcery | ValidControllingPlayer$ You | Execute$ Quickened | Static$ True | TriggerDescription$ The next sorcery card you cast this turn can be cast as though it had flash. +SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Sorcery | ValidActivatingPlayer$ You | Execute$ Quickened | Static$ True | TriggerDescription$ The next sorcery card you cast this turn can be cast as though it had flash. SVar:Quickened:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Graveyard SVar:RemAIDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/q/quill_slinger_boggart.txt b/res/cardsfolder/q/quill_slinger_boggart.txt index 94fb9c2a01d..9fdd8e77fe0 100644 --- a/res/cardsfolder/q/quill_slinger_boggart.txt +++ b/res/cardsfolder/q/quill_slinger_boggart.txt @@ -3,7 +3,7 @@ ManaCost:3 B Types:Creature Goblin Warrior Text:no text PT:3/2 -T:Mode$ SpellCast | ValidCard$ Card.Kithkin | TriggerZones$ Battlefield | Execute$ TrigLoseLife | OptionalDecider$ You | TriggerDescription$ Whenever a player casts a Kithkin spell, you may have target player lose 1 life. +T:Mode$ SpellCast | ValidCard$ Kithkin | TriggerZones$ Battlefield | Execute$ TrigLoseLife | OptionalDecider$ You | TriggerDescription$ Whenever a player casts a Kithkin spell, you may have target player lose 1 life. SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | ValidTgts$ Player | TgtPrompt$ Select a player | LifeAmount$ 1 SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/quill_slinger_boggart.jpg diff --git a/res/cardsfolder/q/quirion_dryad.txt b/res/cardsfolder/q/quirion_dryad.txt index 28578046354..2bc9267471f 100644 --- a/res/cardsfolder/q/quirion_dryad.txt +++ b/res/cardsfolder/q/quirion_dryad.txt @@ -3,7 +3,7 @@ ManaCost:1 G Types:Creature Dryad Text:no text PT:1/1 -T:Mode$ SpellCast | ValidCard$ Card.White+YouCtrl,Card.Blue+YouCtrl,Card.Black+YouCtrl,Card.Red+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a white, blue, black, or red spell, put a +1/+1 counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card.White,Card.Blue,Card.Black,Card.Red | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a white, blue, black, or red spell, put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 SVar:BuffedBy:Card.White,Card.Blue,Card.Black,Card.Red SVar:RemRandomDeck:True diff --git a/res/cardsfolder/r/rage_extractor.txt b/res/cardsfolder/r/rage_extractor.txt index e4cf0aaab0b..03b2462e0cc 100644 --- a/res/cardsfolder/r/rage_extractor.txt +++ b/res/cardsfolder/r/rage_extractor.txt @@ -2,7 +2,7 @@ Name:Rage Extractor ManaCost:4 PR Types:Artifact Text:no text -T:Mode$ SpellCast | ValidCard$ Card.CostsPhyrexianMana+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a spell with P in its mana cost, CARDNAME deals damage equal to that spell's converted mana cost to target creature or player. +T:Mode$ SpellCast | ValidCard$ Card.CostsPhyrexianMana | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ Whenever you cast a spell with P in its mana cost, CARDNAME deals damage equal to that spell's converted mana cost to target creature or player. SVar:TrigDealDamage:AB$DealDamage | Cost$ 0 | Tgt$ TgtCP | NumDmg$ X SVar:X:TriggeredCard$CardManaCost SVar:RemRandomDeck:True diff --git a/res/cardsfolder/r/recycle.txt b/res/cardsfolder/r/recycle.txt index 58b2369ff35..c15f9bcc027 100644 --- a/res/cardsfolder/r/recycle.txt +++ b/res/cardsfolder/r/recycle.txt @@ -4,7 +4,7 @@ Types:Enchantment Text:no text S:Mode$ Continuous | Affected$ You | AddKeyword$ Skip your draw step. | Description$ Skip your draw step. S:Mode$ Continuous | Affected$ You | SetMaxHandSize$ 2 | Description$ Your maximum hand size is 2. -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you play a card, draw a card. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you play a card, draw a card. T:Mode$ LandPlayed | ValidCard$ Land.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | Secondary$ True | TriggerDescription$ Whenever you play a card, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True diff --git a/res/cardsfolder/r/reki_the_history_of_kamigawa.txt b/res/cardsfolder/r/reki_the_history_of_kamigawa.txt index f90371e3c6d..c4b7191d489 100644 --- a/res/cardsfolder/r/reki_the_history_of_kamigawa.txt +++ b/res/cardsfolder/r/reki_the_history_of_kamigawa.txt @@ -3,7 +3,7 @@ ManaCost:2 G Types:Legendary Creature Human Shaman Text:no text PT:1/2 -T:Mode$ SpellCast | ValidCard$ Legendary.YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a legendary spell, draw a card. +T:Mode$ SpellCast | ValidCard$ Legendary | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a legendary spell, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/reki_the_history_of_kamigawa.jpg diff --git a/res/cardsfolder/r/reparations.txt b/res/cardsfolder/r/reparations.txt index 8cf7e25e1cb..98f7b431b99 100644 --- a/res/cardsfolder/r/reparations.txt +++ b/res/cardsfolder/r/reparations.txt @@ -2,7 +2,7 @@ Name:Reparations ManaCost:1 W U Types:Enchantment Text:no text -T:Mode$ SpellCast | TriggerZones$ Battlefield | ValidCard$ Spell.YouDontCtrl | TargetsValid$ You,Creature.YouCtrl | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a spell that targets you or a creature you control, you may draw a card. +T:Mode$ SpellCast | TriggerZones$ Battlefield | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TargetsValid$ You,Creature.YouCtrl | Execute$ TrigDraw | TriggerDescription$ Whenever an opponent casts a spell that targets you or a creature you control, you may draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | NumCards$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/reparations.jpg diff --git a/res/cardsfolder/r/rhystic_study.txt b/res/cardsfolder/r/rhystic_study.txt index 62c885ca3aa..64f1adf42d0 100644 --- a/res/cardsfolder/r/rhystic_study.txt +++ b/res/cardsfolder/r/rhystic_study.txt @@ -2,7 +2,7 @@ Name:Rhystic Study ManaCost:2 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a spell, you may draw a card unless that player pays 1. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a spell, you may draw a card unless that player pays 1. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | UnlessCost$ 1 | UnlessPayer$ TriggeredPlayer | NumCards$ 1 SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/rhystic_study.jpg diff --git a/res/cardsfolder/r/riddlesmith.txt b/res/cardsfolder/r/riddlesmith.txt index bd4fc4b7ba6..1df02062ac6 100644 --- a/res/cardsfolder/r/riddlesmith.txt +++ b/res/cardsfolder/r/riddlesmith.txt @@ -3,7 +3,7 @@ ManaCost:1 U Types:Creature Human Artificer Text:no text PT:2/1 -T:Mode$ SpellCast | ValidCard$ Artifact.YouCtrl | Execute$ TrigLoot | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may draw a card. If you do, discard a card. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigLoot | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, you may draw a card. If you do, discard a card. SVar:TrigLoot:AB$Draw | Cost$ 0 | NumCards$ 1 | SubAbility$ DBDiscard SVar:DBDiscard:DB$Discard | Defined$ You | Mode$ TgtChoose | NumCards$ 1 SVar:Rarity:Uncommon diff --git a/res/cardsfolder/r/ronin_cliffrider.txt b/res/cardsfolder/r/ronin_cliffrider.txt index 3092231dd62..1344fece836 100644 --- a/res/cardsfolder/r/ronin_cliffrider.txt +++ b/res/cardsfolder/r/ronin_cliffrider.txt @@ -6,6 +6,7 @@ PT:2/2 K:Bushido 1 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDamage | OptionalDecider$ You| TriggerDescription$ Whenever CARDNAME attacks, you may have it deal 1 damage to each creature defending player controls. SVar:TrigDamage:AB$DamageAll | Cost$ 0 | ValidCards$ Creature.YouDontCtrl | NumDmg$ 1| ValidDescription$ each creature defending player controls. +SVar:HasAttackEffect:TRUE SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/ronin_cliffrider.jpg SetInfo:BOK|Uncommon|http://magiccards.info/scans/en/bok/116.jpg diff --git a/res/cardsfolder/s/safehold_duo.txt b/res/cardsfolder/s/safehold_duo.txt index f595eb2695b..6c9bb3adfb9 100644 --- a/res/cardsfolder/s/safehold_duo.txt +++ b/res/cardsfolder/s/safehold_duo.txt @@ -3,8 +3,8 @@ ManaCost:3 GW Types:Creature Elf Warrior Shaman Text:no text PT:2/4 -T:Mode$ SpellCast | ValidCard$ Card.Green+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a green spell, CARDNAME gets +1/+1 until end of turn. -T:Mode$ SpellCast | ValidCard$ Card.White+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPumpKW | TriggerDescription$ Whenever you cast a white spell, CARDNAME gains vigilance until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.Green | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a green spell, CARDNAME gets +1/+1 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPumpKW | TriggerDescription$ Whenever you cast a white spell, CARDNAME gains vigilance until end of turn. SVar:TrigPump11:AB$Pump | Cost$ 0 | NumAtt$ +1 | NumDef$ +1 | Defined$ Self SVar:TrigPumpKW:AB$Pump | Cost$ 0 | KW$ Vigilance | Defined$ Self SVar:BuffedBy:Card.Green,Card.White diff --git a/res/cardsfolder/s/sandstorm_eidolon.txt b/res/cardsfolder/s/sandstorm_eidolon.txt index ff30dbd5e6e..34fcf1c2ed9 100644 --- a/res/cardsfolder/s/sandstorm_eidolon.txt +++ b/res/cardsfolder/s/sandstorm_eidolon.txt @@ -4,7 +4,7 @@ Types:Creature Spirit Text:no text PT:2/2 A:AB$ Pump | Cost$ R Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | KW$ HIDDEN CARDNAME can't block. | IsCurse$ True | SpellDescription$ Target creature can't block this turn. -T:Mode$ SpellCast | ValidCard$ Card.MultiColor+YouCtrl | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Hand | Defined$ Self SVar:RemAIDeck:True SVar:Rarity:Common diff --git a/res/cardsfolder/s/scalding_salamander.txt b/res/cardsfolder/s/scalding_salamander.txt index 486366e72bb..7822870fbfe 100644 --- a/res/cardsfolder/s/scalding_salamander.txt +++ b/res/cardsfolder/s/scalding_salamander.txt @@ -5,6 +5,7 @@ Text:no text PT:2/1 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may have it deal 1 damage to each creature without flying defending player controls. SVar:TrigDamage:AB$DamageAll | Cost$ 0 | NumDmg$ 1 | ValidCards$ Creature.withoutFlying+YouDontCtrl +SVar:HasAttackEffect:TRUE SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/scalding_salamander.jpg SetInfo:EXO|Uncommon|http://magiccards.info/scans/en/ex/100.jpg diff --git a/res/cardsfolder/s/scouts_warning.txt b/res/cardsfolder/s/scouts_warning.txt index b8aaacfc961..355e35858ca 100644 --- a/res/cardsfolder/s/scouts_warning.txt +++ b/res/cardsfolder/s/scouts_warning.txt @@ -5,7 +5,7 @@ Text:no text A:SP$Effect | Cost$ W | Name$ Scout's Warning effect | StaticAbilities$ ScoutFlash | Triggers$ SpellCastTrig | SVars$ WarningGiven | SubAbility$ DBDraw | SpellDescription$ The next creature card you play this turn can be played as though it had flash. SVar:DBDraw:DB$Draw | NumCards$ 1 | SpellDescription$ Draw a card. SVar:ScoutFlash:Mode$ Continuous | Affected$ Creature.YouCtrl | AffectedZone$ Hand,Graveyard,Exile | AddHiddenKeyword$ HIDDEN Flash -SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Creature | ValidControllingPlayer$ You | Execute$ WarningGiven | Static$ True | TriggerDescription$ The next creature card you play this turn can be played as though it had flash. +SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ WarningGiven | Static$ True | TriggerDescription$ The next creature card you play this turn can be played as though it had flash. SVar:WarningGiven:DB$ ChangeZone | Defined$ Self | Origin$ Battlefield | Destination$ Graveyard SVar:RemAIDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/s/scroll_of_origins.txt b/res/cardsfolder/s/scroll_of_origins.txt index 214bb2f14f5..585312e4f70 100644 --- a/res/cardsfolder/s/scroll_of_origins.txt +++ b/res/cardsfolder/s/scroll_of_origins.txt @@ -3,6 +3,7 @@ ManaCost:2 Types:Artifact Text:no text A:AB$ Draw | Cost$ 2 T | NumCards$ 1 | ConditionCardsInHand$ 7 | SpellDescription$ Draw a card if you have seven or more cards in hand. +SVar:RemAIDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/scroll_of_origins.jpg SetInfo:SOK|Rare|http://magiccards.info/scans/en/sok/159.jpg diff --git a/res/cardsfolder/s/secrets_of_the_dead.txt b/res/cardsfolder/s/secrets_of_the_dead.txt index 4fee1888f13..736765c31da 100644 --- a/res/cardsfolder/s/secrets_of_the_dead.txt +++ b/res/cardsfolder/s/secrets_of_the_dead.txt @@ -2,7 +2,7 @@ Name:Secrets of the Dead ManaCost:2 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouOwn+wasCastFromGraveyard | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell from your graveyard, draw a card. +T:Mode$ SpellCast | ValidCard$ Card.wasCastFromGraveyard | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell from your graveyard, draw a card. SVar:TrigDraw:AB$ Draw | Cost$ 0| Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/s/sedge_sliver.txt b/res/cardsfolder/s/sedge_sliver.txt new file mode 100644 index 00000000000..d8109c002a6 --- /dev/null +++ b/res/cardsfolder/s/sedge_sliver.txt @@ -0,0 +1,18 @@ +Name:Sedge Sliver +ManaCost:2 R +Types:Creature Sliver +Text:no text +PT:2/2 +S:Mode$ Continuous | Affected$ Creature.Sliver+YouCtrl | AddPower$ 1 | AddToughness$ 1 | CheckSVar$ X | SVarCompare$ GE1 | Description$ All Sliver creatures have "This creature gets +1/+1 as long as you control a Swamp." +S:Mode$ Continuous | Affected$ Creature.Sliver+YouDontCtrl | AddPower$ 1 | AddToughness$ 1 | CheckSVar$ Y | SVarCompare$ GE1 | Secondary$ True | Description$ All Sliver creatures have "This creature gets +1/+1 as long as you control a Swamp." +S:Mode$ Continuous | Affected$ Sliver | AddAbility$ Pump | Description$ All Slivers have "B: Regenerate this permanent." +SVar:Pump:AB$Regenerate | Cost$ B | SpellDescription$ Regenerate CARDNAME. +SVar:X:Count$Valid Swamp.YouCtrl +SVar:Y:Count$Valid Swamp.YouDontCtrl +SVar:PlayMain1:TRUE +SVar:RemRandomDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/sedge_sliver.jpg +SetInfo:TSP|Rare|http://magiccards.info/scans/en/ts/177.jpg +Oracle:All Sliver creatures have "This creature gets +1/+1 as long as you control a Swamp."\nAll Slivers have "{B}: Regenerate this permanent." +End \ No newline at end of file diff --git a/res/cardsfolder/s/shelldock_isle.txt b/res/cardsfolder/s/shelldock_isle.txt new file mode 100644 index 00000000000..741bc5cfd4e --- /dev/null +++ b/res/cardsfolder/s/shelldock_isle.txt @@ -0,0 +1,17 @@ +Name:Shelldock Isle +ManaCost:no cost +Types:Land +Text:no text +K:Hideaway +T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library. +SVar:TrigDig:AB$ Dig | Cost$ 0 | Defined$ You | DigNum$ 4 | DestinationZone$ Exile | ExileFaceDown$ True | RememberChanged$ True +A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add U to your mana pool. +A:AB$ Play | Cost$ U T | Defined$ Remembered | Controller$ You | WithoutManaCost$ True | Optional$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ LEY | ForgetRemembered$ True | SpellDescription$ You may play the exiled card without paying its mana cost if a library has twenty or fewer cards in it. +SVar:Y:Number$20 +SVar:X:Count$LowestLibrary +SVar:RemRandomDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/shelldock_isle.jpg +SetInfo:LRW|Rare|http://magiccards.info/scans/en/lw/272.jpg +Oracle:Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.)\n{T}: Add {U} to your mana pool.\n{U}, {T}: You may play the exiled card without paying its mana cost if a library has twenty or fewer cards in it. +End \ No newline at end of file diff --git a/res/cardsfolder/s/shrieking_specter.txt b/res/cardsfolder/s/shrieking_specter.txt index b652dc024d6..633d1b2657e 100644 --- a/res/cardsfolder/s/shrieking_specter.txt +++ b/res/cardsfolder/s/shrieking_specter.txt @@ -6,6 +6,7 @@ PT:2/2 K:Flying T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDiscard | TriggerDescription$ Whenever CARDNAME attacks, defending player discards a card. SVar:TrigDiscard:AB$Discard | Cost$ 0 | Defined$ Opponent | NumCards$ 1 | Mode$ TgtChoose +SVar:HasAttackEffect:TRUE SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/shrieking_specter.jpg SetInfo:S99|Uncommon|http://magiccards.info/scans/en/st/89.jpg diff --git a/res/cardsfolder/s/sigil_of_the_empty_throne.txt b/res/cardsfolder/s/sigil_of_the_empty_throne.txt index 96a82c292eb..a4dc128b083 100644 --- a/res/cardsfolder/s/sigil_of_the_empty_throne.txt +++ b/res/cardsfolder/s/sigil_of_the_empty_throne.txt @@ -2,7 +2,7 @@ Name:Sigil of the Empty Throne ManaCost:3 W W Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Enchantment.YouCtrl | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an enchantment spell, put a 4/4 white Angel creature token with flying onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Enchantment | ValidActivatingPlayer$ You | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an enchantment spell, put a 4/4 white Angel creature token with flying onto the battlefield. SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Angel | TokenTypes$ Creature,Angel | TokenOwner$ You | TokenColors$ White | TokenPower$ 4 | TokenToughness$ 4 | TokenKeywords$ Flying SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/sigil_of_the_empty_throne.jpg diff --git a/res/cardsfolder/s/skittering_horror.txt b/res/cardsfolder/s/skittering_horror.txt index 4aa66b96aef..7b6c4bea182 100644 --- a/res/cardsfolder/s/skittering_horror.txt +++ b/res/cardsfolder/s/skittering_horror.txt @@ -3,9 +3,9 @@ ManaCost:2 B Types:Creature Horror Text:no text PT:4/3 -T:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When you cast a creature spell, sacrifice CARDNAME. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When you cast a creature spell, sacrifice CARDNAME. SVar:TrigSac:AB$ Sacrifice | Cost$ 0 | Defined$ Self -SVar:RemRandomDeck:True +SVar:RemAIDeck:True SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/skittering_horror.jpg SetInfo:UDS|Common|http://magiccards.info/scans/en/ud/70.jpg diff --git a/res/cardsfolder/s/skittering_monstrosity.txt b/res/cardsfolder/s/skittering_monstrosity.txt index f31e798a102..f21fbec8bc3 100644 --- a/res/cardsfolder/s/skittering_monstrosity.txt +++ b/res/cardsfolder/s/skittering_monstrosity.txt @@ -3,7 +3,7 @@ ManaCost:3 B B Types:Creature Horror Text:no text PT:5/5 -T:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When you cast a creature spell, sacrifice CARDNAME. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When you cast a creature spell, sacrifice CARDNAME. SVar:TrigSac:AB$Sacrifice | Cost$ 0 | Defined$ Self SVar:RemAIDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/s/skittering_skirge.txt b/res/cardsfolder/s/skittering_skirge.txt index e6a1ab7f6cd..19a29c21925 100644 --- a/res/cardsfolder/s/skittering_skirge.txt +++ b/res/cardsfolder/s/skittering_skirge.txt @@ -4,7 +4,7 @@ Types:Creature Imp Text:no text PT:3/2 K:Flying -T:Mode$ SpellCast | ValidCard$ Creature.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSacrifice | TriggerDescription$ When you cast a creature spell, sacrifice CARDNAME. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSacrifice | TriggerDescription$ When you cast a creature spell, sacrifice CARDNAME. SVar:TrigSacrifice:AB$Sacrifice | Cost$ 0 SVar:RemAIDeck:True SVar:Rarity:Common diff --git a/res/cardsfolder/s/skull_collector.txt b/res/cardsfolder/s/skull_collector.txt index 306e1709d89..543fccb5861 100644 --- a/res/cardsfolder/s/skull_collector.txt +++ b/res/cardsfolder/s/skull_collector.txt @@ -5,8 +5,8 @@ Text:no text PT:3/3 A:AB$ Regenerate | Cost$ 1 B | SpellDescription$ Regenerate CARDNAME. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, return a black creature you control to its owner's hand. -SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target black creature | Mandatory$ True | ValidTgts$ Creature.Black+YouCtrl -SVar:RemRandomDeck:True +SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target black creature | Mandatory$ True | Hidden$ True | ValidTgts$ Creature.Black+YouCtrl +SVar:RemAIDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/skull_collector.jpg SetInfo:SOK|Uncommon|http://magiccards.info/scans/en/sok/90.jpg diff --git a/res/cardsfolder/s/sludge_strider.txt b/res/cardsfolder/s/sludge_strider.txt index 18135719f3f..7047528bd44 100644 --- a/res/cardsfolder/s/sludge_strider.txt +++ b/res/cardsfolder/s/sludge_strider.txt @@ -4,7 +4,7 @@ Types:Artifact Creature Insect Text:no text PT:3/3 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Artifact.Other+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigLoseLife | TriggerDescription$ Whenever another artifact enters the battlefield under your control or another artifact you control leaves the battlefield, you may pay 1. If you do, target player loses 1 life and you gain 1 life. -T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Artifact.Other+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Secondary$ True | Execute$ TrigLoseLife | TriggerDescription$ Whenever another artifact enters the battlefield under your control or another artifact you control leaves the battlefield, you may pay 1. If you do, target player loses 1 life and you gain 1 life. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Artifact.Other+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Secondary$ True | Execute$ TrigLoseLife | TriggerDescription$ Whenever another artifact enters the battlefield under your control or another artifact you control leaves the battlefield, you may pay 1. If you do, target player loses 1 life and you gain 1 life. SVar:TrigLoseLife:AB$LoseLife | Cost$ 1 | ValidTgts$ Player | TgtPrompt$ Select target player | LifeAmount$ 1 | SubAbility$ DBGainLife SVar:DBGainLife:DB$GainLife | Cost$ 0 | LifeAmount$ 1 SVar:Picture:http://www.wizards.com/global/images/magic/general/sludge_strider.jpg diff --git a/res/cardsfolder/s/snake_pit.txt b/res/cardsfolder/s/snake_pit.txt index bc5464509fd..a4c72b831ee 100644 --- a/res/cardsfolder/s/snake_pit.txt +++ b/res/cardsfolder/s/snake_pit.txt @@ -2,7 +2,7 @@ Name:Snake Pit ManaCost:2 G Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.Blue+YouDontCtrl,Card.Black+YouDontCtrl | Execute$ TrigToken | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a blue or black spell, you may put a 1/1 green Snake creature token onto the battlefield. +T:Mode$ SpellCast | ValidCard$ Card.Blue,Card.Black | ValidActivatingPlayer$ Opponent | Execute$ TrigToken | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a blue or black spell, you may put a 1/1 green Snake creature token onto the battlefield. SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Snake | TokenTypes$ Creature,Snake | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/snake_pit.jpg diff --git a/res/cardsfolder/s/soot_imp.txt b/res/cardsfolder/s/soot_imp.txt index 350d404febe..030ab43c63a 100644 --- a/res/cardsfolder/s/soot_imp.txt +++ b/res/cardsfolder/s/soot_imp.txt @@ -5,7 +5,7 @@ Text:no text PT:1/2 K:Flying T:Mode$ SpellCast | ValidCard$ Card.nonBlack | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Whenever a player casts a nonblack spell, that player loses 1 life. -SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | Defined$ TriggeredCardController | LifeAmount$ 1 +SVar:TrigLoseLife:AB$LoseLife | Cost$ 0 | Defined$ TriggeredActivator | LifeAmount$ 1 SVar:RemRandomDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/soot_imp.jpg diff --git a/res/cardsfolder/s/soul_barrier.txt b/res/cardsfolder/s/soul_barrier.txt index b2951a361c9..05c4a2d47a5 100644 --- a/res/cardsfolder/s/soul_barrier.txt +++ b/res/cardsfolder/s/soul_barrier.txt @@ -2,7 +2,7 @@ Name:Soul Barrier ManaCost:2 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Creature | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a creature spell, Soul Barrier deals 2 damage to that player unless he or she pays 2. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDamage | OptionalDecider$ You | TriggerDescription$ Whenever an opponent casts a creature spell, Soul Barrier deals 2 damage to that player unless he or she pays 2. SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Defined$ TriggeredCardController | UnlessCost$ 2 | UnlessPayer$ TriggeredPlayer | NumDmg$ 2 SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/soul_barrier.jpg diff --git a/res/cardsfolder/s/spellshock.txt b/res/cardsfolder/s/spellshock.txt index 2da401b0201..b1ddb588240 100644 --- a/res/cardsfolder/s/spellshock.txt +++ b/res/cardsfolder/s/spellshock.txt @@ -2,10 +2,9 @@ Name:Spellshock ManaCost:2 R Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | Execute$ TrigDamageYou | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a spell, CARDNAME deals 2 damage to that player. -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | Execute$ TrigDamageOpp | TriggerZones$ Battlefield | Secondary$ True | TriggerDescription$ Whenever a player casts a spell, CARDNAME deals 2 damage to that player. -SVar:TrigDamageYou:AB$DealDamage | Cost$ 0 | Defined$ You | NumDmg$ 2 -SVar:TrigDamageOpp:AB$DealDamage | Cost$ 0 | Defined$ Opponent | NumDmg$ 2 +T:Mode$ SpellCast | ValidCard$ Card | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a spell, CARDNAME deals 2 damage to that player. +SVar:TrigDamage:AB$DealDamage | Cost$ 0 | Defined$ TriggeredActivator | NumDmg$ 2 +SVar:RemAIDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/spellshock.jpg SetInfo:EXO|Uncommon|http://magiccards.info/scans/en/ex/104.jpg diff --git a/res/cardsfolder/s/sphinx_bone_wand.txt b/res/cardsfolder/s/sphinx_bone_wand.txt index 0012cd94513..00ff47f42f6 100644 --- a/res/cardsfolder/s/sphinx_bone_wand.txt +++ b/res/cardsfolder/s/sphinx_bone_wand.txt @@ -2,7 +2,7 @@ Name:Sphinx-Bone Wand ManaCost:7 Types:Artifact Text:no text -T:Mode$ SpellCast | ValidCard$ Instant.YouCtrl,Sorcery.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerDescription$ Whenever you cast an instant or sorcery spell, you may put a charge counter on CARDNAME. If you do, CARDNAME deals damage equal to the number of charge counters on it to target creature or player. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPutCounter | OptionalDecider$ You | TriggerDescription$ Whenever you cast an instant or sorcery spell, you may put a charge counter on CARDNAME. If you do, CARDNAME deals damage equal to the number of charge counters on it to target creature or player. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ CHARGE | CounterNum$ 1 | SubAbility$ DBDealDamage SVar:DBDealDamage:DB$DealDamage | Tgt$ TgtCP | NumDmg$ X SVar:X:Count$CardCounters.CHARGE diff --git a/res/cardsfolder/s/spinerock_knoll.txt b/res/cardsfolder/s/spinerock_knoll.txt new file mode 100644 index 00000000000..e92288c9036 --- /dev/null +++ b/res/cardsfolder/s/spinerock_knoll.txt @@ -0,0 +1,16 @@ +Name:Spinerock Knoll +ManaCost:no cost +Types:Land +Text:no text +K:Hideaway +T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library. +SVar:TrigDig:AB$ Dig | Cost$ 0 | Defined$ You | DigNum$ 4 | DestinationZone$ Exile | ExileFaceDown$ True | RememberChanged$ True +A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add R to your mana pool. +A:AB$ Play | Cost$ R T | Defined$ Remembered | Controller$ You | WithoutManaCost$ True | Optional$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GE7 | ForgetRemembered$ True | SpellDescription$ You may play the exiled card without paying its mana cost if an opponent was dealt 7 or more damage this turn. +SVar:X:Count$OppDamageThisTurn +SVar:RemRandomDeck:True +SVar:Rarity:Rare +SVar:Picture:http://www.wizards.com/global/images/magic/general/spinerock_knoll.jpg +SetInfo:LRW|Rare|http://magiccards.info/scans/en/lw/274.jpg +Oracle:Hideaway (This land enters the battlefield tapped. When it does, look at the top four cards of your library, exile one face down, then put the rest on the bottom of your library.)\n{T}: Add {R} to your mana pool.\n{R}, {T}: You may play the exiled card without paying its mana cost if an opponent was dealt 7 or more damage this turn. +End \ No newline at end of file diff --git a/res/cardsfolder/s/stampeding_wildebeests.txt b/res/cardsfolder/s/stampeding_wildebeests.txt index 7fc9429af1e..0d62e2c7cfb 100644 --- a/res/cardsfolder/s/stampeding_wildebeests.txt +++ b/res/cardsfolder/s/stampeding_wildebeests.txt @@ -6,7 +6,7 @@ PT:5/4 K:Trample T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigBounce | TriggerDescription$ At the beginning of your upkeep, return a green creature you control to its owner's hand. SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | ChangeType$ Creature.Green+YouCtrl | ChangeNum$ 1 | Origin$ Battlefield | Destination$ Hand | Mandatory$ True | Hidden$ True -SVar:RemRandomDeck:True +SVar:RemAIDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/stampeding_wildebeests.jpg SetInfo:VIS|Uncommon|http://magiccards.info/scans/en/vi/71.jpg diff --git a/res/cardsfolder/s/standstill.txt b/res/cardsfolder/s/standstill.txt index f64a4d37b2b..47c8f6b81a3 100644 --- a/res/cardsfolder/s/standstill.txt +++ b/res/cardsfolder/s/standstill.txt @@ -2,8 +2,8 @@ Name:Standstill ManaCost:1 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidControllingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSacYou | TriggerDescription$ When a player casts a spell, sacrifice CARDNAME. If you do, each of that player's opponents draws three cards. -T:Mode$ SpellCast | ValidControllingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigSacOpp | Secondary$ True | TriggerDescription$ When a player casts a spell, sacrifice CARDNAME. If you do, each of that player's opponents draws three cards. +T:Mode$ SpellCast | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigSacYou | TriggerDescription$ When a player casts a spell, sacrifice CARDNAME. If you do, each of that player's opponents draws three cards. +T:Mode$ SpellCast | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigSacOpp | Secondary$ True | TriggerDescription$ When a player casts a spell, sacrifice CARDNAME. If you do, each of that player's opponents draws three cards. #Must use SacrificeAll since regular sacrifice can't remember the sac'd cards atm. SVar:TrigSacYou:AB$SacrificeAll | Cost$ 0 | ValidCards$ Card.Self | RememberSacrificed$ True | SubAbility$ DrawOpp SVar:TrigSacOpp:AB$SacrificeAll | Cost$ 0 | ValidCards$ Card.Self | RememberSacrificed$ True | SubAbility$ DrawYou diff --git a/res/cardsfolder/s/straw_golem.txt b/res/cardsfolder/s/straw_golem.txt index 9078e3cfd08..ea1d23578ea 100644 --- a/res/cardsfolder/s/straw_golem.txt +++ b/res/cardsfolder/s/straw_golem.txt @@ -3,8 +3,9 @@ ManaCost:1 Types:Artifact Creature Golem Text:no text PT:2/3 -T:Mode$ SpellCast | ValidCard$ Creature.YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigSacrifice | TriggerDescription$ When an opponent casts a creature spell, sacrifice CARDNAME. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigSacrifice | TriggerDescription$ When an opponent casts a creature spell, sacrifice CARDNAME. SVar:TrigSacrifice:AB$Sacrifice | Cost$ 0 | Defined$ Self +SVar:AntiBuffedBy:Creature SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/straw_golem.jpg SetInfo:WTH|Uncommon|http://magiccards.info/scans/en/wl/158.jpg diff --git a/res/cardsfolder/s/sun_titan.txt b/res/cardsfolder/s/sun_titan.txt index 7519ba00c16..1150adc98d4 100644 --- a/res/cardsfolder/s/sun_titan.txt +++ b/res/cardsfolder/s/sun_titan.txt @@ -7,6 +7,7 @@ K:Vigilance T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChange | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME enters the battlefield, you may return target permanent card with converted mana cost 3 or less from your graveyard to the battlefield. T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may return target permanent card with converted mana cost 3 or less from your graveyard to the battlefield. SVar:TrigChange:AB$ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Permanent.YouCtrl+cmcLE3 | Cost$ 0 +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/sun_titan.jpg SetInfo:M11|Mythic|http://magiccards.info/scans/en/m11/35.jpg diff --git a/res/cardsfolder/s/surrakar_spellblade.txt b/res/cardsfolder/s/surrakar_spellblade.txt index 066fbe566a6..1f7b1adb9e4 100644 --- a/res/cardsfolder/s/surrakar_spellblade.txt +++ b/res/cardsfolder/s/surrakar_spellblade.txt @@ -3,7 +3,7 @@ ManaCost:1 U U Types:Creature Surrakar Text:no text PT:2/1 -T:Mode$ SpellCast | ValidCard$ Instant.YouCtrl,Sorcery.YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a instant or sorcery spell, you may put a charge counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a instant or sorcery spell, you may put a charge counter on CARDNAME. T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | CombatDamage$ True | OptionalDecider$ You | Execute$ TrigDraw | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may draw X cards, where X is the number of charge counters on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ CHARGE | CounterNum$ 1 SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ X diff --git a/res/cardsfolder/t/tamiyo_the_moon_sage.txt b/res/cardsfolder/t/tamiyo_the_moon_sage.txt index 8f56ac563f5..96b65b8c77f 100644 --- a/res/cardsfolder/t/tamiyo_the_moon_sage.txt +++ b/res/cardsfolder/t/tamiyo_the_moon_sage.txt @@ -7,7 +7,7 @@ A:AB$ Tap | Cost$ AddCounter<1/LOYALTY> | ValidTgts$ Permanent | TgtPrompt$ Choo SVar:TamiyoPump:DB$Pump | Defined$ Targeted | Permanent$ True | KW$ HIDDEN This card doesn't untap during your next untap step. A:AB$ Draw | Cost$ SubCounter<2/LOYALTY> | ValidTgts$ Player | TgtPrompt$ Select target player | Defined$ You | NumCards$ X | Planeswalker$ True | SpellDescription$ Draw a card for each tapped creature target player controls. SVar:X:Count$Valid Creature.tapped+TargetedPlayerCtrl -A:AB$ Effect | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Tamiyo, the Moon Sage emblem | Image$ tamiyo_moon_sage_emblem | StaticAbilities$ UnlimitedHand | Triggers$ TamiyoCardToGrave | SVars$ TamiyoReturn | Stackable$ False | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "You have no maximum hand size" and "Whenever a card is put into your graveyard from anywhere, you may return it to your hand." +A:AB$ Effect | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Tamiyo, the Moon Sage emblem | Image$ tamiyo_the_moon_sage_emblem | StaticAbilities$ UnlimitedHand | Triggers$ TamiyoCardToGrave | SVars$ TamiyoReturn | Stackable$ False | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "You have no maximum hand size" and "Whenever a card is put into your graveyard from anywhere, you may return it to your hand." SVar:UnlimitedHand:Mode$ Continuous | Affected$ You | SetMaxHandSize$ -1 | Description$ You have no maximum hand size. SVar:TamiyoCardToGrave:Mode$ ChangesZone | Origin$ Any | Destination$ Graveyard | ValidCard$ Card.nonToken+YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TamiyoReturn | TriggerDescription$ Whenever a card is put into your graveyard from anywhere, you may return it to your hand. SVar:TamiyoReturn:AB$ChangeZone | Cost$ 0 | Defined$ TriggeredCard | Origin$ Graveyard | Destination$ Hand diff --git a/res/cardsfolder/t/tangleroot.txt b/res/cardsfolder/t/tangleroot.txt index a57da0887e3..4721d24a620 100644 --- a/res/cardsfolder/t/tangleroot.txt +++ b/res/cardsfolder/t/tangleroot.txt @@ -3,7 +3,7 @@ ManaCost:3 Types:Artifact Text:no text T:Mode$ SpellCast | ValidCard$ Creature | Execute$ TrigMana | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a creature spell, that player adds G to his or her mana pool. -SVar:TrigMana:AB$Mana | Cost$ 0 | Produced$ G | Amount$ 1 | Defined$ TriggeredPlayer +SVar:TrigMana:AB$Mana | Cost$ 0 | Produced$ G | Amount$ 1 | Defined$ TriggeredActivator SVar:RemRandomDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/tangleroot.jpg diff --git a/res/cardsfolder/t/tattermunge_duo.txt b/res/cardsfolder/t/tattermunge_duo.txt index 1362a493a73..c344b26a490 100644 --- a/res/cardsfolder/t/tattermunge_duo.txt +++ b/res/cardsfolder/t/tattermunge_duo.txt @@ -3,8 +3,8 @@ ManaCost:2 RG Types:Creature Goblin Warrior Shaman Text:no text PT:2/3 -T:Mode$ SpellCast | ValidCard$ Card.Red+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a red spell, CARDNAME gets +1/+1 until end of turn. -T:Mode$ SpellCast | ValidCard$ Card.Green+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPumpKW | TriggerDescription$ Whenever you cast a green spell, CARDNAME gains forestwalk until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.Red | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a red spell, CARDNAME gets +1/+1 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.Green | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPumpKW | TriggerDescription$ Whenever you cast a green spell, CARDNAME gains forestwalk until end of turn. SVar:TrigPump11:AB$Pump | Cost$ 0 | NumAtt$ +1 | NumDef$ +1 | Defined$ Self SVar:TrigPumpKW:AB$Pump | Cost$ 0 | KW$ Forestwalk | Defined$ Self SVar:BuffedBy:Card.Red,Card.Green diff --git a/res/cardsfolder/t/taurean_mauler.txt b/res/cardsfolder/t/taurean_mauler.txt index 424bb4959eb..b4c9ed183b0 100644 --- a/res/cardsfolder/t/taurean_mauler.txt +++ b/res/cardsfolder/t/taurean_mauler.txt @@ -4,7 +4,7 @@ Types:Creature Shapeshifter Text:no text PT:2/2 S:Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | CharacteristicDefining$ True | AddType$ AllCreatureTypes | Description$ Changeling (This card is every creature type at all times.) -T:Mode$ SpellCast | ValidCard$ Card.YouDontCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts a spell, you may put a +1/+1 counter on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever an opponent casts a spell, you may put a +1/+1 counter on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/taurean_mauler.jpg diff --git a/res/cardsfolder/t/thatcher_revolt.txt b/res/cardsfolder/t/thatcher_revolt.txt index 14f3c0db9d1..4c0b44f87ef 100644 --- a/res/cardsfolder/t/thatcher_revolt.txt +++ b/res/cardsfolder/t/thatcher_revolt.txt @@ -2,7 +2,7 @@ Name:Thatcher Revolt ManaCost:2 R Types:Sorcery Text:no text -A:SP$ Token | Cost$ 2 R | TokenAmount$ 3 | TokenName$ Human | TokenTypes$ Creature,Human | TokenOwner$ You | TokenColors$ Red | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Haste<>At the beginning of the end step, sacrifice CARDNAME. | SpellDescription$ Put three 1/1 red Human creature tokens with haste onto the battlefield. Sacrifice those tokens at the beginning of the next end step. +A:SP$ Token | Cost$ 2 R | TokenAmount$ 3 | TokenName$ Human | TokenTypes$ Creature,Human | TokenOwner$ You | TokenColors$ Red | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Haste<>At the beginning of the end step, sacrifice CARDNAME. | TokenImage$ r 1 1 human avr | SpellDescription$ Put three 1/1 red Human creature tokens with haste onto the battlefield. Sacrifice those tokens at the beginning of the next end step. SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/thatcher_revolt.jpg SetInfo:AVR|Common|http://magiccards.info/scans/en/avr/158.jpg diff --git a/res/cardsfolder/t/thistledown_duo.txt b/res/cardsfolder/t/thistledown_duo.txt index 1ecd2d52898..0c621535d0b 100644 --- a/res/cardsfolder/t/thistledown_duo.txt +++ b/res/cardsfolder/t/thistledown_duo.txt @@ -3,8 +3,8 @@ ManaCost:2 WU Types:Creature Kithkin Soldier Wizard Text:no text PT:2/2 -T:Mode$ SpellCast | ValidCard$ Card.White+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a white spell, CARDNAME gets +1/+1 until end of turn. -T:Mode$ SpellCast | ValidCard$ Card.Blue+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPumpKW | TriggerDescription$ Whenever you cast a blue spell, CARDNAME gains flying until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump11 | TriggerDescription$ Whenever you cast a white spell, CARDNAME gets +1/+1 until end of turn. +T:Mode$ SpellCast | ValidCard$ Card.Blue | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPumpKW | TriggerDescription$ Whenever you cast a blue spell, CARDNAME gains flying until end of turn. SVar:TrigPump11:AB$Pump | Cost$ 0 | NumAtt$ +1 | NumDef$ +1 | Defined$ Self SVar:TrigPumpKW:AB$Pump | Cost$ 0 | KW$ Flying | Defined$ Self SVar:BuffedBy:Card.White,Card.Blue diff --git a/res/cardsfolder/t/thorntooth_witch.txt b/res/cardsfolder/t/thorntooth_witch.txt index 36923428588..7142c1f96eb 100644 --- a/res/cardsfolder/t/thorntooth_witch.txt +++ b/res/cardsfolder/t/thorntooth_witch.txt @@ -3,7 +3,7 @@ ManaCost:5 B Types:Creature Treefolk Shaman Text:no text PT:3/4 -T:Mode$ SpellCast | ValidCard$ Treefolk.Other+YouCtrl | OptionalDecider$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a Treefolk spell, you may have target creature get +3/-3 until end of turn. +T:Mode$ SpellCast | ValidCard$ Treefolk | ValidActivatingPlayer$ You | OptionalDecider$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast a Treefolk spell, you may have target creature get +3/-3 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 3 | NumDef$ -3 | IsCurse$ True SVar:RemAIDeck:True SVar:Rarity:Uncommon diff --git a/res/cardsfolder/t/thought_prison.txt b/res/cardsfolder/t/thought_prison.txt index 8a490215840..ac14415944d 100644 --- a/res/cardsfolder/t/thought_prison.txt +++ b/res/cardsfolder/t/thought_prison.txt @@ -5,7 +5,7 @@ Text:no text T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigChangeZone | OptionalDecider$ You | TriggerDescription$ Imprint - When CARDNAME enters the battlefield, you may have target player reveal his or her hand. If you do, choose a nonland card from it and exile that card. SVar:TrigChangeZone:AB$ ChangeZone | Cost$ 0 | Origin$ Hand | Destination$ Exile | ChangeType$ Card.nonLand | ChangeNum$ 1 | ValidTgts$ Player | TgtPrompt$ Select target player | Chooser$ You | Imprint$ True | Hidden$ True T:Mode$ SpellCast | ValidCard$ Card.cmcEQThoughtX,Card.SharesColorWith Imprinted | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever a player casts a spell that shares a color or converted mana cost with the exiled card, CARDNAME deals 2 damage to that player. -SVar:TrigDamage:AB$ DealDamage | Cost$ 0 | NumDmg$ 2 | Defined$ TriggeredCardController +SVar:TrigDamage:AB$ DealDamage | Cost$ 0 | NumDmg$ 2 | Defined$ TriggeredActivator SVar:ThoughtX:Count$ImprintedCardManaCost SVar:RemAIDeck:True SVar:RemRandomDeck:True diff --git a/res/cardsfolder/t/thraximundar.txt b/res/cardsfolder/t/thraximundar.txt index 1c7c33d78b0..5126c2d97f9 100644 --- a/res/cardsfolder/t/thraximundar.txt +++ b/res/cardsfolder/t/thraximundar.txt @@ -8,6 +8,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ T:Mode$ Sacrificed | ValidCard$ Creature | Execute$ TrigPutCounter | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever a player sacrifices a creature, you may put a +1/+1 counter on CARDNAME. SVar:TrigSac:AB$Sacrifice | Cost$ 0 | Defined$ Opponent | SacValid$ Creature SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +SVar:HasAttackEffect:TRUE SVar:Rarity:Mythic SVar:Picture:http://www.wizards.com/global/images/magic/general/thraximundar.jpg SetInfo:ARB|Mythic|http://magiccards.info/scans/en/arb/113.jpg diff --git a/res/cardsfolder/t/thunderbolt.txt b/res/cardsfolder/t/thunderbolt.txt index 2480eb9fac9..96f662ece40 100644 --- a/res/cardsfolder/t/thunderbolt.txt +++ b/res/cardsfolder/t/thunderbolt.txt @@ -4,7 +4,6 @@ Types:Instant Text:no text A:SP$ DealDamage | Cost$ 1 R | Tgt$ TgtP | NumDmg$ 3 | SpellDescription$ Choose one - CARDNAME deals 3 damage to target player; A:SP$ DealDamage | Cost$ 1 R | ValidTgts$ Creature.withFlying | NumDmg$ 4 | SpellDescription$ or CARDNAME deals 4 damage to target creature with flying. -SVar:RemAIDeck:True SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/thunderbolt.jpg SetInfo:WTH|Common|http://magiccards.info/scans/en/wl/115.jpg diff --git a/res/cardsfolder/t/tidespout_tyrant.txt b/res/cardsfolder/t/tidespout_tyrant.txt index fb991e37e81..75bd14859f7 100644 --- a/res/cardsfolder/t/tidespout_tyrant.txt +++ b/res/cardsfolder/t/tidespout_tyrant.txt @@ -4,7 +4,7 @@ Types:Creature Djinn Text:no text PT:5/5 K:Flying -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigBounce | TriggerDescription$ Whenever you cast a spell, return target permanent to its owner's hand. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigBounce | TriggerDescription$ Whenever you cast a spell, return target permanent to its owner's hand. SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | Origin$ Battlefield | Destination$ Hand SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/tidespout_tyrant.jpg diff --git a/res/cardsfolder/t/trusted_advisor.txt b/res/cardsfolder/t/trusted_advisor.txt index ea7c7874f6e..6f0dd33a905 100644 --- a/res/cardsfolder/t/trusted_advisor.txt +++ b/res/cardsfolder/t/trusted_advisor.txt @@ -5,7 +5,7 @@ Text:no text PT:1/2 S:Mode$ Continuous | Affected$ You | RaiseMaxHandSize$ 2 | Description$ Your maximum hand size is increased by two. T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, return a blue creature you control to its owner's hand. -SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target blue creature | Mandatory$ True | ValidTgts$ Creature.Blue+YouCtrl +SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand | TgtPrompt$ Choose target blue creature | Mandatory$ True | Hidden$ True | ValidTgts$ Creature.Blue+YouCtrl SVar:RemAIDeck:True SVar:Rarity:Uncommon SVar:Picture:http://www.wizards.com/global/images/magic/general/trusted_advisor.jpg diff --git a/res/cardsfolder/u/unifying_theory.txt b/res/cardsfolder/u/unifying_theory.txt index 22e5339d93f..ffd78cff841 100644 --- a/res/cardsfolder/u/unifying_theory.txt +++ b/res/cardsfolder/u/unifying_theory.txt @@ -2,8 +2,8 @@ Name:Unifying Theory ManaCost:1 U Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a player casts a spell, that player may pay 2. If the player does, he or she draws a card. -SVar:TrigDraw:AB$Draw | Cost$ 2 | Defined$ TriggeredPlayer | NumCards$ 1 +T:Mode$ SpellCast | ValidCard$ Card | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerController$ TriggeredActivator | TriggerDescription$ Whenever a player casts a spell, that player may pay 2. If the player does, he or she draws a card. +SVar:TrigDraw:AB$Draw | Cost$ 2 | Defined$ TriggeredActivator | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/unifying_theory.jpg diff --git a/res/cardsfolder/v/vedalken_archmage.txt b/res/cardsfolder/v/vedalken_archmage.txt index c49a9bb72f4..28318e9035f 100644 --- a/res/cardsfolder/v/vedalken_archmage.txt +++ b/res/cardsfolder/v/vedalken_archmage.txt @@ -3,7 +3,7 @@ ManaCost:2 U U Types:Creature Vedalken Wizard Text:no text PT:0/2 -T:Mode$ SpellCast | ValidCard$ Card.Artifact+YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, draw a card. +T:Mode$ SpellCast | ValidCard$ Artifact | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast an artifact spell, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/v/veilstone_amulet.txt b/res/cardsfolder/v/veilstone_amulet.txt index a95f718c284..39dcf875edc 100644 --- a/res/cardsfolder/v/veilstone_amulet.txt +++ b/res/cardsfolder/v/veilstone_amulet.txt @@ -2,7 +2,7 @@ Name:Veilstone Amulet ManaCost:3 Types:Artifact Text:no text -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Whenever you cast a spell, creatures you control can't be the targets of spells or abilities your opponents control this turn. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Whenever you cast a spell, creatures you control can't be the targets of spells or abilities your opponents control this turn. SVar:TrigEffect:AB$Effect | Cost$ 0 | Name$ Veilstone Amulet Effect | StaticAbilities$ CantTarget SVar:CantBeCast:Mode$ CantTarget | ValidCard$ Creature.YouCtrl | Activator$ Opponent | Description$ Creatures you control can't be the targets of spells or abilities your opponents control SVar:RemAIDeck:True diff --git a/res/cardsfolder/v/vengevine.txt b/res/cardsfolder/v/vengevine.txt index b0a06ff1034..2fa2f7fb34a 100644 --- a/res/cardsfolder/v/vengevine.txt +++ b/res/cardsfolder/v/vengevine.txt @@ -4,7 +4,7 @@ Types:Creature Elemental Text:no text PT:4/3 K:Haste -T:Mode$ SpellCast | ValidCard$ Creature | ValidControllingPlayer$ You | CheckSVar$ X | SVarCompare$ EQ2 | TriggerZones$ Graveyard | Execute$ TrigReturn | OptionalDecider$ You | TriggerDescription$ Whenever you cast a spell, if it's the second creature spell you cast this turn, you may return CARDNAME from your graveyard to the battlefield. +T:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | CheckSVar$ X | SVarCompare$ EQ2 | TriggerZones$ Graveyard | Execute$ TrigReturn | OptionalDecider$ You | TriggerDescription$ Whenever you cast a spell, if it's the second creature spell you cast this turn, you may return CARDNAME from your graveyard to the battlefield. SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Defined$ Self | Origin$ Graveyard | Destination$ Battlefield SVar:X:Count$ThisTurnCast_Creature.YouCtrl SVar:Rarity:Mythic diff --git a/res/cardsfolder/v/venser_the_sojourner.txt b/res/cardsfolder/v/venser_the_sojourner.txt index 364803f6943..835b7001960 100644 --- a/res/cardsfolder/v/venser_the_sojourner.txt +++ b/res/cardsfolder/v/venser_the_sojourner.txt @@ -10,7 +10,7 @@ SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True A:AB$ Effect | Cost$ SubCounter<1/LOYALTY> | Planeswalker$ True | Name$ Venser, the Sojourner Effect | Image$ venser_the_sojourner_emblem | StaticAbilities$ KWPump | SpellDescription$ Creatures are unblockable this turn. SVar:KWPump:Mode$ Continuous | Affected$ Creature | AddHiddenKeyword$ HIDDEN Unblockable | Description$ creatures are unblockable this turn. A:AB$ Effect | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Venser, the Sojourner emblem | Triggers$ TrigSpellCast | SVars$ EffSpellCast | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "Whenever you cast a spell, exile target permanent." -SVar:TrigSpellCast:Mode$ SpellCast | ValidControllingPlayer$ You | Execute$ EffSpellCast | TriggerDescription$ Whenever you cast a spell, exile target permanent. +SVar:TrigSpellCast:Mode$ SpellCast | ValidActivatingPlayer$ You | Execute$ EffSpellCast | TriggerDescription$ Whenever you cast a spell, exile target permanent. SVar:EffSpellCast:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Permanent SVar:RemAIDeck:True SVar:Rarity:Mythic diff --git a/res/cardsfolder/v/verdant_eidolon.txt b/res/cardsfolder/v/verdant_eidolon.txt index ca89191b762..e14909a3e31 100644 --- a/res/cardsfolder/v/verdant_eidolon.txt +++ b/res/cardsfolder/v/verdant_eidolon.txt @@ -4,7 +4,7 @@ Types:Creature Spirit Text:no text PT:2/2 A:AB$ Mana | Cost$ G Sac<1/CARDNAME> | Produced$ Any | Amount$ 3 | SpellDescription$ Add three mana of any one color to your mana pool. -T:Mode$ SpellCast | ValidCard$ Card.MultiColor+YouCtrl | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. +T:Mode$ SpellCast | ValidCard$ Card.MultiColor | ValidActivatingPlayer$ You | TriggerZones$ Graveyard | OptionalDecider$ You | Execute$ TrigReturn | TriggerDescription$ Whenever you cast a multicolored spell, you may return CARDNAME from your graveyard to your hand. SVar:TrigReturn:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Hand | Defined$ Self SVar:RemAIDeck:True SVar:Rarity:Common diff --git a/res/cardsfolder/v/verduran_enchantress.txt b/res/cardsfolder/v/verduran_enchantress.txt index a4f00feeaa0..6e1cec05829 100644 --- a/res/cardsfolder/v/verduran_enchantress.txt +++ b/res/cardsfolder/v/verduran_enchantress.txt @@ -3,7 +3,7 @@ ManaCost:1 G G Types:Creature Human Druid Text:no text PT:0/2 -T:Mode$ SpellCast | ValidCard$ Card.Enchantment+YouCtrl | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. +T:Mode$ SpellCast | ValidCard$ Enchantment | ValidActivatingPlayer$ You | Execute$ TrigDraw | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast an enchantment spell, draw a card. SVar:TrigDraw:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 1 SVar:RemRandomDeck:True SVar:Rarity:Rare diff --git a/res/cardsfolder/v/voice_of_the_provinces.txt b/res/cardsfolder/v/voice_of_the_provinces.txt index 8fae1a3f4f5..864afdf2749 100644 --- a/res/cardsfolder/v/voice_of_the_provinces.txt +++ b/res/cardsfolder/v/voice_of_the_provinces.txt @@ -5,7 +5,7 @@ Text:no text PT:3/3 K:Flying T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, put a 1/1 white Human creature token onto the battlefield. -SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Human | TokenTypes$ Creature,Human | TokenOwner$ You | TokenPower$ 1 | TokenToughness$ 1 | TokenColors$ White +SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 1 | TokenName$ Human | TokenTypes$ Creature,Human | TokenOwner$ You | TokenPower$ 1 | TokenToughness$ 1 | TokenColors$ White | TokenImage$ w 1 1 human avr SVar:Rarity:Common SVar:Picture:http://www.wizards.com/global/images/magic/general/voice_of_the_provinces.jpg SetInfo:AVR|Common|http://magiccards.info/scans/en/avr/40.jpg diff --git a/res/cardsfolder/v/voidmage_husher.txt b/res/cardsfolder/v/voidmage_husher.txt index 5a109001ae2..ae9cba33ef5 100644 --- a/res/cardsfolder/v/voidmage_husher.txt +++ b/res/cardsfolder/v/voidmage_husher.txt @@ -5,7 +5,7 @@ Text:no text PT:2/2 K:Flash T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigCounter | TriggerDescription$ When CARDNAME enters the battlefield, counter target activated ability. -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | Execute$ TrigBounce | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a spell, you may return CARDNAME to its owner's hand. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigBounce | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever you cast a spell, you may return CARDNAME to its owner's hand. SVar:TrigCounter:DB$Counter | Cost$ 0 | TargetType$ Activated | TgtPrompt$ Select target ability | ValidTgts$ Permanent SVar:TrigBounce:AB$ChangeZone | Cost$ 0 | Origin$ Battlefield | Destination$ Hand SVar:Rarity:Uncommon diff --git a/res/cardsfolder/w/wee_dragonauts.txt b/res/cardsfolder/w/wee_dragonauts.txt index a179901a460..c67f0f8ad35 100644 --- a/res/cardsfolder/w/wee_dragonauts.txt +++ b/res/cardsfolder/w/wee_dragonauts.txt @@ -4,7 +4,7 @@ Types:Creature Faerie Wizard Text:no text PT:1/3 K:Flying -T:Mode$ SpellCast | ValidCard$ Instant.YouCtrl,Sorcery.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast an instant or sorcery spell, CARDNAME gets +2/+0 until end of turn. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever you cast an instant or sorcery spell, CARDNAME gets +2/+0 until end of turn. SVar:TrigPump:AB$Pump | Cost$ 0 | Defined$ Self | NumAtt$ 2 SVar:BuffedBy:Instant,Sorcery SVar:Rarity:Common diff --git a/res/cardsfolder/w/witch_maw_nephilim.txt b/res/cardsfolder/w/witch_maw_nephilim.txt index 4972f62c5d9..11f898c7d79 100644 --- a/res/cardsfolder/w/witch_maw_nephilim.txt +++ b/res/cardsfolder/w/witch_maw_nephilim.txt @@ -3,7 +3,7 @@ ManaCost:G W U B Types:Creature Nephilim Text:Whenever CARDNAME attacks, it gains trample until end of turn if its power is 10 or greater. PT:1/1 -T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a spell, you may put two +1/+1 counters on CARDNAME. +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever you cast a spell, you may put two +1/+1 counters on CARDNAME. SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ P1P1 | CounterNum$ 2 SVar:BuffedBy:Card SVar:Rarity:Rare diff --git a/res/cardsfolder/w/withering_wisps.txt b/res/cardsfolder/w/withering_wisps.txt new file mode 100644 index 00000000000..6d1876a8755 --- /dev/null +++ b/res/cardsfolder/w/withering_wisps.txt @@ -0,0 +1,15 @@ +Name:Withering Wisps +ManaCost:1 B B +Types:Enchantment +Text:no text +T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | IsPresent$ Creature | PresentCompare$ EQ0 | Execute$ TrigSac | TriggerDescription$ At the beginning of the end step, if no creatures are on the battlefield, sacrifice CARDNAME. +SVar:TrigSac:AB$Sacrifice | Cost$ 0 | Defined$ Self +A:AB$ DamageAll | Cost$ B | NumDmg$ 1 | ValidCards$ Creature | ValidPlayers$ Each | ValidDescription$ each creature and each player. | ActivationLimit$ X | SpellDescription$ CARDNAME deals 1 damage to each creature and each player. Activate this ability no more times each turn than the number of snow Swamps you control. +SVar:X:Count$Valid Swamp.Snow+YouCtrl +SVar:NeedsToPlay:Creature +SVar:RemRandomDeck:True +SVar:Rarity:Uncommon +SVar:Picture:http://www.wizards.com/global/images/magic/general/withering_wisps.jpg +SetInfo:ICE|Uncommon|http://magiccards.info/scans/en/ia/56.jpg +Oracle:At the beginning of the end step, if no creatures are on the battlefield, sacrifice Withering Wisps.\n{B}: Withering Wisps deals 1 damage to each creature and each player. Activate this ability no more times each turn than the number of snow Swamps you control. +End \ No newline at end of file diff --git a/res/cardsfolder/x/xantid_swarm.txt b/res/cardsfolder/x/xantid_swarm.txt index 9bc09456cf1..d8f0ee93ed7 100644 --- a/res/cardsfolder/x/xantid_swarm.txt +++ b/res/cardsfolder/x/xantid_swarm.txt @@ -8,6 +8,7 @@ T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ Tr SVar:TrigEffect:AB$Effect | Cost$ 0 | Name$ Xantid Swarm Effect | StaticAbilities$ CantBeCast SVar:CantBeCast:Mode$ CantBeCast | ValidCard$ Card | Caster$ Opponent | Description$ Defending player can't cast spells. SVar:RemRandomDeck:True +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/xantid_swarm.jpg SetInfo:SCG|Rare|http://magiccards.info/scans/en/sc/135.jpg diff --git a/res/cardsfolder/y/yawgmoths_edict.txt b/res/cardsfolder/y/yawgmoths_edict.txt index cc307aa3458..4125482e0dd 100644 --- a/res/cardsfolder/y/yawgmoths_edict.txt +++ b/res/cardsfolder/y/yawgmoths_edict.txt @@ -2,7 +2,7 @@ Name:Yawgmoth's Edict ManaCost:1 B Types:Enchantment Text:no text -T:Mode$ SpellCast | ValidCard$ Card.White+YouDontCtrl | TriggerZones$ Battlefield | Execute$ TrigDrain | TriggerDescription$ Whenever an opponent casts a white spell, that player loses 1 life and you gain 1 life. +T:Mode$ SpellCast | ValidCard$ Card.White | ValidActivatingPlayer$ Opponent | TriggerZones$ Battlefield | Execute$ TrigDrain | TriggerDescription$ Whenever an opponent casts a white spell, that player loses 1 life and you gain 1 life. SVar:TrigDrain:AB$LoseLife | Cost$ 0 | Defined$ Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife SVar:DBGainLife:DB$GainLife | Defined$ You | LifeAmount$ 1 SVar:RemRandomDeck:True diff --git a/res/cardsfolder/y/yore_tiller_nephilim.txt b/res/cardsfolder/y/yore_tiller_nephilim.txt index 1956158b42b..5f3ba4ebc84 100644 --- a/res/cardsfolder/y/yore_tiller_nephilim.txt +++ b/res/cardsfolder/y/yore_tiller_nephilim.txt @@ -5,6 +5,7 @@ Text:no text PT:2/2 T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, return target creature card from your graveyard to the battlefield tapped and attacking. SVar:TrigChange:AB$ChangeZone | Cost$ 0 | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.YouCtrl | Tapped$ True | Attacking$ True +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/yore_tiller_nephilim.jpg SetInfo:GPT|Rare|http://magiccards.info/scans/en/gp/140.jpg diff --git a/res/cardsfolder/z/zur_the_enchanter.txt b/res/cardsfolder/z/zur_the_enchanter.txt index bee89c484d0..c2249c54aa4 100644 --- a/res/cardsfolder/z/zur_the_enchanter.txt +++ b/res/cardsfolder/z/zur_the_enchanter.txt @@ -6,6 +6,7 @@ PT:1/4 K:Flying T:Mode$ Attacks | ValidCard$ Card.Self | OptionalDecider$ You | Execute$ TrigChange | TriggerDescription$ Whenever CARDNAME attacks, you may search your library for an enchantment card with converted mana cost 3 or less and put it onto the battlefield. If you do, shuffle your library. SVar:TrigChange:AB$ChangeZone | Cost$ 0 | Origin$ Library | Destination$ Battlefield | ChangeType$ Enchantment.cmcLE3 | ChangeNum$ 1 +SVar:HasAttackEffect:TRUE SVar:Rarity:Rare SVar:Picture:http://www.wizards.com/global/images/magic/general/zur_the_enchanter.jpg SetInfo:CSP|Rare|http://magiccards.info/scans/en/cs/135.jpg diff --git a/res/images/deckeditor/filter_artifact_n.png b/res/images/deckeditor/filter_artifact_n.png deleted file mode 100644 index 2523d044c0a..00000000000 Binary files a/res/images/deckeditor/filter_artifact_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_artifact_y.png b/res/images/deckeditor/filter_artifact_y.png deleted file mode 100644 index 0b551e67d93..00000000000 Binary files a/res/images/deckeditor/filter_artifact_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_black_n.png b/res/images/deckeditor/filter_black_n.png deleted file mode 100644 index 60b23423217..00000000000 Binary files a/res/images/deckeditor/filter_black_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_black_y.png b/res/images/deckeditor/filter_black_y.png deleted file mode 100644 index 6e4246a2beb..00000000000 Binary files a/res/images/deckeditor/filter_black_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_blue_n.png b/res/images/deckeditor/filter_blue_n.png deleted file mode 100644 index c2183dc0c50..00000000000 Binary files a/res/images/deckeditor/filter_blue_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_blue_y.png b/res/images/deckeditor/filter_blue_y.png deleted file mode 100644 index ff5b7e7d35b..00000000000 Binary files a/res/images/deckeditor/filter_blue_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_colorless_n.png b/res/images/deckeditor/filter_colorless_n.png deleted file mode 100644 index cf231becc4c..00000000000 Binary files a/res/images/deckeditor/filter_colorless_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_colorless_y.png b/res/images/deckeditor/filter_colorless_y.png deleted file mode 100644 index bce292d3086..00000000000 Binary files a/res/images/deckeditor/filter_colorless_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_creature_n.png b/res/images/deckeditor/filter_creature_n.png deleted file mode 100644 index d577f01ef08..00000000000 Binary files a/res/images/deckeditor/filter_creature_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_creature_y.png b/res/images/deckeditor/filter_creature_y.png deleted file mode 100644 index aee035d6445..00000000000 Binary files a/res/images/deckeditor/filter_creature_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_enchant_n.png b/res/images/deckeditor/filter_enchant_n.png deleted file mode 100644 index b23e3122a68..00000000000 Binary files a/res/images/deckeditor/filter_enchant_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_enchant_y.png b/res/images/deckeditor/filter_enchant_y.png deleted file mode 100644 index 054bfbdbb47..00000000000 Binary files a/res/images/deckeditor/filter_enchant_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_green_n.png b/res/images/deckeditor/filter_green_n.png deleted file mode 100644 index 95d9527074f..00000000000 Binary files a/res/images/deckeditor/filter_green_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_green_y.png b/res/images/deckeditor/filter_green_y.png deleted file mode 100644 index eb4a5112544..00000000000 Binary files a/res/images/deckeditor/filter_green_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_instant_n.png b/res/images/deckeditor/filter_instant_n.png deleted file mode 100644 index 7c25dd437a5..00000000000 Binary files a/res/images/deckeditor/filter_instant_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_instant_y.png b/res/images/deckeditor/filter_instant_y.png deleted file mode 100644 index 83cd0d9a9d3..00000000000 Binary files a/res/images/deckeditor/filter_instant_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_land_n.png b/res/images/deckeditor/filter_land_n.png deleted file mode 100644 index f54f4f2864d..00000000000 Binary files a/res/images/deckeditor/filter_land_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_land_y.png b/res/images/deckeditor/filter_land_y.png deleted file mode 100644 index 8cc194c5327..00000000000 Binary files a/res/images/deckeditor/filter_land_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_planeswalker_n.png b/res/images/deckeditor/filter_planeswalker_n.png deleted file mode 100644 index f7b4c8bd85b..00000000000 Binary files a/res/images/deckeditor/filter_planeswalker_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_planeswalker_y.png b/res/images/deckeditor/filter_planeswalker_y.png deleted file mode 100644 index 81d204b7756..00000000000 Binary files a/res/images/deckeditor/filter_planeswalker_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_red_n.png b/res/images/deckeditor/filter_red_n.png deleted file mode 100644 index 4c059bc8392..00000000000 Binary files a/res/images/deckeditor/filter_red_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_red_y.png b/res/images/deckeditor/filter_red_y.png deleted file mode 100644 index 6c3f7b1c34f..00000000000 Binary files a/res/images/deckeditor/filter_red_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_sorcery_n.png b/res/images/deckeditor/filter_sorcery_n.png deleted file mode 100644 index cbfb904f55a..00000000000 Binary files a/res/images/deckeditor/filter_sorcery_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_sorcery_y.png b/res/images/deckeditor/filter_sorcery_y.png deleted file mode 100644 index e7b1cf10f76..00000000000 Binary files a/res/images/deckeditor/filter_sorcery_y.png and /dev/null differ diff --git a/res/images/deckeditor/filter_white_n.png b/res/images/deckeditor/filter_white_n.png deleted file mode 100644 index 77a37ec4337..00000000000 Binary files a/res/images/deckeditor/filter_white_n.png and /dev/null differ diff --git a/res/images/deckeditor/filter_white_y.png b/res/images/deckeditor/filter_white_y.png deleted file mode 100644 index d6ed26b89b5..00000000000 Binary files a/res/images/deckeditor/filter_white_y.png and /dev/null differ diff --git a/res/layouts/editor_default.xml b/res/layouts/editor_default.xml new file mode 100644 index 00000000000..52f95a2ff8b --- /dev/null +++ b/res/layouts/editor_default.xml @@ -0,0 +1,21 @@ + + + + CARD_PICTURE + EDITOR_PREFERENCES + EDITOR_FILTERS + + + EDITOR_CURRENTDECK + EDITOR_ALLDECKS + EDITOR_STATISTICS + EDITOR_PROBABILITIES + + + CARD_DETAIL + EDITOR_DECKGEN + + + EDITOR_CATALOG + + \ No newline at end of file diff --git a/res/main.properties b/res/main.properties index 02564a75384..da625f623b4 100644 --- a/res/main.properties +++ b/res/main.properties @@ -58,9 +58,9 @@ draft--properties=draft/draft.properties lang--transparent-properties=lang/lang.properties -image/base--file=pics -image/token--file=pics/tokens -image/icon--file=images/icons +image/base--file=C:/forge/pics +image/token--file=C:/forge/pics/tokens +image/icon--file=pics/icons image/product--file=pics_product pics/booster/images--file=quest/booster-images.txt diff --git a/res/preferences/editor.preferences b/res/preferences/editor.preferences new file mode 100644 index 00000000000..e205c2da6de --- /dev/null +++ b/res/preferences/editor.preferences @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/preferences/main.properties b/res/preferences/main.properties new file mode 100644 index 00000000000..aa12a9bddd6 --- /dev/null +++ b/res/preferences/main.properties @@ -0,0 +1,69 @@ +program/howToReportBugsURL=http://tinyurl.com/3zzrnyb +program/cardforgeURL=http://cardforge.org + +showdeck/2color=false +showdeck/3color=false +showdeck/4color=false +showdeck/5color=false + +tokens--file=AllTokens.txt +mtg-data--file=mtg-data.txt + +decks--file=all-decks2 +booster-decks--file=booster-deck +decks-dir--file=../decks + +card-pictures--file=card-pictures.txt +token-images--file=token-images.txt +card-pictures_a--file=../pics_link/card-pictures_a.txt +card-pictures_b--file=../pics_link/card-pictures_b.txt +card-pictures_c--file=../pics_link/card-pictures_c.txt +card-pictures_d--file=../pics_link/card-pictures_d.txt +card-pictures_e--file=../pics_link/card-pictures_e.txt +card-pictures_f--file=../pics_link/card-pictures_f.txt +card-pictures_g--file=../pics_link/card-pictures_g.txt +card-pictures_h--file=../pics_link/card-pictures_h.txt +card-pictures_i--file=../pics_link/card-pictures_i.txt +card-pictures_j--file=../pics_link/card-pictures_j.txt +card-pictures_k--file=../pics_link/card-pictures_k.txt +card-pictures_l--file=../pics_link/card-pictures_l.txt +card-pictures_m--file=../pics_link/card-pictures_m.txt +card-pictures_n--file=../pics_link/card-pictures_n.txt +card-pictures_o--file=../pics_link/card-pictures_o.txt +card-pictures_p--file=../pics_link/card-pictures_p.txt +card-pictures_q--file=../pics_link/card-pictures_q.txt +card-pictures_r--file=../pics_link/card-pictures_r.txt +card-pictures_s--file=../pics_link/card-pictures_s.txt +card-pictures_t--file=../pics_link/card-pictures_t.txt +card-pictures_u--file=../pics_link/card-pictures_u.txt +card-pictures_v--file=../pics_link/card-pictures_v.txt +card-pictures_w--file=../pics_link/card-pictures_w.txt +card-pictures_x--file=../pics_link/card-pictures_x.txt +card-pictures_y--file=../pics_link/card-pictures_y.txt +card-pictures_z--file=../pics_link/card-pictures_z.txt +card-pictures_other--file=../pics_link/card-pictures_other.txt +card-pictures_token_hq--file=../pics_link/card-pictures_token.txt +cards--file=cards.txt +cardsfolder--file=../cardsfolder +removed-cards--file=removedCards.txt + +regular/common--file=common.txt +regular/uncommon--file=uncommon.txt +regular/rare--file=rare.txt + +name-mutator--file=name-mutator.txt + +quest--properties=../quest/quest.properties +draft--properties=../draft/draft.properties + +lang--transparent-properties=../lang/lang.properties + +image/base--file=C:/forge/pics +image/token--file=C:/forge/pics/tokens +image/icon--file=../pics/icons +image/product--file=../pics_product +pics/booster/images--file=../quest/booster-images.txt + +quest/opponent/icons--file=../quest/quest-opponent-icons.txt +quest/pet/icons--file=../quest/quest-pet-shop-icons.txt +quest/pet/tokens--file=../quest/quest-pet-token-images.txt diff --git a/res/quest/all-prices.txt b/res/quest/all-prices.txt index db0b9fecc36..0e253861c7e 100644 --- a/res/quest/all-prices.txt +++ b/res/quest/all-prices.txt @@ -1,139 +1,141 @@ AErathi Berserker=100 -AEther Adept=45 -AEther Barrier=64 +AEther Adept=37 +AEther Barrier=50 AEther Burst=44 AEther Charge=28 -AEther Figment=25 -AEther Flash=25 -AEther Membrane=99 -AEther Mutation=68 +AEther Figment=36 +AEther Flash=41 +AEther Membrane=179 +AEther Mutation=52 AEther Rift=58 -AEther Shockwave=24 -AEther Snap=84 +AEther Shockwave=39 +AEther Snap=100 AEther Spellbomb=25 AEther Sting=40 AEther Storm=27 AEther Tide=28 AEther Tradewinds=25 -AEther Vial=1022 +AEther Vial=881 AEther Web=24 AEtherflame Wall=54 -AEthermage's Touch=51 +AEthermage's Touch=60 AEtherplasm=25 AEthersnipe=25 AEthertow=25 -AWOL=55 -Abandon Hope=40 +AWOL=62 +Abandon Hope=100 Abandoned Outpost=15 -Abattoir Ghoul=31 +Abattoir Ghoul=32 Abbey Gargoyles=28 Abbey Griffin=35 Abbey Matron=25 -Abduction=47 -Abeyance=266 +Abduction=38 +Abeyance=289 Abjure=38 -Abolish=35 -Abomination=40 +Abolish=38 +Abomination=28 Aboroth=38 Aboshan's Desire=25 Aboshan, Cephalid Emperor=78 -About Face=40 +About Face=15 Absolute Grace=41 -Absolute Law=55 +Absolute Law=50 Absolver Thrull=25 -Absorb=182 +Absorb=163 Absorb Vis=25 -Abu Ja'far=287 +Abu Ja'far=144 Abuna Acolyte=50 Abuna's Chant=25 -Abundance=70 -Abyssal Gatekeeper=25 +Abundance=73 +Abundant Growth=35 +Abyssal Gatekeeper=39 Abyssal Horror=10 Abyssal Hunter=46 Abyssal Nightstalker=25 -Abyssal Nocturnus=56 -Abyssal Persecutor=454 -Abyssal Specter=31 -Academy Rector=783 -Academy Researchers=24 -Academy Ruins=676 +Abyssal Nocturnus=190 +Abyssal Persecutor=365 +Abyssal Specter=35 +Academy Rector=883 +Academy Researchers=25 +Academy Ruins=751 Accelerate=46 Accelerated Mutation=28 Acceptable Losses=28 -Accorder Paladin=37 -Accorder's Shield=25 -Accumulated Knowledge=27 +Accorder Paladin=27 +Accorder's Shield=42 +Accumulated Knowledge=22 Accursed Centaur=25 Ach! Hans, Run!=62 -Acid Rain=1068 +Acid Rain=860 Acid Web Spider=37 Acidic Dagger=39 -Acidic Slime=25 -Acidic Sliver=125 +Acidic Slime=22 +Acidic Sliver=57 Acidic Soil=40 -Acolyte of Xathrid=25 -Acorn Harvest=29 -Acquire=196 +Acolyte of Xathrid=62 +Acorn Harvest=48 +Acquire=102 Acridian=16 -Act of Aggression=25 -Act of Treason=25 +Act of Aggression=50 +Act of Treason=22 Active Volcano=15 -Ad Nauseam=82 -Adamaro, First to Desire=93 -Adaptive Automaton=244 +Ad Nauseam=116 +Adamaro, First to Desire=74 +Adaptive Automaton=184 Adarkar Sentinel=38 Adarkar Unicorn=25 -Adarkar Valkyrie=579 -Adarkar Wastes=134 +Adarkar Valkyrie=754 +Adarkar Wastes=117 Adarkar Windform=56 Adder-Staff Boggart=40 Addle=40 -Admonition Angel=188 -Adun Oakenshield=1283 +Admonition Angel=225 +Adun Oakenshield=1434 Advance Scout=25 Advanced Hoverguard=25 -Adventurers' Guildhouse=65 +Adventurers' Guildhouse=130 Adventuring Gear=25 Advice from the Fae=25 -Aegis Angel=48 -Aegis of Honor=129 +Aegis Angel=41 +Aegis of Honor=120 Aegis of the Meek=79 Aeolipile=75 -Aeon Chronicler=288 +Aeon Chronicler=25 Aerial Caravan=54 Aerie Mystics=25 Aerie Ouphes=99 Aesthetic Consultation=100 Aesthir Glider=41 Affa Guard Hound=25 -Afflict=22 -Afiya Grove=100 +Afflict=27 +Afflicted Deserter=34 +Afiya Grove=58 Afterlife=25 -Aftershock=40 -Agadeem Occultist=25 -Ageless Entity=61 +Aftershock=35 +Agadeem Occultist=38 +Ageless Entity=97 Ageless Sentinels=25 -Agent of Masks=29 +Agent of Masks=63 Agent of Shauku=37 Agent of Stromgald=16 -Aggravated Assault=250 +Aggravated Assault=142 Aggression=40 Aggressive Urge=5970 Agility=12 Agonizing Demise=40 Agonizing Memories=23 -Agony Warp=100 -Agrus Kos, Wojek Veteran=85 +Agony Warp=42 +Agrus Kos, Wojek Veteran=58 Air Bladder=28 -Air Elemental=37 +Air Elemental=36 Air Servant=27 -Airborne Aid=45 +Airborne Aid=25 Airdrop Condor=25 Aisling Leprechaun=28 -Ajani Goldmane=455 -Ajani Vengeant=335 -Ajani's Mantra=13 -Ajani's Pridemate=69 +Ajani Goldmane=494 +Ajani Vengeant=383 +Ajani's Mantra=25 +Ajani's Pridemate=25 Akki Avalanchers=25 Akki Blizzard-Herder=12 Akki Coalflinger=40 @@ -145,22 +147,22 @@ Akki Underling=25 Akki Underminer=30 Akoum Battlesinger=25 Akoum Boulderfoot=25 -Akoum Refuge=62 +Akoum Refuge=54 Akrasan Squire=37 Akroma's Blessing=100 Akroma's Devoted=49 -Akroma's Memorial=1382 -Akroma's Vengeance=115 -Akroma, Angel of Fury=230 -Akroma, Angel of Wrath=678 -Akron Legionnaire=76 -Aku Djinn=125 -Akuta, Born of Ash=28 -Al-abara's Carpet=399 -Alabaster Dragon=104 +Akroma's Memorial=1519 +Akroma's Vengeance=117 +Akroma, Angel of Fury=217 +Akroma, Angel of Wrath=745 +Akron Legionnaire=74 +Aku Djinn=43 +Akuta, Born of Ash=35 +Al-abara's Carpet=249 +Alabaster Dragon=98 Alabaster Leech=11 Alabaster Mage=35 -Alabaster Potion=23 +Alabaster Potion=19 Alabaster Wall=28 Alaborn Cavalier=25 Alaborn Grenadier=25 @@ -168,68 +170,71 @@ Alaborn Musketeer=41 Alaborn Trooper=28 Alaborn Veteran=233 Alaborn Zealot=289 -Aladdin=574 -Aladdin's Lamp=212 -Aladdin's Ring=52 -Alarum=28 -Albino Troll=21 -Alchor's Tomb=307 +Aladdin=118 +Aladdin's Lamp=81 +Aladdin's Ring=36 +Alarum=163 +Albino Troll=20 +Alchemist's Refuge=168 +Alchor's Tomb=200 Aleatory=29 Alert Shu Infantry=50 Alexi's Cloak=39 Alexi, Zephyr Mage=25 -Algae Gharial=25 -Ali Baba=167 -Ali from Cairo=4373 +Algae Gharial=100 +Ali Baba=118 +Ali from Cairo=3281 Aliban's Tower=15 -All Hallow's Eve=2577 -All Is Dust=680 -All Suns' Dawn=87 +All Hallow's Eve=3436 +All Is Dust=804 +All Suns' Dawn=100 Alladin's Lamp=66 Alladin's Ring=349 Allay=52 Alley Grifters=40 Allied Strategies=30 -Allosaurus Rider=98 +Allosaurus Rider=69 Alloy Golem=25 -Alloy Myr=50 +Alloy Myr=54 Alluring Scent=101 -Alluring Siren=12 +Alluring Siren=11 Alms=41 -Alpha Kavu=25 +Alpha Brawl=26 +Alpha Kavu=100 Alpha Myr=49 -Alpha Status=131 -Alpha Tyrranax=13 -Altar Golem=79 -Altar of Bone=81 -Altar of Dementia=457 -Altar of Shadows=95 +Alpha Status=84 +Alpha Tyrranax=25 +Altar Golem=25 +Altar of Bone=62 +Altar of Dementia=421 +Altar of Shadows=48 +Altar of the Lost=25 Altar's Light=25 -Altar's Reap=19 +Altar's Reap=35 Alter Reality=129 -Aluren=437 -Ambassador Laquatus=117 +Aluren=368 +Ambassador Laquatus=68 Ambassador Oak=25 -Amber Prison=47 +Amber Prison=72 Ambiguity=100 -Ambition's Cost=317 +Ambition's Cost=212 Ambush=399 -Ambush Commander=266 +Ambush Commander=79 Ambush Party=28 -Ambush Viper=25 -Amnesia=108 -Amoeboid Changeling=28 -Amok=110 +Ambush Viper=43 +Amnesia=101 +Amoeboid Changeling=31 +Amok=25 Amphibious Kavu=28 -Amphin Cutthroat=40 +Amphin Cutthroat=99 Amrou Kithkin=25 Amrou Scout=25 Amrou Seekers=25 Amugaba=100 Amulet of Kroog=28 Amulet of Quoz=199 -Amulet of Unmaking=35 -Amulet of Vigor=72 +Amulet of Unmaking=99 +Amulet of Vigor=89 An-Havva Constable=49 An-Havva Inn=40 An-Havva Township=25 @@ -240,94 +245,98 @@ Ana Sanctuary=12 Anaba Ancestor=50 Anaba Bodyguard=28 Anaba Shaman=26 -Anaba Spirit Crafter=48 +Anaba Spirit Crafter=39 Anaconda=23 -Anarchist=17 +Anarchist=16 Anarchy=100 Anathemancer=25 Anavolver=25 -Ancestor's Chosen=30 +Ancestor's Chosen=25 Ancestor's Prophet=175 -Ancestral Knowledge=100 -Ancestral Mask=36 -Ancestral Memories=35 -Ancestral Recall=40231 +Ancestral Knowledge=47 +Ancestral Mask=38 +Ancestral Memories=36 +Ancestral Recall=66448 Ancestral Tribute=100 -Ancestral Vision=383 -Ancient Amphitheater=90 -Ancient Craving=465 -Ancient Den=126 -Ancient Grudge=24 +Ancestral Vision=282 +Ancient Amphitheater=100 +Ancient Craving=461 +Ancient Den=94 +Ancient Grudge=172 Ancient Hellkite=66 Ancient Hydra=32 Ancient Kavu=28 -Ancient Ooze=76 -Ancient Runes=100 -Ancient Silverback=59 +Ancient Ooze=100 +Ancient Runes=35 +Ancient Silverback=52 Ancient Spider=25 Ancient Spring=25 Ancient Stirrings=45 -Ancient Tomb=735 -Ancient Ziggurat=178 +Ancient Tomb=698 +Ancient Ziggurat=179 Andradite Leech=49 -Angel Token=130 -Angel of Despair=333 -Angel of Flight Alabaster=34 +Angel Token=91 +Angel of Despair=376 +Angel of Flight Alabaster=32 Angel of Fury=549 -Angel of Light=171 -Angel of Mercy=54 -Angel of Retribution=58 -Angel of Salvation=70 -Angel's Feather=20 -Angel's Grace=361 +Angel of Glory's Rise=73 +Angel of Jubilation=249 +Angel of Light=774 +Angel of Mercy=36 +Angel of Retribution=100 +Angel of Salvation=58 +Angel's Feather=23 +Angel's Grace=296 Angel's Herald=47 -Angel's Mercy=30 -Angel's Trumpet=40 +Angel's Mercy=25 +Angel's Tomb=35 +Angel's Trumpet=38 Angelfire Crusader=25 -Angelheart Vial=62 -Angelic Arbiter=41 -Angelic Benediction=37 +Angelheart Vial=33 +Angelic Arbiter=73 +Angelic Armaments=67 +Angelic Benediction=52 Angelic Blessing=44 -Angelic Chorus=113 -Angelic Curator=39 -Angelic Destiny=1355 +Angelic Chorus=163 +Angelic Curator=37 +Angelic Destiny=972 Angelic Favor=29 -Angelic Overseer=135 -Angelic Page=23 -Angelic Protector=50 -Angelic Renewal=25 -Angelic Shield=40 -Angelic Voices=107 -Angelic Wall=27 -Angelsong=25 -Anger=93 -Angry Mob=36 -Angus Mackenzie=2029 +Angelic Overseer=124 +Angelic Page=9 +Angelic Protector=100 +Angelic Renewal=79 +Angelic Shield=38 +Angelic Voices=127 +Angelic Wall=26 +Angelsong=36 +Anger=67 +Angry Mob=37 +Angus Mackenzie=2235 Animal Boneyard=40 Animal Magnetism=66 Animate Artifact=38 -Animate Dead=173 +Animate Dead=127 Animate Land=25 -Animate Wall=171 -Ankh of Mishra=247 -Annex=45 +Animate Wall=178 +Ankh of Mishra=225 +Annex=34 Annihilate=25 -Annul=11 +Annul=10 Anodet Lurker=49 Anoint=16 -Anowon, the Ruin Sage=129 -Ant Queen=61 +Anowon, the Ruin Sage=143 +Ant Queen=56 Antagonism=39 Anthem of Rakdos=54 -Anthroplasm=25 -Anti-Magic Aura=12 +Anthroplasm=44 +Anti-Magic Aura=13 Antler Skulkin=25 Anurid Barkripper=27 Anurid Brushhopper=25 Anurid Murkdiver=28 Anurid Scavenger=25 Anurid Swarmsnapper=25 -Anvil of Bogardan=321 +Anvil of Bogardan=473 Apathy=40 Apes of Rath=29 Apex Hawks=40 @@ -336,254 +345,261 @@ Aphetto Dredging=40 Aphetto Exterminator=25 Aphetto Grifter=40 Aphetto Runecaster=25 -Aphetto Vulture=40 -Aphotic Wisps=40 +Aphetto Vulture=99 +Aphotic Wisps=25 Apocalypse Chime=125 -Apocalypse Hydra=258 -Apostle's Blessing=25 +Apocalypse Hydra=200 +Apostle's Blessing=34 Apothecary Initiate=49 -Apprentice Necromancer=120 +Appetite for Brains=61 +Apprentice Necromancer=211 Apprentice Sorcerer=100 -Apprentice Wizard=46 +Apprentice Wizard=39 Aquamoeba=15 Aquamorph Entity=28 Aquastrand Spider=40 -Aquitect's Will=28 +Aquitect's Will=40 Araba Mothrider=79 Arachnoid=225 -Arachnus Spinner=26 -Arachnus Web=25 -Arashi, the Sky Asunder=93 -Arbalest Elite=35 +Arachnus Spinner=25 +Arachnus Web=16 +Arashi, the Sky Asunder=250 +Arbalest Elite=25 Arbiter of Knollridge=57 -Arbor Elf=43 -Arboria=155 -Arc Blade=25 +Arbor Elf=25 +Arboria=145 +Arc Blade=39 Arc Lightning=36 Arc Mage=25 -Arc Runner=25 -Arc Trail=146 -Arc-Slogger=29 -Arcades Sabboth=142 -Arcane Denial=30 -Arcane Laboratory=57 -Arcane Sanctum=155 +Arc Runner=31 +Arc Trail=80 +Arc-Slogger=16 +Arcades Sabboth=974 +Arcane Denial=35 +Arcane Laboratory=66 +Arcane Melee=38 +Arcane Sanctum=162 Arcane Spyglass=40 Arcane Teachings=40 -Arcanis the Omnipotent=328 -Arcanum Wings=25 +Arcanis the Omnipotent=274 +Arcanum Wings=26 Arcbound Bruiser=31 -Arcbound Crusher=77 -Arcbound Fiend=32 +Arcbound Crusher=99 +Arcbound Fiend=40 Arcbound Hybrid=25 Arcbound Lancer=25 -Arcbound Overseer=162 -Arcbound Ravager=1679 -Arcbound Reclaimer=76 -Arcbound Slith=31 -Arcbound Stinger=31 +Arcbound Overseer=214 +Arcbound Ravager=1463 +Arcbound Reclaimer=170 +Arcbound Slith=62 +Arcbound Stinger=28 Arcbound Wanderer=40 -Arcbound Worker=42 -Archaeological Dig=46 -Archangel=175 -Archdemon of Unx=41 +Arcbound Worker=38 +Archaeological Dig=25 +Archangel=134 +Archangel's Light=50 +Archdemon of Unx=76 Archery Training=40 Architects of Will=25 -Archive Trap=119 -Archivist=25 -Archmage Ascension=32 -Archon of Justice=277 -Archon of Redemption=31 -Arctic Flats=31 +Archive Trap=150 +Archivist=30 +Archmage Ascension=34 +Archon of Justice=28 +Archon of Redemption=35 +Archwing Dragon=97 +Arctic Flats=179 Arctic Foxes=25 Arctic Merfolk=28 Arctic Nishoba=40 -Arctic Wolves=24 -Arcum Dagsson=116 +Arctic Wolves=38 +Arcum Dagsson=166 Arcum's Sleigh=10 Arcum's Weathervane=25 Arcum's Whistle=100 -Ardent Militia=26 -Ardent Plea=25 -Ardent Recruit=25 +Ardent Militia=25 +Ardent Plea=42 +Ardent Recruit=46 Ardent Soldier=50 -Arena=255 -Arena of the Ancients=125 +Arena=170 +Arena of the Ancients=109 Arenson's Aura=25 -Argent Mutation=35 -Argent Sphinx=45 -Argentum Armor=74 -Argivian Archaeologist=1143 +Argent Mutation=34 +Argent Sphinx=35 +Argentum Armor=65 +Argivian Archaeologist=765 Argivian Blacksmith=26 -Argivian Find=45 -Argivian Restoration=42 -Argothian Elder=94 -Argothian Enchantress=1194 +Argivian Find=49 +Argivian Restoration=50 +Argothian Elder=88 +Argothian Enchantress=1080 Argothian Pixies=28 Argothian Swine=16 -Argothian Treefolk=25 -Argothian Wurm=155 -Arid Mesa=889 -Ark of Blight=25 +Argothian Treefolk=19 +Argothian Wurm=215 +Arid Mesa=878 +Ark of Blight=37 Arm with AEther=25 -Armadillo Cloak=47 -Armageddon=437 -Armageddon Clock=59 -Armament Master=27 +Armadillo Cloak=50 +Armageddon=286 +Armageddon Clock=47 +Armament Master=54 Armed Response=25 -Armillary Sphere=15 +Armillary Sphere=37 Armistice=100 Armor Sliver=50 Armor Thrull=25 Armor of Faith=26 Armor of Thorns=100 -Armored Ascension=33 +Armored Ascension=29 Armored Cancrix=12 Armored Galleon=49 Armored Griffin=41 Armored Guardian=56 Armored Pegasus=47 -Armored Skaab=12 +Armored Skaab=37 Armored Warhorse=12 Armorer Guildmage=28 Arms Dealer=50 -Army Ants=50 -Army of Allah=329 -Army of the Damned=199 +Army Ants=51 +Army of Allah=160 +Army of the Damned=121 Arnjlot's Ascent=999 -Arrest=19 -Arrogant Bloodlord=34 +Arrest=26 +Arrogant Bloodlord=37 Arrogant Vampire=103 -Arrogant Wurm=58 +Arrogant Wurm=32 Arrow Volley Trap=1350 Arsenal Thresher=33 +Artful Dodge=16 Artful Looter=28 -Artifact Blast=26 -Artifact Mutation=230 -Artifact Possession=30 -Artifact Ward=250 +Artifact Blast=29 +Artifact Mutation=100 +Artifact Possession=34 +Artifact Ward=750 Artificer's Intuition=25 Artificial Evolution=79 Artillerize=16 -Artisan of Kozilek=72 -Ascendant Evincar=150 +Artisan of Kozilek=67 +Ascendant Evincar=178 Ascending Aven=28 -Asceticism=137 -Asha's Favor=7 +Asceticism=132 +Asha's Favor=25 Ashcoat Bear=25 Ashen Firebeast=25 Ashen Ghoul=31 Ashen Monstrosity=25 -Ashen Powder=100 -Ashen-Skin Zubera=34 +Ashen Powder=166 +Ashen-Skin Zubera=25 Ashenmoor Cohort=25 -Ashenmoor Gouger=49 -Ashenmoor Liege=245 -Ashes to Ashes=25 +Ashenmoor Gouger=66 +Ashenmoor Liege=102 +Ashes to Ashes=27 Ashling the Pilgrim=25 Ashling's Prerogative=25 -Ashling, the Extinguisher=196 +Ashling, the Extinguisher=192 Ashmouth Hound=36 -Ashnod's Altar=76 -Ashnod's Battle Gear=25 -Ashnod's Coupon=777 +Ashnod's Altar=49 +Ashnod's Battle Gear=29 +Ashnod's Coupon=505 Ashnod's Cylix=62 Ashnod's Transmogrant=42 -Asmira, Holy Avenger=10 -Aspect of Mongoose=52 -Aspect of Wolf=384 -Ass Whuppin'=100 -Assassin's Blade=140 +Asmira, Holy Avenger=75 +Aspect of Mongoose=34 +Aspect of Wolf=381 +Ass Whuppin'=113 +Assassin's Blade=69 Assassinate=24 Assault Griffin=11 -Assault Strobe=34 -Assault Zeppelid=31 +Assault Strobe=31 +Assault Zeppelid=25 Assault/Battery=50 Assembly Hall=36 Assembly-Worker=25 Assert Authority=15 -Assquatch=99 -Astral Slide=66 +Assquatch=100 +Astral Slide=29 Astral Steel=25 -Astrolabe=50 -Atalya, Samite Master=23 +Astrolabe=16 +Atalya, Samite Master=198 Atinlay Igpay=40 -Atog=19 +Atog=13 Atogatog=90 -Attrition=83 -Attunement=174 +Attrition=81 +Attunement=88 Augur il-Vec=25 -Augur of Skulls=41 -Augury Adept=115 +Augur of Skulls=25 +Augury Adept=140 Augury Owl=25 -Auntie's Hovel=145 -Auntie's Snitch=32 +Auntie's Hovel=153 +Auntie's Snitch=49 Aura Barbs=25 Aura Blast=40 Aura Extraction=25 Aura Finesse=25 Aura Flux=25 Aura Fracture=36 -Aura Gnarlid=41 +Aura Gnarlid=35 Aura Graft=25 -Aura Mutation=152 -Aura Shards=128 -Aura Thief=86 +Aura Mutation=133 +Aura Shards=110 +Aura Thief=98 Aura of Dominion=40 -Aura of Silence=37 -Auramancer=99 -Auramancer's Guise=37 -Auratog=55 -Auratouched Mage=46 -Aurification=157 +Aura of Silence=44 +Auramancer=25 +Auramancer's Guise=25 +Auratog=65 +Auratouched Mage=25 +Aurification=73 Auriok Bladewarden=37 -Auriok Champion=233 -Auriok Edgewright=46 +Auriok Champion=329 +Auriok Edgewright=31 Auriok Glaivemaster=40 Auriok Replica=12 -Auriok Salvagers=25 +Auriok Salvagers=34 Auriok Siege Sled=25 -Auriok Steelshaper=136 -Auriok Sunchaser=25 +Auriok Steelshaper=148 +Auriok Sunchaser=34 Auriok Survivors=25 Auriok Transfixer=25 -Auriok Windwalker=79 +Auriok Windwalker=25 Aurochs=26 Aurochs Herd=25 Aurora Eidolon=25 Aurora Griffin=28 -Auspicious Ancestor=125 -Austere Command=151 -Autochthon Wurm=79 +Auspicious Ancestor=25 +Austere Command=162 +Autochthon Wurm=85 Autumn Willow=37 -Autumn's Veil=45 -Avacyn's Pilgrim=390 -Avacynian Priest=35 +Autumn's Veil=27 +Avacyn's Collar=25 +Avacyn's Pilgrim=34 +Avacyn, Angel of Hope=1142 +Avacynian Priest=32 Avalanche=86 -Avalanche Riders=50 +Avalanche Riders=45 Avarax=41 Avarice Totem=12 -Avatar of Discord=140 -Avatar of Fury=74 -Avatar of Hope=83 -Avatar of Me=121 -Avatar of Might=89 -Avatar of Will=58 -Avatar of Woe=215 +Avatar of Discord=172 +Avatar of Fury=63 +Avatar of Hope=82 +Avatar of Me=100 +Avatar of Might=106 +Avatar of Will=38 +Avatar of Woe=115 Aven Archer=40 Aven Augur=25 -Aven Brigadier=36 +Aven Brigadier=132 Aven Cloudchaser=27 Aven Envoy=28 Aven Farseer=25 Aven Fateshaper=25 Aven Fisher=27 -Aven Fleetwing=30 +Aven Fleetwing=35 Aven Flock=28 Aven Fogbringer=25 Aven Liberator=102 -Aven Mimeomancer=41 -Aven Mindcensor=222 +Aven Mimeomancer=66 +Aven Mindcensor=196 Aven Redeemer=25 Aven Riftwatcher=25 Aven Shrine=25 @@ -592,60 +608,60 @@ Aven Soulgazer=25 Aven Squire=54 Aven Trailblazer=14 Aven Trooper=28 -Aven Warhawk=25 +Aven Warhawk=30 Aven Windreader=27 -Avenger en-Dal=25 -Avenger of Zendikar=327 -Avenging Angel=100 +Avenger en-Dal=26 +Avenger of Zendikar=323 +Avenging Angel=104 Avenging Druid=52 Avian Changeling=25 Avizoa=39 -Avoid Fate=31 -Awakener Druid=23 -Awakening=209 -Awakening Zone=139 -Awe Strike=40 +Avoid Fate=30 +Awakener Druid=26 +Awakening=33 +Awakening Zone=114 +Awe Strike=58 Awesome Presence=25 Axegrinder Giant=25 -Axelrod Gunnarson=106 -Ayesha Tanaka=62 -Aysen Abbey=29 +Axelrod Gunnarson=112 +Ayesha Tanaka=29 +Aysen Abbey=19 Aysen Bureaucrats=28 -Aysen Crusader=37 +Aysen Crusader=85 Aysen Highway=50 Ayumi, the Last Visitor=99 -Azami, Lady of Scrolls=577 +Azami, Lady of Scrolls=197 Azimaet Drake=25 Azorius AEthermage=25 Azorius Chancery=49 -Azorius First-Wing=31 -Azorius Guildmage=26 -Azorius Herald=36 +Azorius First-Wing=25 +Azorius Guildmage=72 +Azorius Herald=58 Azorius Ploy=25 -Azorius Signet=47 -Azure Drake=31 -Azure Mage=28 -Azusa, Lost but Seeking=370 +Azorius Signet=38 +Azure Drake=29 +Azure Mage=16 +Azusa, Lost but Seeking=366 B-I-N-G-O=199 -Back from the Brink=26 -Back to Basics=629 -Back to Nature=40 +Back from the Brink=33 +Back to Basics=481 +Back to Nature=30 Backdraft=25 -Backfire=50 -Backlash=25 +Backfire=36 +Backlash=99 Backslide=40 Bad Ass=25 -Bad Moon=255 -Bad River=85 -Badlands=5010 +Bad Moon=235 +Bad River=93 +Badlands=5576 Baki's Curse=25 Baku Altar=225 Bala Ged Scorpion=25 Bala Ged Thief=25 -Balance=282 -Balance of Power=83 +Balance=413 +Balance of Power=119 Balancing Act=37 -Balduvian Barbarians=29 +Balduvian Barbarians=28 Balduvian Bears=27 Balduvian Conjurer=25 Balduvian Dead=32 @@ -655,40 +671,41 @@ Balduvian Horde=30 Balduvian Hydra=99 Balduvian Rage=40 Balduvian Shaman=25 -Balduvian Trading Post=99 +Balduvian Trading Post=54 Balduvian War-Makers=28 Balduvian Warlord=40 -Balefire Dragon=80 -Balefire Liege=394 -Baleful Stare=25 -Ball Lightning=158 +Balefire Dragon=68 +Balefire Liege=414 +Baleful Stare=24 +Ball Lightning=156 Ballista Squad=27 Balloon Peddler=16 -Ballynock Cohort=49 +Ballynock Cohort=25 Ballynock Trapper=32 -Ballyrush Banneret=43 +Ballyrush Banneret=52 Balm of Restoration=100 Baloth Cage Trap=37 -Baloth Woodcrasher=42 +Baloth Woodcrasher=50 Balshan Beguiler=45 Balshan Collaborator=29 Balshan Griffin=25 -Balthor the Defiled=314 +Balthor the Defiled=320 Balthor the Stout=100 Bamboozle=38 Bandage=26 Bane of the Living=79 -Banefire=198 -Baneful Omen=50 -Baneslayer Angel=599 +Banefire=234 +Baneful Omen=36 +Baneslayer Angel=619 Banewasp Affliction=47 Banishing Knack=25 +Banishing Stroke=40 Banishment Decree=11 Banshee=36 -Banshee's Blade=37 -Bant Battlemage=25 -Bant Charm=31 -Bant Panorama=25 +Banshee's Blade=58 +Bant Battlemage=35 +Bant Charm=76 +Bant Panorama=34 Bant Sojourners=25 Bant Sureblade=25 Barbarian Bully=25 @@ -698,138 +715,140 @@ Barbarian Horde=149 Barbarian Lunatic=28 Barbarian Outcast=27 Barbarian Riftcutter=25 -Barbarian Ring=91 +Barbarian Ring=77 Barbary Apes=25 Barbed Battlegear=42 Barbed Field=40 Barbed Foliage=25 Barbed Lightning=25 Barbed Sextant=25 -Barbed Shocker=31 +Barbed Shocker=37 Barbed Sliver=50 Barbed Wire=25 Barbed-Back Wurm=25 -Barbtooth Wurm=40 +Barbtooth Wurm=33 Bargain=66 Bargaining Table=37 Barishi=25 Barkhide Mauler=49 Barkshell Blessing=25 -Barktooth Warbeard=100 -Barl's Cage=18 -Baron Sengir=265 +Barktooth Warbeard=70 +Barl's Cage=17 +Baron Sengir=229 Barony Vampire=25 Barrage Ogre=31 Barrel Down Sokenzan=25 Barreling Attack=42 -Barren Glory=56 +Barren Glory=25 Barren Moor=32 Barrenton Cragtreads=25 Barrenton Medic=40 Barrin's Codex=25 Barrin's Spite=25 Barrin's Unmaking=7 -Barrin, Master Wizard=107 +Barrin, Master Wizard=54 Barrow Ghoul=28 -Bartel Runeaxe=99 -Barter in Blood=45 -Baru, Fist of Krosa=89 +Bartel Runeaxe=89 +Barter in Blood=35 +Baru, Fist of Krosa=119 Basal Sliver=40 Basal Thrull=33 Basalt Gargoyle=25 Basalt Golem=29 -Basalt Monolith=313 -Bash to Bits=25 -Basilisk Collar=314 -Basking Rootwalla=34 +Basalt Monolith=243 +Bash to Bits=31 +Basilisk Collar=322 +Basking Rootwalla=38 Bathe in Light=11 Baton of Courage=25 -Baton of Morale=30 +Baton of Morale=100 Battered Golem=25 Battering Craghorn=26 -Battering Ram=23 +Battering Ram=19 Battering Sliver=25 -Battering Wurm=49 -Batterskull=1129 +Battering Wurm=25 +Batterskull=1063 Battle Cry=25 Battle Frenzy=25 Battle Hurda=25 -Battle Mastery=37 +Battle Hymn=25 +Battle Mastery=49 Battle Rampart=25 -Battle Screech=32 +Battle Screech=50 Battle Squadron=75 Battle Strain=40 Battle of Wits=23 Battle-Mad Ronin=25 Battle-Rattle Shaman=25 -Battlefield Forge=92 +Battlefield Forge=43 Battlefield Medic=25 Battlefield Percher=25 Battlefield Scrounger=25 -Battlegate Mimic=44 -Battlegrace Angel=99 -Battleground Geist=50 -Battlegrowth=47 +Battlegate Mimic=36 +Battlegrace Angel=89 +Battleground Geist=32 +Battlegrowth=25 Battletide Alchemist=40 -Battlewand Oak=43 +Battlewand Oak=63 Battlewise Aven=28 -Batwing Brume=70 +Batwing Brume=82 Bay Falcon=40 -Bayou=6494 +Bayou=7118 Bayou Dragonfly=40 -Bazaar Trader=41 -Bazaar of Baghdad=23209 +Bazaar Trader=60 +Bazaar of Baghdad=18970 Bazaar of Wonders=72 Beacon Behemoth=25 Beacon Hawk=25 -Beacon of Creation=250 +Beacon of Creation=284 Beacon of Destiny=35 -Beacon of Destruction=33 -Beacon of Immortality=324 -Beacon of Tomorrows=310 -Beacon of Unrest=185 +Beacon of Destruction=76 +Beacon of Immortality=327 +Beacon of Tomorrows=147 +Beacon of Unrest=237 Bear Cub=160 -Bear Token=107 -Bear Umbra=110 +Bear Token=110 +Bear Umbra=124 Bearscape=42 Beast Attack=52 Beast Hunt=13 -Beast Token=25 +Beast Token=109 Beast Walkers=40 -Beast Within=169 -Beast of Burden=45 +Beast Within=147 +Beast of Burden=51 Beastbreaker of Bala Ged=25 -Beastmaster Ascension=73 +Beastmaster Ascension=104 Beastmaster's Magemark=15 Beasts of Bogardan=44 -Beckon Apparition=43 -Bedlam=65 -Bee Sting=292 -Befoul=36 -Behemoth Sledge=68 +Beckon Apparition=116 +Bedlam=62 +Bee Sting=43 +Befoul=32 +Beguiler of Wills=77 +Behemoth Sledge=94 Behemoth's Herald=25 Belbe's Armor=42 Belbe's Percher=28 -Belbe's Portal=161 +Belbe's Portal=117 Belfry Spirit=25 Belligerent Hatchling=25 Bellowing Fiend=22 -Bellowing Tanglewurm=32 +Bellowing Tanglewurm=49 Belltower Sphinx=38 -Beloved Chaplain=52 +Beloved Chaplain=50 Ben-Ben, Akki Hermit=100 Benalish Cavalry=25 -Benalish Commander=96 +Benalish Commander=125 Benalish Emissary=25 Benalish Heralds=75 Benalish Hero=35 Benalish Infantry=38 -Benalish Knight=41 +Benalish Knight=40 Benalish Lancer=25 Benalish Missionary=38 Benalish Trapper=25 Benalish Veteran=35 -Bend or Break=15 +Bend or Break=25 Benediction of Moons=25 Benevolent Ancestor=25 Benevolent Bodyguard=25 @@ -838,177 +857,183 @@ Benthic Behemoth=41 Benthic Djinn=74 Benthic Explorers=25 Benthicore=25 -Bequeathal=36 +Bequeathal=25 Bereavement=22 -Berserk=3705 +Berserk=3222 Berserk Murlodont=16 Berserkers of Blood Ridge=25 -Beseech the Queen=81 -Bestial Fury=25 +Beseech the Queen=150 +Bestial Fury=16 Bestial Menace=37 -Betrayal=48 -Betrayal of Flesh=29 +Betrayal=25 +Betrayal of Flesh=25 Betrothed of Fire=28 Bewilder=25 -Bifurcate=58 +Bifurcate=100 Big Game Hunter=25 Bile Urchin=25 -Bind=87 +Bind=149 Binding Agony=40 Binding Grasp=24 -Biomantic Mastery=56 +Biomantic Mastery=100 Bioplasm=100 -Biorhythm=44 -Birchlore Rangers=26 +Biorhythm=47 +Birchlore Rangers=15 Bird Maiden=49 Bird Token=10 -Birds of Paradise=571 -Birthing Pod=395 +Birds of Paradise=493 +Birthing Pod=272 Biting Tether=25 -Bitter Ordeal=132 -Bitterblossom=1274 -Bitterheart Witch=25 -Bituminous Blast=103 +Bitter Ordeal=131 +Bitterblossom=1125 +Bitterheart Witch=37 +Bituminous Blast=31 Black Carriage=175 -Black Knight=51 -Black Lotus=91670 -Black Mana Battery=53 -Black Market=559 +Black Cat=20 +Black Knight=53 +Black Lotus=86418 +Black Mana Battery=55 +Black Market=343 Black Poplar Shaman=25 Black Scarab=25 -Black Sun's Zenith=575 -Black Vise=219 -Black Ward=58 -Blackcleave Cliffs=531 -Blackcleave Goblin=40 -Blacker Lotus=448 +Black Sun's Zenith=442 +Black Vise=210 +Black Ward=62 +Blackcleave Cliffs=506 +Blackcleave Goblin=25 +Blacker Lotus=529 Blackmail=54 -Blade Sliver=76 -Blade Splicer=271 -Blade of the Bloodchief=133 +Blade Sliver=38 +Blade Splicer=273 +Blade of the Bloodchief=154 Blade of the Sixth Pride=15 Blade-Tribe Berserkers=26 -Bladed Pinions=28 +Bladed Bracers=41 +Bladed Pinions=25 Bladed Sentinel=25 Blademane Baku=25 Blades of Velis Vel=25 Bladetusk Boar=25 -Bladewing the Risen=117 -Bladewing's Thrall=25 -Blanchwood Armor=47 +Bladewing the Risen=156 +Bladewing's Thrall=13 +Blanchwood Armor=31 Blanchwood Treefolk=16 -Blanket of Night=80 -Blasphemous Act=35 -Blast from the Past=175 +Blanket of Night=49 +Blasphemous Act=38 +Blast from the Past=249 Blasted Landscape=62 Blaster Mage=28 -Blasting Station=87 -Blastoderm=27 -Blatant Thievery=222 -Blaze=100 -Blaze of Glory=1094 +Blasting Station=153 +Blastoderm=25 +Blatant Thievery=303 +Blaze=72 +Blaze of Glory=1321 Blazethorn Scarecrow=40 -Blazing Archon=187 +Blazing Archon=174 Blazing Blade Askari=25 Blazing Effigy=25 Blazing Salvo=25 -Blazing Shoal=297 -Blazing Specter=79 +Blazing Shoal=166 +Blazing Specter=107 Blazing Torch=9 Bleak Coven Vampires=37 -Blessed Breath=40 +Blessed Breath=25 Blessed Orator=25 Blessed Reversal=43 -Blessed Wind=23 -Blessed Wine=10 -Blessing=202 +Blessed Wind=99 +Blessed Wine=26 +Blessing=215 Blessing of Leeches=25 Blessing of the Nephilim=25 -Blight=84 -Blight Mamba=25 +Blessings of Nature=40 +Blight=85 +Blight Mamba=34 Blight Sickle=25 Blighted Agent=31 Blighted Shaman=22 -Blightning=132 -Blightsoil Druid=33 -Blightspeaker=32 -Blightsteel Colossus=541 +Blightning=108 +Blightsoil Druid=35 +Blightspeaker=25 +Blightsteel Colossus=460 Blightwidow=25 Blind Creeper=25 Blind Fury=25 Blind Hunter=25 -Blind Phantasm=23 +Blind Phantasm=15 Blind Seer=62 -Blind Zealot=36 +Blind Zealot=25 Blind with Anger=25 Blind-Spot Giant=25 -Blinding Angel=264 +Blinding Angel=241 Blinding Beam=25 -Blinding Light=85 +Blinding Light=62 Blinding Mage=18 Blinding Powder=25 -Blinding Souleater=25 -Blinking Spirit=27 -Blinkmoth Infusion=11 -Blinkmoth Nexus=920 -Blinkmoth Urn=25 +Blinding Souleater=32 +Blinking Spirit=24 +Blinkmoth Infusion=100 +Blinkmoth Nexus=878 +Blinkmoth Urn=99 Blinkmoth Well=40 Blister Beetle=34 -Blistergrub=37 +Blistergrub=25 Blistering Barrier=25 Blistering Dieflyn=25 -Blistering Firecat=222 +Blistering Firecat=196 Blisterstick Shaman=26 -Blitz Hellion=51 +Blitz Hellion=122 Blizzard=125 -Blizzard Elemental=25 -Blizzard Specter=102 -Bloated Toad=40 +Blizzard Elemental=42 +Blizzard Specter=193 +Bloated Toad=38 Blockade Runner=28 Blockbuster=25 +Blood Artist=45 Blood Celebrant=16 -Blood Clock=75 -Blood Crypt=1644 +Blood Clock=79 +Blood Crypt=1497 Blood Cultist=50 +Blood Feud=32 Blood Frenzy=16 Blood Funnel=25 Blood Hound=50 -Blood Knight=65 -Blood Lust=97 -Blood Moon=497 +Blood Knight=84 +Blood Lust=68 +Blood Moon=399 Blood Oath=100 Blood Ogre=35 -Blood Pet=13 +Blood Pet=11 Blood Rites=25 -Blood Seeker=29 -Blood Speaker=41 -Blood Tithe=25 -Blood Tribute=45 -Blood Tyrant=98 +Blood Seeker=11 +Blood Speaker=104 +Blood Tithe=38 +Blood Tribute=50 +Blood Tyrant=74 Blood Vassal=25 Blood of the Martyr=46 -Bloodbond March=56 -Bloodbraid Elf=185 -Bloodchief Ascension=109 +Bloodbond March=60 +Bloodbraid Elf=197 +Bloodchief Ascension=153 Bloodcrazed Goblin=25 -Bloodcrazed Neonate=62 +Bloodcrazed Neonate=32 Bloodcurdler=49 Bloodcurdling Scream=30 -Bloodfire Colossus=31 +Bloodfire Colossus=62 Bloodfire Dwarf=28 Bloodfire Infusion=28 Bloodfire Kavu=25 -Bloodghast=302 -Bloodgift Demon=48 -Bloodhall Ooze=52 -Bloodhusk Ritualist=35 +Bloodflow Connoisseur=25 +Bloodghast=310 +Bloodgift Demon=40 +Bloodhall Ooze=62 +Bloodhusk Ritualist=34 Bloodied Ghost=25 Bloodletter=28 Bloodletter Quill=25 -Bloodline Keeper=356 +Bloodline Keeper=304 Bloodline Shaman=56 -Bloodlord of Vaasgoth=162 -Bloodmark Mentor=36 +Bloodlord of Vaasgoth=94 +Bloodmark Mentor=65 Bloodpyre Elemental=111 Bloodrage Vampire=25 Bloodrite Invoker=15 @@ -1016,30 +1041,30 @@ Bloodrock Cyclops=27 Bloodscale Prowler=25 Bloodscent=37 Bloodshed Fever=16 -Bloodshot Cyclops=27 +Bloodshot Cyclops=26 Bloodshot Trainee=26 -Bloodstained Mire=1359 +Bloodstained Mire=1445 Bloodstoke Howler=28 Bloodstone Cameo=29 Bloodthirsty Ogre=25 Bloodthorn Taunter=34 -Bloodthrone Vampire=23 -Bloom Tender=142 +Bloodthrone Vampire=37 +Bloom Tender=245 Blossoming Wreath=40 -Blowfly Infestation=85 -Bludgeon Brawl=22 -Blue Elemental Blast=72 -Blue Mana Battery=51 +Blowfly Infestation=35 +Bludgeon Brawl=39 +Blue Elemental Blast=55 +Blue Mana Battery=103 Blue Scarab=25 -Blue Sun's Zenith=72 -Blue Ward=35 -Blunt the Assault=12 -Blurred Mongoose=69 +Blue Sun's Zenith=70 +Blue Ward=42 +Blunt the Assault=28 +Blurred Mongoose=37 Boa Constrictor=25 -Boar Umbra=25 -Boartusk Liege=248 -Body Double=127 -Body Snatcher=99 +Boar Umbra=47 +Boartusk Liege=282 +Body Double=124 +Body Snatcher=90 Body of Jukai=25 Bog Down=29 Bog Elemental=54 @@ -1058,34 +1083,34 @@ Bog Wraith=28 Bog Wreckage=25 Bog-Strider Ash=15 Bogardan Firefiend=27 -Bogardan Hellkite=157 +Bogardan Hellkite=208 Bogardan Lancer=25 -Bogardan Phoenix=42 +Bogardan Phoenix=57 Bogardan Rager=25 Boggart Arsonists=25 Boggart Birth Rite=25 Boggart Forager=25 Boggart Harbinger=40 Boggart Loggers=121 -Boggart Mob=88 -Boggart Ram-Gang=80 -Boggart Shenanigans=46 +Boggart Mob=74 +Boggart Ram-Gang=125 +Boggart Shenanigans=58 Boggart Sprite-Chaser=25 -Boil=12 +Boil=11 Boiling Blood=41 -Boiling Seas=48 -Bojuka Bog=26 +Boiling Seas=84 +Bojuka Bog=31 Bojuka Brigand=25 Bola Warrior=28 Bold Defense=11 Boldwyr Heavyweights=45 Boldwyr Intimidator=25 Bomb Squad=25 -Bond of Agony=71 -Bonded Fetch=38 -Bonds of Faith=20 +Bond of Agony=37 +Bonded Fetch=25 +Bonds of Faith=33 Bonds of Quicksilver=25 -Bone Dancer=158 +Bone Dancer=174 Bone Flute=25 Bone Harvest=25 Bone Mask=49 @@ -1093,267 +1118,274 @@ Bone Saw=42 Bone Shaman=7 Bone Shredder=25 Bone Splinters=25 +Bone to Ash=32 Bonebreaker Giant=13 -Bonehoard=42 +Bonehoard=61 Boneknitter=34 Boneshard Slasher=25 -Bonesplitter=25 +Bonesplitter=30 Bonesplitter Sliver=28 Bonethorn Valesk=25 -Boneyard Wurm=50 -Booby Trap=34 -Book Burning=33 -Book of Rass=17 -Boom/Bust=92 -Boomerang=24 -Boon Reflection=202 -Booster Tutor=46 -Borborygmos=40 +Boneyard Wurm=32 +Bonfire of the Damned=1102 +Booby Trap=43 +Book Burning=44 +Book of Rass=29 +Boom/Bust=175 +Boomerang=27 +Boon Reflection=259 +Booster Tutor=892 +Borborygmos=35 Border Guard=40 Border Patrol=28 -Borderland Behemoth=88 +Borderland Behemoth=45 Borderland Ranger=25 Boreal Centaur=25 Boreal Druid=75 Boreal Griffin=25 -Boreal Shelf=97 -Boris Devilboon=500 +Boreal Shelf=82 +Boris Devilboon=167 Boros Fury-Shield=28 -Boros Garrison=48 +Boros Garrison=51 Boros Guildmage=25 -Boros Recruit=33 -Boros Signet=31 -Boros Swiftblade=38 -Borrowing 100,000 Arrows=494 -Borrowing the East Wind=99 -Boseiju, Who Shelters All=357 -Bosh, Iron Golem=34 -Bosium Strip=25 -Bosk Banneret=25 +Boros Recruit=35 +Boros Signet=47 +Boros Swiftblade=36 +Borrowing 100,000 Arrows=380 +Borrowing the East Wind=498 +Boseiju, Who Shelters All=315 +Bosh, Iron Golem=25 +Bosium Strip=125 +Bosk Banneret=31 Bosom Buddy=25 Bottle Gnomes=42 -Bottle of Suleiman=75 -Bottled Cloister=81 -Bottomless Pit=25 -Bottomless Vault=102 +Bottle of Suleiman=76 +Bottled Cloister=50 +Bottomless Pit=22 +Bottomless Vault=37 Bouncing Beebles=11 Bound in Silence=25 -Bound/Determined=62 -Bounteous Kirin=41 -Bountiful Harvest=32 -Bounty Hunter=15 +Bound/Determined=36 +Bounteous Kirin=79 +Bountiful Harvest=30 +Bounty Hunter=28 Bounty of the Hunt=25 +Bower Passage=25 Brace for Impact=25 Brackwater Elemental=35 -Braid of Fire=397 -Braids, Cabal Minion=110 -Braids, Conjurer Adept=89 +Braid of Fire=511 +Braids, Cabal Minion=109 +Braids, Conjurer Adept=67 Braidwood Cup=25 Braidwood Sextant=25 -Brain Freeze=185 +Brain Freeze=140 Brain Gorgers=40 Brain Pry=25 Brain Weevil=11 Brainbite=25 -Braingeyser=700 -Brainspoil=43 -Brainstorm=179 +Braingeyser=821 +Brainspoil=36 +Brainstorm=131 Brainwash=21 Bramble Creeper=25 Bramble Elemental=25 -Bramblecrush=25 -Bramblesnap=25 -Bramblewood Paragon=95 +Bramblecrush=38 +Bramblesnap=50 +Bramblewood Paragon=98 Branching Bolt=37 Branchsnap Lorian=25 -Brand=205 +Brand=69 Brand of Ill Omen=99 Branded Brawlers=28 Brass Gnat=25 -Brass Herald=57 -Brass Man=62 +Brass Herald=37 +Brass Man=59 Brass Secretary=29 -Brass Squire=43 +Brass Squire=41 Brass-Talon Chimera=42 Brassclaw Orcs=11 Bravado=32 -Brave the Elements=138 -Brawl=31 -Brawn=68 +Brave the Elements=109 +Brawl=26 +Brawn=49 Breach=28 Break Asunder=28 Break Open=70 -Breaking Point=161 +Breaking Point=211 Breaking Wave=25 -Breakthrough=202 +Breakthrough=123 Breath of Darigaaz=25 Breath of Dreams=56 -Breath of Fury=25 -Breath of Life=86 -Breath of Malfegor=40 +Breath of Fury=100 +Breath of Life=85 +Breath of Malfegor=35 Breathstealer=26 -Breathstealer's Crypt=125 -Breeding Pit=12 -Breeding Pool=2470 +Breathstealer's Crypt=75 +Breeding Pit=13 +Breeding Pool=2249 Breezekeeper=25 Briar Patch=25 Briar Shield=25 Briarberry Cohort=40 -Briarhorn=43 +Briarhorn=25 Briarknit Kami=26 -Bribery=1285 -Bridge from Below=1017 +Bribery=1181 +Bridge from Below=1118 Brightflame=56 -Brighthearth Banneret=40 -Brightstone Ritual=28 -Brigid, Hero of Kinsbaile=73 +Brighthearth Banneret=31 +Brightstone Ritual=47 +Brigid, Hero of Kinsbaile=88 Brilliant Halo=41 -Brilliant Plan=192 -Brilliant Ultimatum=25 -Brimstone Dragon=695 -Brimstone Mage=25 -Brimstone Volley=36 -Brindle Boar=35 +Brilliant Plan=99 +Brilliant Ultimatum=100 +Brimstone Dragon=868 +Brimstone Mage=75 +Brimstone Volley=56 +Brindle Boar=16 Brine Elemental=25 Brine Hag=32 -Brine Seer=38 +Brine Seer=41 Brine Shaman=16 -Bringer of the Black Dawn=200 -Bringer of the Blue Dawn=224 -Bringer of the Green Dawn=128 -Bringer of the Red Dawn=157 -Bringer of the White Dawn=163 -Brink of Disaster=35 -Brink of Madness=54 -Brion Stoutarm=102 -Brittle Effigy=37 -Broken Ambitions=40 -Broken Dam=50 +Bringer of the Black Dawn=151 +Bringer of the Blue Dawn=197 +Bringer of the Green Dawn=109 +Bringer of the Red Dawn=142 +Bringer of the White Dawn=137 +Brink of Disaster=30 +Brink of Madness=62 +Brion Stoutarm=133 +Brittle Effigy=32 +Broken Ambitions=37 +Broken Dam=99 Broken Fall=8 Broken Visage=45 Brontotherium=30 -Bronze Bombshell=25 +Bronze Bombshell=64 Bronze Calendar=31 Bronze Horse=81 -Bronze Tablet=95 +Bronze Tablet=91 Brood Birthing=25 -Brood Sliver=115 -Brood of Cockroaches=39 -Broodhatch Nantuko=49 -Brooding Saurian=25 -Broodmate Dragon=1674 -Broodstar=98 -Broodwarden=30 -Brothers Yamazaki=20 +Brood Sliver=143 +Brood of Cockroaches=36 +Broodhatch Nantuko=52 +Brooding Saurian=169 +Broodmate Dragon=366 +Broodstar=100 +Broodwarden=37 +Brothers Yamazaki=25 Brothers of Fire=25 -Browbeat=191 -Brown Ouphe=11 -Browse=28 +Browbeat=186 +Brown Ouphe=25 +Browse=22 +Bruna, Light of Alabaster=369 Brush With Death=29 -Brushland=90 +Brushland=65 Brushstroke Paintermage=28 -Brushwagg=44 +Brushwagg=7 Brutal Deceiver=25 Brutal Nightstalker=62 Brutal Suppression=25 -Brutalizer Exarch=40 -Brute Force=25 -Bubble Matrix=199 +Brutalizer Exarch=25 +Brute Force=100 +Bubble Matrix=78 Bubbling Beebles=28 -Bubbling Muck=56 -Budoka Gardener=109 +Bubbling Muck=58 +Budoka Gardener=85 Budoka Pupil=100 Builder's Bane=28 +Builder's Blessing=31 Bull Aurochs=25 Bull Cerodon=25 Bull Elephant=40 -Bull Hippo=30 +Bull Hippo=23 Bull Rush=30 Bullwhip=31 Bulwark=21 -Bump in the Night=23 +Bump in the Night=41 Buoyancy=25 Burden of Greed=42 Bureaucracy=100 -Burgeoning=326 -Buried Alive=138 -Buried Ruin=35 +Burgeoning=469 +Buried Alive=188 +Buried Ruin=42 Burn Trail=25 -Burn the Impure=35 +Burn at the Stake=60 +Burn the Impure=34 Burning Cinder Fury of Crimson Chaos Fire=127 Burning Cloak=38 Burning Fields=99 -Burning Inquiry=25 +Burning Inquiry=36 Burning Palm Efreet=16 Burning Sands=48 Burning Shield Askari=28 -Burning Vengeance=34 -Burning Wish=524 -Burning of Xinye=3633 +Burning Vengeance=31 +Burning Wish=569 +Burning of Xinye=1333 Burning-Eye Zubera=25 Burning-Tree Bloodscale=25 -Burning-Tree Shaman=120 +Burning-Tree Shaman=199 Burnout=31 -Burnt Offering=21 +Burnt Offering=36 Burr Grafter=25 Burrenton Bombardier=25 -Burrenton Forge-Tender=25 +Burrenton Forge-Tender=31 Burrenton Shield-Bearers=25 -Burrowing=44 -Burst Lightning=39 +Burrowing=36 +Burst Lightning=92 Burst of Energy=40 Burst of Speed=15 Bursting Beebles=28 Bushi Tenderfoot=25 -Butcher Orgg=48 -Butcher of Malakir=77 +Butcher Orgg=100 +Butcher of Malakir=75 Butcher's Cleaver=52 Cabal Archon=45 -Cabal Coffers=600 -Cabal Conditioning=14 +Cabal Coffers=627 +Cabal Conditioning=25 Cabal Executioner=25 Cabal Inquisitor=28 -Cabal Interrogator=46 -Cabal Patriarch=45 +Cabal Interrogator=104 +Cabal Patriarch=25 Cabal Pit=31 -Cabal Ritual=110 +Cabal Ritual=68 Cabal Shrine=31 Cabal Slaver=13 Cabal Surgeon=28 -Cabal Therapy=328 +Cabal Therapy=382 Cabal Torturer=47 Cabal Trainee=16 -Cache Raiders=138 -Cackling Counterpart=35 +Cache Raiders=25 +Cackling Counterpart=34 Cackling Fiend=31 Cackling Flames=25 Cackling Imp=60 -Cackling Witch=40 -Cadaver Imp=25 -Cadaverous Bloom=152 -Cadaverous Knight=23 +Cackling Witch=69 +Cadaver Imp=11 +Cadaverous Bloom=154 +Cadaverous Knight=50 Cage of Hands=39 Caged Sun=104 Cagemail=28 -Cairn Wanderer=150 -Calciderm=32 -Calciform Pools=39 +Cairn Wanderer=211 +Calciderm=26 +Calciform Pools=100 Calcite Snapper=25 Caldera Hellion=23 Caldera Kavu=28 -Caldera Lake=81 +Caldera Lake=145 Call for Blood=25 -Call of the Herd=41 -Call of the Wild=23 -Call the Skybreaker=49 +Call of the Herd=104 +Call of the Wild=37 +Call the Skybreaker=29 Call to Arms=11 Call to Glory=37 Call to Heel=45 -Call to Mind=49 -Call to the Grave=56 -Call to the Netherworld=35 +Call to Mind=30 +Call to the Grave=47 +Call to the Kindred=39 +Call to the Netherworld=25 Caller of Gales=25 -Caller of the Claw=115 +Caller of the Claw=147 Caller of the Hunt=50 Callous Deceiver=25 Callous Giant=25 @@ -1361,73 +1393,74 @@ Callous Oppressor=49 Callow Jushi=25 Calming Licid=37 Calming Verse=25 -Caltrops=25 +Caltrops=27 Camel=25 -Camouflage=105 -Cancel=29 -Candelabra of Tawnos=13920 +Camouflage=139 +Cancel=32 +Candelabra of Tawnos=17124 Candles of Leng=25 Candles' Glow=25 Canker Abomination=25 Cankerous Thirst=25 -Cannibalize=25 +Cannibalize=15 Canopy Claws=28 Canopy Cover=25 Canopy Crawler=27 -Canopy Dragon=99 +Canopy Dragon=25 Canopy Spider=29 Canopy Surge=25 Cantivore=25 Canyon Drake=29 Canyon Minotaur=38 Canyon Wildcat=28 -Cao Cao, Lord of Wei=142 +Cao Cao, Lord of Wei=1031 Cao Ren, Wei Commander=1695 Capashen Knight=40 Capashen Standard=25 Capashen Templar=28 Capashen Unicorn=100 -Capricious Efreet=25 +Capricious Efreet=99 Capricious Sorcerer=220 -Capsize=55 -Captain Sisay=156 -Captain of the Watch=297 -Captain's Maneuver=24 +Capsize=61 +Captain Sisay=201 +Captain of the Mists=52 +Captain of the Watch=412 +Captain's Maneuver=100 Captivating Glance=25 -Captivating Vampire=368 +Captivating Vampire=341 Captive Flame=25 -Capture of Jingzhou=20000 +Capture of Jingzhou=15975 Captured Sunlight=25 Carapace=28 Carapace Forger=25 -Caravan Escort=25 +Caravan Escort=30 Caravan Hurda=11 -Caravan Vigil=25 +Caravan Vigil=32 Carbonize=50 -Cardboard Carapace=231 +Cardboard Carapace=178 Cardpecker=40 Careful Consideration=30 -Careful Study=123 +Careful Study=67 Caregiver=25 -Caress of Phyrexia=25 +Caress of Phyrexia=34 Caribou Range=54 Carnage Altar=25 Carnage Wurm=38 Carnassid=49 -Carnifex Demon=35 -Carnival of Souls=37 +Carnifex Demon=64 +Carnival of Souls=100 Carnivorous Death-Parrot=26 Carnivorous Plant=16 -Carnophage=39 +Carnophage=29 Carom=25 -Carpet of Flowers=75 +Carpet of Flowers=2140 Carrier Pigeons=28 Carrion=145 -Carrion Ants=182 +Carrion Ants=101 Carrion Beetles=25 Carrion Call=31 -Carrion Feeder=28 -Carrion Howler=25 +Carrion Feeder=32 +Carrion Howler=35 Carrion Rats=44 Carrion Thrash=25 Carrion Wall=25 @@ -1435,23 +1468,23 @@ Carrion Wurm=40 Carrionette=71 Carry Away=25 Cartographer=23 -Carven Caryatid=43 -Cascade Bluffs=942 -Cast Through Time=100 -Castigate=16 -Casting of Bones=25 -Castle=33 +Carven Caryatid=50 +Cascade Bluffs=910 +Cast Through Time=81 +Castigate=25 +Casting of Bones=15 +Castle=26 Castle Raptors=25 -Castle Sengir=50 +Castle Sengir=19 Cat Burglar=52 Cat Warriors=26 -Cataclysm=327 -Catacomb Dragon=203 +Cataclysm=155 +Catacomb Dragon=100 Catalog=9 -Catalyst Stone=58 -Catapult Master=12 +Catalyst Stone=48 +Catapult Master=48 Catapult Squad=40 -Catastrophe=310 +Catastrophe=208 Cateran Brute=29 Cateran Enforcer=16 Cateran Kidnappers=29 @@ -1460,50 +1493,52 @@ Cateran Persuader=599 Cateran Slaver=20 Cateran Summons=44 Caterwauling Boggart=15 +Cathars' Crusade=77 Cathartic Adept=24 -Cathedral Membrane=25 -Cathedral of Serra=114 +Cathedral Membrane=37 +Cathedral of Serra=149 Cathodion=43 Cauldron Dance=45 Cauldron Haze=39 -Cauldron of Souls=215 +Cauldron of Souls=55 Caustic Crawler=25 Caustic Hound=50 -Caustic Rain=56 -Caustic Tar=31 +Caustic Rain=25 +Caustic Tar=25 Caustic Wasps=41 Cautery Sliver=25 -Cavalry Master=12 +Cavalry Master=25 Cave People=26 Cave Sense=12 Cave Tiger=16 -Cave-In=56 +Cave-In=72 Cavern Crawler=28 Cavern Harpy=25 Cavern Thoctar=25 -Caverns of Despair=238 -Caves of Koilos=197 +Cavern of Souls=2151 +Caverns of Despair=224 +Caves of Koilos=294 Cease-Fire=28 Ceaseless Searblades=56 -Celestial Ancient=72 -Celestial Colonnade=224 -Celestial Convergence=88 -Celestial Crusader=25 -Celestial Dawn=29 +Celestial Ancient=119 +Celestial Colonnade=253 +Celestial Convergence=74 +Celestial Crusader=34 +Celestial Dawn=39 Celestial Gatekeeper=11 Celestial Kirin=100 -Celestial Mantle=86 -Celestial Prism=52 -Celestial Purge=45 +Celestial Mantle=132 +Celestial Prism=57 +Celestial Purge=76 Celestial Sword=28 -Cellar Door=66 +Cellar Door=67 Cemetery Gate=50 -Cemetery Puca=117 -Cemetery Reaper=257 +Cemetery Puca=100 +Cemetery Reaper=189 Cenn's Enlistment=25 Cenn's Heir=25 -Cenn's Tactician=47 -Censorship=89 +Cenn's Tactician=37 +Censorship=100 Centaur Archer=30 Centaur Chieftain=25 Centaur Courser=25 @@ -1511,11 +1546,11 @@ Centaur Garden=25 Centaur Glade=93 Centaur Omenreader=25 Centaur Rootcaster=25 -Centaur Safeguard=31 +Centaur Safeguard=25 Centaur Veteran=40 Cephalid Aristocrat=28 -Cephalid Broker=25 -Cephalid Coliseum=335 +Cephalid Broker=38 +Cephalid Coliseum=322 Cephalid Constable=56 Cephalid Illusionist=34 Cephalid Inkshrouder=25 @@ -1527,74 +1562,76 @@ Cephalid Scout=28 Cephalid Shrine=25 Cephalid Snitch=28 Cephalid Vandal=79 -Cerebral Eruption=28 -Cerebral Vortex=25 +Cerebral Eruption=46 +Cerebral Vortex=88 Ceremonial Guard=28 -Cerodon Yearling=25 -Cerulean Sphinx=85 +Cerodon Yearling=45 +Cerulean Sphinx=37 Cerulean Wisps=40 Cessation=25 Ceta Disciple=28 Ceta Sanctuary=40 Cetavolver=25 -Chain Lightning=934 -Chain Reaction=47 +Chain Lightning=1145 +Chain Reaction=31 Chain Stasis=40 Chain of Acid=25 Chain of Plasma=12 Chain of Silence=25 Chain of Smog=40 -Chain of Vapor=111 +Chain of Vapor=136 Chainbreaker=40 Chained Throatseeker=12 -Chainer's Edict=95 -Chainer, Dementia Master=50 +Chainer's Edict=63 +Chainer, Dementia Master=49 Chainflinger=27 -Chains of Mephistopheles=5643 -Chalice of the Void=648 +Chains of Mephistopheles=5342 +Chalice of Life=58 +Chalice of the Void=612 Chamber of Manipulation=47 Chambered Nautilus=25 Chameleon Blur=25 -Chameleon Colossus=224 +Chameleon Colossus=186 Chameleon Spirit=79 -Champion Lancer=334 -Champion of the Parish=323 +Champion Lancer=448 +Champion of Lambholt=144 +Champion of the Parish=408 Champion's Drake=25 Champion's Victory=100 -Chance Encounter=95 -Chancellor of the Annex=30 -Chancellor of the Dross=41 -Chancellor of the Forge=30 +Chance Encounter=57 +Chancellor of the Annex=54 +Chancellor of the Dross=50 +Chancellor of the Forge=40 Chancellor of the Spires=52 -Chancellor of the Tangle=51 +Chancellor of the Tangle=61 Chandler=99 -Chandra Ablaze=315 -Chandra Nalaar=281 -Chandra's Outrage=35 -Chandra's Phoenix=464 -Chandra's Spitfire=67 -Chandra, the Firebrand=708 +Chandra Ablaze=434 +Chandra Nalaar=310 +Chandra's Outrage=45 +Chandra's Phoenix=332 +Chandra's Spitfire=1262 +Chandra, the Firebrand=560 Change of Heart=40 Changeling Berserker=46 Changeling Hero=25 -Changeling Sentinel=25 -Changeling Titan=25 -Channel=115 -Channel the Suns=50 -Chant of Vitu-Ghazi=24 +Changeling Sentinel=40 +Changeling Titan=38 +Channel=119 +Channel the Suns=49 +Chant of Vitu-Ghazi=36 Chaos Charm=31 -Chaos Confetti=52 -Chaos Harlequin=99 +Chaos Confetti=56 +Chaos Harlequin=29 Chaos Lord=15 Chaos Moon=62 -Chaos Orb=4844 -Chaoslace=245 -Chaosphere=79 +Chaos Orb=3857 +Chaoslace=247 +Chaosphere=99 Chaotic Backlash=56 Chaotic Goo=103 Chaotic Strike=25 Chapel Geist=14 -Char=25 +Char=69 Char-Rumbler=25 Charcoal Diamond=51 Charge Across the Araba=50 @@ -1604,112 +1641,114 @@ Charging Rhino=126 Charging Slateback=10 Charging Troll=25 Chariot of the Sun=7 -Charisma=249 +Charisma=251 Charm Peddler=28 Charm School=31 -Charmbreaker Devils=28 +Charmbreaker Devils=32 Charmed Griffin=25 Charmed Pendant=50 -Charnelhoard Wurm=67 +Charnelhoard Wurm=99 Chartooth Cougar=25 -Chasm Drake=30 -Chastise=27 -Chatter of the Squirrel=40 -Cheap Ass=32 -Cheatyface=104 +Chasm Drake=35 +Chastise=26 +Chatter of the Squirrel=38 +Cheap Ass=40 +Cheatyface=201 Checks and Balances=31 Chicken Egg=25 Chicken a la King=257 Chieftain en-Dal=25 -Child of Alara=169 -Child of Gaea=80 +Child of Alara=177 +Child of Gaea=174 Child of Night=28 Child of Thorns=25 Childhood Horror=25 Children of Korlis=28 -Chill=36 +Chill=105 Chill Haunting=25 +Chill of Foreboding=25 Chill to the Bone=79 Chilling Apparition=38 Chilling Shade=25 -Chime of Night=25 +Chime of Night=40 Chimeric Coils=25 Chimeric Egg=31 Chimeric Idol=39 -Chimeric Mass=39 +Chimeric Mass=35 Chimeric Sphere=25 Chimeric Staff=30 Chimney Imp=25 Chisei, Heart of Oceans=25 -Chittering Rats=25 -Chlorophant=92 +Chittering Rats=31 +Chlorophant=93 Cho-Arrim Alchemist=100 Cho-Arrim Bruiser=50 Cho-Arrim Legate=25 Cho-Manno's Blessing=32 Cho-Manno, Revolutionary=64 -Choice of Damnations=197 -Choke=77 -Choking Fumes=33 -Choking Sands=39 +Choice of Damnations=285 +Choke=93 +Choking Fumes=34 +Choking Sands=25 Choking Tethers=28 -Choking Vines=40 -Chord of Calling=659 +Choking Vines=25 +Chord of Calling=800 Chorus of Woe=28 -Chorus of the Conclave=63 +Chorus of the Conclave=25 +Chosen of Markov=28 Chromatic Armor=25 -Chromatic Sphere=28 -Chromatic Star=28 -Chrome Mox=972 +Chromatic Sphere=44 +Chromatic Star=23 +Chrome Mox=968 Chrome Steed=25 -Chromescale Drake=79 -Chromeshell Crab=100 -Chromium=84 -Chronatog=17 +Chromescale Drake=50 +Chromeshell Crab=11 +Chromium=268 +Chronatog=149 Chronatog Totem=29 Chronomantic Escape=43 -Chronosavant=8 -Chronozoa=99 +Chronosavant=34 +Chronozoa=215 Chub Toad=63 Churning Eddy=32 Cinder Cloud=25 Cinder Crawler=28 Cinder Elemental=29 Cinder Giant=25 -Cinder Marsh=39 -Cinder Pyromancer=42 -Cinder Seer=56 +Cinder Marsh=25 +Cinder Pyromancer=52 +Cinder Seer=40 Cinder Shade=25 Cinder Storm=171 Cinder Wall=22 Cinderbones=25 Cinderhaze Wretch=25 -Circle of Affliction=25 -Circle of Despair=74 +Circle of Affliction=50 +Circle of Despair=50 Circle of Flame=25 Circle of Protection: Artifacts=27 -Circle of Protection: Black=44 +Circle of Protection: Black=43 Circle of Protection: Blue=13 -Circle of Protection: Green=35 -Circle of Protection: Red=23 +Circle of Protection: Green=34 +Circle of Protection: Red=11 Circle of Protection: Shadow=10 Circle of Protection: White=27 Circle of Solace=10 Circling Vultures=32 -Circu, Dimir Lobotomist=260 -Circular Logic=105 +Circu, Dimir Lobotomist=245 +Circular Logic=130 Citadel of Pain=40 Citanul Centaurs=16 -Citanul Druid=79 -Citanul Flute=34 -Citanul Hierophants=100 +Citanul Druid=150 +Citanul Flute=25 +Citanul Hierophants=33 Citanul Woodreaders=28 -City in a Bottle=1216 -City of Ass=251 -City of Brass=382 -City of Shadows=74 -City of Solitude=250 -City of Traitors=1939 +City in a Bottle=830 +City of Ass=239 +City of Brass=289 +City of Shadows=150 +City of Solitude=249 +City of Traitors=2267 Civic Guildmage=25 Civic Wayfinder=25 Civilized Scholar=25 @@ -1717,211 +1756,214 @@ Clairvoyance=16 Clam Session=25 Clam-I-Am=25 Clambassadors=25 -Clarion Ultimatum=39 +Clarion Ultimatum=49 Clash of Realities=25 -Claustrophobia=25 -Claws of Gix=26 -Claws of Valakut=25 +Claustrophobia=14 +Claws of Gix=22 +Claws of Valakut=38 Claws of Wirewood=25 -Clay Pigeon=30 +Clay Pigeon=31 Clay Statue=27 Cleanfall=40 -Cleanse=838 -Cleansing=103 +Cleanse=655 +Cleansing=149 Cleansing Beam=25 Cleansing Meditation=25 -Clear=25 +Clear=33 Clear the Land=100 Clearwater Goblet=93 Clergy en-Vec=38 Clergy of the Holy Nimbus=25 Clickslither=25 Cliff Threader=25 -Cliffrunner Behemoth=46 -Clifftop Retreat=229 +Cliffrunner Behemoth=35 +Clifftop Retreat=356 Clinging Darkness=25 -Cloak and Dagger=37 +Cloak and Dagger=25 Cloak of Confusion=28 Cloak of Feathers=38 Cloak of Invisibility=25 Cloak of Mists=25 -Clock of Omens=31 -Clockspinning=28 +Clock of Omens=25 +Clockspinning=100 Clockwork Avian=109 -Clockwork Beast=125 +Clockwork Beast=112 Clockwork Beetle=25 Clockwork Condor=25 -Clockwork Dragon=125 +Clockwork Dragon=60 Clockwork Gnomes=50 Clockwork Hydra=25 Clockwork Steed=22 Clockwork Swarm=25 Clockwork Vorrac=37 Cloistered Youth=25 -Clone=61 +Clone=23 Clone Shell=25 Close Quarters=25 -Clot Sliver=31 -Cloud Cover=68 +Clot Sliver=34 +Cloud Cover=99 Cloud Crusader=13 Cloud Djinn=25 -Cloud Dragon=426 +Cloud Dragon=217 Cloud Elemental=22 -Cloud Key=145 -Cloud Pirates=46 +Cloud Key=351 +Cloud Pirates=49 Cloud Spirit=50 -Cloud Sprite=27 -Cloud of Faeries=43 +Cloud Sprite=826 +Cloud of Faeries=62 Cloudchaser Eagle=33 Cloudchaser Kestrel=25 -Cloudcrest Lake=40 +Cloudcrest Lake=150 Cloudcrown Oak=25 -Cloudgoat Ranger=28 +Cloudgoat Ranger=25 Cloudheath Drake=25 Cloudhoof Kirin=99 -Cloudpost=123 -Cloudreach Cavalry=37 +Cloudpost=93 +Cloudreach Cavalry=25 Cloudseeder=25 +Cloudshift=37 Cloudskate=38 -Cloudstone Curio=269 -Cloudthresher=119 +Cloudstone Curio=175 +Cloudthresher=57 Clout of the Dominus=42 -Cloven Casting=62 +Cloven Casting=25 Clutch of Undeath=25 -Clutch of the Undercity=25 +Clutch of the Undercity=36 Coal Golem=50 Coal Stoker=25 Coalhauler Swine=25 Coalition Flag=25 -Coalition Relic=259 -Coalition Victory=99 -Coast Watcher=29 +Coalition Relic=284 +Coalition Victory=79 +Coast Watcher=37 Coastal Drake=25 Coastal Hornclaw=28 -Coastal Piracy=40 -Coastal Tower=40 +Coastal Piracy=37 +Coastal Tower=52 Coastal Wizard=99 -Coat of Arms=199 +Coat of Arms=185 Cobalt Golem=25 -Cobbled Wings=34 +Cobbled Wings=32 Cobra Trap=25 -Cockatrice=181 +Cockatrice=176 Cocoon=37 Coercion=27 -Coffin Puppets=71 +Coffin Puppets=33 Coffin Purge=25 -Coffin Queen=292 -Cognivore=25 +Coffin Queen=344 +Cognivore=100 Coiled Tinviper=28 -Coiling Oracle=93 +Coiling Oracle=63 Coiling Woodworm=44 Coils of the Medusa=25 Cold Snap=1984 -Cold Storage=88 -Cold-Eyed Selkie=221 -Coldsteel Heart=69 +Cold Storage=25 +Cold-Eyed Selkie=332 +Coldsteel Heart=61 Colfenor's Plans=25 -Colfenor's Urn=47 +Colfenor's Urn=25 Collapsing Borders=25 -Collective Restraint=175 -Collective Unconscious=89 +Collective Restraint=143 +Collective Unconscious=87 Collector Protector=100 Colos Yearling=28 -Colossal Might=30 -Colossus of Sardia=81 +Colossal Might=35 +Colossus of Sardia=118 Coma Veil=25 Combat Medic=25 -Combust=19 -Comet Storm=63 +Combust=22 +Comet Storm=77 Command of Unsummoning=56 -Commandeer=99 -Commander Eesha=26 -Commander Greven il-Vec=104 +Commandeer=149 +Commander Eesha=180 +Commander Greven il-Vec=116 +Commander's Authority=34 Commando Raid=25 Commune with Nature=27 Complex Automaton=8 Complicate=100 -Composite Golem=26 +Composite Golem=23 Compost=38 Compulsion=17 -Compulsive Research=38 -Concentrate=50 -Concerted Effort=156 -Conch Horn=40 -Conclave Equenaut=25 -Conclave Phalanx=46 +Compulsive Research=37 +Concentrate=42 +Concerted Effort=205 +Conch Horn=43 +Conclave Equenaut=35 +Conclave Phalanx=31 Conclave's Blessing=25 -Concordant Crossroads=593 +Concordant Crossroads=570 Concussive Bolt=23 -Condemn=53 -Condescend=30 +Condemn=26 +Condescend=26 Cone of Flame=27 Confessor=25 -Confiscate=20 +Confiscate=23 Conflagrate=25 Confound=58 -Confusion in the Ranks=85 -Congregate=32 -Congregation at Dawn=45 +Confusion in the Ranks=100 +Congregate=158 +Congregation at Dawn=67 Conjurer's Ban=25 Conjurer's Bauble=25 +Conjurer's Closet=50 Conquer=25 -Conquering Manticore=57 -Conqueror's Pledge=34 -Consecrate Land=103 -Consecrated Sphinx=807 -Conservator=38 +Conquering Manticore=39 +Conqueror's Pledge=50 +Consecrate Land=192 +Consecrated Sphinx=607 +Conservator=40 Consign to Dream=25 -Conspiracy=85 -Constant Mists=72 +Conspiracy=97 +Constant Mists=36 Constricting Tendrils=25 Consult the Necrosages=43 -Consume Spirit=23 -Consume Strength=25 -Consume the Meek=50 +Consume Spirit=24 +Consume Strength=19 +Consume the Meek=65 Consuming Bonfire=25 Consuming Ferocity=25 -Consuming Vapors=99 +Consuming Vapors=119 Consuming Vortex=25 -Consumptive Goo=46 -Contagion=41 -Contagion Clasp=30 -Contagion Engine=83 -Contagious Nim=37 +Consumptive Goo=25 +Contagion=27 +Contagion Clasp=67 +Contagion Engine=56 +Contagious Nim=25 Contaminated Bond=23 -Contaminated Ground=30 -Contamination=234 +Contaminated Ground=28 +Contamination=87 Contemplation=25 Contempt=20 -Contested Cliffs=121 -Contested War Zone=64 -Contract from Below=327 -Control Magic=90 +Contested Cliffs=62 +Contested War Zone=41 +Contract from Below=252 +Control Magic=92 Control of the Court=200 Controlled Instincts=41 Controvert=31 -Conundrum Sphinx=25 -Convalescence=49 +Conundrum Sphinx=50 +Convalescence=100 Convalescent Care=85 Conversion=42 -Conversion Chamber=38 -Conviction=40 +Conversion Chamber=33 +Conviction=99 Convincing Mirage=25 -Convolute=12 +Convolute=35 Convulsing Licid=25 Cooperation=999 Coordinated Barrage=25 Copper Carapace=13 -Copper Gnomes=170 -Copper Myr=27 -Copper Tablet=142 -Copper-Leaf Angel=29 +Copper Gnomes=89 +Copper Myr=25 +Copper Tablet=288 +Copper-Leaf Angel=100 Copperhoof Vorrac=62 -Copperhorn Scout=25 -Copperline Gorge=635 -Copy Artifact=477 -Copy Enchantment=140 -Coral Atoll=68 +Copperhorn Scout=33 +Copperline Gorge=661 +Copy Artifact=434 +Copy Enchantment=194 +Coral Atoll=100 Coral Eel=30 Coral Fighters=15 Coral Helm=89 @@ -1929,224 +1971,232 @@ Coral Merfolk=124 Coral Net=28 Coral Reef=2000 Coral Trickster=99 -Coralhelm Commander=243 +Coralhelm Commander=225 Core Prowler=31 -Coretapper=90 -Cornered Market=43 +Coretapper=124 +Cornered Market=45 Corpse Connoisseur=25 -Corpse Cur=25 -Corpse Dance=149 -Corpse Harvester=67 -Corpse Lunge=16 +Corpse Cur=28 +Corpse Dance=222 +Corpse Harvester=75 +Corpse Lunge=11 Corpsehatch=25 Corpulent Corpse=25 -Corrosion=47 -Corrosive Gale=35 -Corrosive Mentor=47 -Corrupt=24 +Corrosion=33 +Corrosive Gale=68 +Corrosive Mentor=126 +Corrupt=25 Corrupt Court Official=450 -Corrupt Eunuchs=50 -Corrupt Official=30 -Corrupted Conscience=36 +Corrupt Eunuchs=150 +Corrupt Official=119 +Corrupted Conscience=46 Corrupted Harvester=16 -Corrupted Resolve=46 +Corrupted Resolve=45 Corrupted Roots=25 Corrupted Zendikon=47 Corrupting Licid=25 Cosi's Ravager=25 -Cosi's Trickster=54 -Cosmic Horror=70 +Cosi's Trickster=28 +Cosmic Horror=84 Cosmic Larva=25 -Council of Advisors=50 +Council of Advisors=99 Counsel of the Soratami=7 -Counterbalance=463 -Counterbore=80 -Counterintelligence=195 -Counterspell=99 -Countersquall=88 -Countryside Crusher=172 +Counterbalance=519 +Counterbore=52 +Counterintelligence=350 +Counterlash=37 +Counterspell=142 +Countersquall=130 +Countryside Crusher=165 Courier Hawk=40 Courier's Capsule=45 Court Archers=35 Court Homunculus=25 -Court Hussar=36 -Covenant of Minds=30 -Cover of Darkness=94 +Court Hussar=30 +Covenant of Minds=79 +Cover of Darkness=158 Cover of Winter=28 Covert Operative=28 -Covetous Dragon=77 -Cowardice=93 +Covetous Dragon=178 +Cowardice=87 Cowed by Wisdom=25 Crab Umbra=25 Crabapple Cohort=15 Crack the Earth=25 -Crackdown=102 -Crackleburr=203 +Crackdown=116 +Crackleburr=63 Crackling Club=28 -Cradle Guard=31 -Cradle of Vitality=122 +Cradle Guard=30 +Cradle of Vitality=113 Cradle to Grave=25 Crafty Pathmage=29 Crag Puca=25 Crag Saurian=25 -Cragganwick Cremator=79 -Cranial Extraction=133 -Cranial Plating=213 +Cragganwick Cremator=25 +Cranial Extraction=77 +Cranial Plating=101 Crash=40 -Crash Landing=52 +Crash Landing=25 Crash of Rhinos=41 Crashing Boars=25 Crashing Centaur=25 -Crater Hellion=245 +Crater Hellion=88 +Craterhoof Behemoth=176 Craven Giant=27 Craven Knight=36 -Craw Giant=23 -Craw Wurm=25 +Craw Giant=25 +Craw Wurm=24 Crawling Filth=35 -Crawlspace=93 +Crawlspace=149 Crazed Armodon=49 Crazed Firecat=25 Crazed Goblin=25 Crazed Skirge=25 Creakwood Ghoul=40 -Creakwood Liege=569 -Cream of the Crop=88 +Creakwood Liege=540 +Cream of the Crop=58 Creature Bond=30 Creature Guy=25 -Credit Voucher=40 -Creeping Corrosion=48 +Credit Voucher=25 +Creeping Corrosion=52 Creeping Mold=27 -Creeping Renaissance=27 -Creeping Tar Pit=268 -Creepy Doll=29 +Creeping Renaissance=30 +Creeping Tar Pit=259 +Creepy Doll=32 Cremate=25 Crenellated Wall=24 Crested Craghorn=27 Crevasse=99 -Crib Swap=92 -Crime/Punishment=100 +Crib Swap=48 +Crime/Punishment=80 Crimson Acolyte=16 -Crimson Hellkite=99 -Crimson Kobolds=151 +Crimson Hellkite=132 +Crimson Kobolds=81 Crimson Mage=35 -Crimson Manticore=52 +Crimson Manticore=34 Crimson Roc=25 Crimson Wisps=27 +Crippling Chill=25 Crippling Fatigue=22 -Cromat=146 +Cromat=49 Crookclaw Elder=25 Crookclaw Transmuter=25 Crooked Scales=10 -Crookshank Kobolds=76 -Crop Rotation=37 +Crookshank Kobolds=47 +Crop Rotation=40 Crosis's Attendant=25 -Crosis's Catacombs=65 +Crosis's Catacombs=74 Crosis's Charm=25 -Crosis, the Purger=238 +Crosis, the Purger=301 Crossbow Ambush=100 Crossbow Infantry=28 Crossway Vampire=50 Crosswinds=40 Crovax the Cursed=25 -Crovax, Ascendant Hero=97 +Crovax, Ascendant Hero=140 Crowd Favorites=25 Crowd of Cinders=25 Crown of Ascension=28 Crown of Awe=47 -Crown of Convergence=60 -Crown of Empires=39 +Crown of Convergence=35 +Crown of Empires=25 Crown of Flames=45 Crown of Fury=25 Crown of Suspicion=25 Crown of Vigor=29 Crown of the Ages=78 -Crucible of Fire=232 -Crucible of Worlds=2141 +Crucible of Fire=189 +Crucible of Worlds=1894 Crude Rampart=25 -Cruel Bargain=1174 +Cruel Bargain=1115 Cruel Deceiver=25 -Cruel Edict=12 +Cruel Edict=10 Cruel Fate=113 -Cruel Revival=45 -Cruel Tutor=1509 -Cruel Ultimatum=62 -Crumble=24 -Crumbling Ashes=70 +Cruel Revival=38 +Cruel Tutor=1555 +Cruel Ultimatum=92 +Crumble=12 +Crumbling Ashes=54 Crumbling Colossus=35 -Crumbling Necropolis=83 +Crumbling Necropolis=104 Crumbling Sanctuary=100 -Crusade=134 -Crusading Knight=121 -Crush=30 +Crusade=207 +Crusading Knight=168 +Crush=32 Crush Underfoot=25 -Crush of Wurms=97 +Crush of Wurms=111 Crusher Zendikon=40 Crushing Pain=36 -Cry of Contrition=43 -Cryoclasm=23 -Crypt Angel=157 +Crushing Vines=35 +Cry of Contrition=25 +Cryoclasm=20 +Crypt Angel=125 Crypt Champion=25 -Crypt Cobra=50 -Crypt Creeper=25 -Crypt Rats=23 -Crypt Ripper=25 -Crypt Sliver=38 -Crypt of Agadeem=49 +Crypt Cobra=100 +Crypt Rats=87 +Crypt Ripper=11 +Crypt Sliver=25 +Crypt of Agadeem=75 Cryptic Annelid=25 -Cryptic Command=1398 -Cryptic Gateway=133 -Cryptoplasm=47 +Cryptic Command=1224 +Cryptic Gateway=205 +Cryptoplasm=38 Cryptwailing=25 -Crystal Ball=44 +Crystal Ball=40 Crystal Chimes=28 Crystal Golem=29 -Crystal Quarry=234 -Crystal Rod=49 +Crystal Quarry=193 +Crystal Rod=51 Crystal Seer=300 -Crystal Shard=85 +Crystal Shard=137 Crystal Spray=25 -Crystal Vein=31 -Crystalline Sliver=243 -Crystallization=47 +Crystal Vein=37 +Crystalline Sliver=269 +Crystallization=30 Cudgel Troll=16 -Culling Dais=25 -Culling Scales=71 +Culling Dais=35 +Culling Scales=64 Culling Sun=25 -Culling the Weak=68 +Culling the Weak=69 Cultbrand Cinder=25 -Cultivate=35 -Cultural Exchange=121 +Cultivate=25 +Cultural Exchange=108 Cumber Stone=25 Cunning=99 -Cunning Advisor=56 +Cunning Advisor=127 Cunning Bandit=25 Cunning Giant=112 Cunning Lethemancer=25 -Cunning Sparkmage=33 -Cunning Wish=382 -Cuombajj Witches=45 +Cunning Sparkmage=62 +Cunning Wish=430 +Cuombajj Witches=41 Curfew=16 -Curiosity=25 +Curiosity=48 Curse Artifact=25 -Curse of Chains=25 -Curse of Death's Hold=58 +Curse of Bloodletting=36 +Curse of Chains=38 +Curse of Death's Hold=52 +Curse of Echoes=32 +Curse of Exhaustion=25 Curse of Marit Lage=49 +Curse of Misfortunes=30 Curse of Oblivion=12 -Curse of Stalked Prey=42 -Curse of Wizardry=35 -Curse of the Bloody Tome=30 -Curse of the Cabal=62 +Curse of Stalked Prey=34 +Curse of Thirst=27 +Curse of Wizardry=25 +Curse of the Bloody Tome=78 +Curse of the Cabal=56 Curse of the Fire Penguin=100 -Curse of the Nightly Hunt=50 -Curse of the Pierced Heart=25 -Cursecatcher=189 +Curse of the Nightly Hunt=34 +Curse of the Pierced Heart=30 +Cursecatcher=265 Cursed Flesh=213 -Cursed Land=28 +Cursed Land=24 Cursed Monstrosity=49 -Cursed Rack=44 -Cursed Ronin=29 -Cursed Scroll=613 -Cursed Totem=170 +Cursed Rack=63 +Cursed Ronin=25 +Cursed Scroll=841 +Cursed Totem=119 Curtain of Light=40 Custody Battle=25 Customs Depot=20 @@ -2155,17 +2205,17 @@ Cut the Tethers=25 Cutthroat il-Dal=25 Cycle of Life=25 Cyclical Evolution=50 -Cyclone=101 +Cyclone=98 Cyclopean Giant=25 -Cyclopean Mummy=26 +Cyclopean Mummy=25 Cyclopean Snare=25 -Cyclopean Tomb=2272 +Cyclopean Tomb=1540 Cyclops Gladiator=25 Cylian Elf=47 -Cylian Sunsinger=29 +Cylian Sunsinger=25 Cystbearer=25 -Cytoplast Manipulator=154 -Cytoplast Root-Kin=44 +Cytoplast Manipulator=71 +Cytoplast Root-Kin=86 Cytoshape=37 Cytospawn Shambler=25 D'Avenant Archer=25 @@ -2173,203 +2223,209 @@ D'Avenant Healer=25 Daggerback Basilisk=25 Daggerclaw Imp=25 Daily Regimen=25 -Dakkon Blackblade=440 +Dakkon Blackblade=320 Dakmor Bat=40 -Dakmor Ghoul=340 +Dakmor Ghoul=250 Dakmor Lancer=25 Dakmor Plague=44 -Dakmor Salvage=75 +Dakmor Salvage=50 Dakmor Scorpion=42 -Dakmor Sorceress=226 -Damnation=1864 -Dampen Thought=69 +Dakmor Sorceress=231 +Damnation=2028 +Dampen Thought=44 Damping Engine=45 Damping Field=189 -Damping Matrix=100 +Damping Matrix=110 Dance of Many=83 Dance of Shadows=25 -Dance of the Dead=108 -Dancing Scimitar=108 +Dance of the Dead=92 +Dancing Scimitar=135 Dandan=26 -Daraja Griffin=9 +Dangerous Wager=12 +Daraja Griffin=13 Darba=25 -Darien, King of Kjeldor=271 +Darien, King of Kjeldor=305 Darigaaz's Attendant=25 -Darigaaz's Caldera=46 +Darigaaz's Caldera=150 Darigaaz's Charm=25 -Darigaaz, the Igniter=110 +Darigaaz, the Igniter=57 Daring Apprentice=39 Daring Leap=48 -Dark Banishing=16 -Dark Confidant=3609 -Dark Depths=1604 +Dark Banishing=10 +Dark Confidant=3480 +Dark Depths=1351 Dark Favor=38 Dark Hatchling=25 Dark Heart of the Wood=22 +Dark Impostor=64 Dark Maze=526 Dark Offering=28 Dark Privilege=25 -Dark Ritual=85 -Dark Sphere=69 +Dark Ritual=59 +Dark Sphere=84 Dark Supplicant=40 Dark Suspicions=62 Dark Temper=25 Dark Triumph=25 -Dark Tutelage=27 +Dark Tutelage=25 Dark Withering=25 -Darkblast=25 -Darkest Hour=44 +Darkblast=45 +Darkest Hour=94 Darkheart Sliver=75 Darkling Stalker=38 Darklit Gargoyle=25 -Darkness=97 -Darkpact=454 -Darkslick Drake=37 -Darkslick Shores=1310 -Darksteel Axe=12 +Darkness=248 +Darkpact=198 +Darkslick Drake=35 +Darkslick Shores=1048 +Darksteel Axe=56 Darksteel Brute=40 -Darksteel Citadel=95 -Darksteel Colossus=384 -Darksteel Forge=883 -Darksteel Gargoyle=25 -Darksteel Garrison=62 -Darksteel Ingot=24 -Darksteel Myr=30 +Darksteel Citadel=114 +Darksteel Colossus=348 +Darksteel Forge=768 +Darksteel Gargoyle=58 +Darksteel Garrison=99 +Darksteel Ingot=30 +Darksteel Myr=28 Darksteel Pendant=25 -Darksteel Plate=137 -Darksteel Reactor=143 -Darksteel Relic=50 -Darksteel Sentinel=26 +Darksteel Plate=145 +Darksteel Reactor=228 +Darksteel Relic=45 +Darksteel Sentinel=35 Darkthicket Wolf=34 -Darkwatch Elves=38 -Darkwater Catacombs=133 -Darkwater Egg=25 +Darkwatch Elves=25 +Darkwater Catacombs=299 +Darkwater Egg=38 Darting Merfolk=25 Daru Cavalier=37 -Daru Encampment=67 +Daru Encampment=30 Daru Healer=20 Daru Lancer=25 Daru Mender=25 Daru Sanctifier=21 Daru Spiritualist=40 Daru Stinger=25 -Daru Warchief=116 -Dash Hopes=116 +Daru Warchief=137 +Dash Hopes=84 Daughter of Autumn=25 Daunting Defender=25 -Dauntless Dourbark=234 -Dauntless Escort=127 +Dauntless Dourbark=222 +Dauntless Escort=138 Dauthi Cutthroat=40 -Dauthi Embrace=44 -Dauthi Ghoul=33 -Dauthi Horror=25 +Dauthi Embrace=33 +Dauthi Ghoul=34 +Dauthi Horror=27 Dauthi Jackal=31 -Dauthi Marauder=25 +Dauthi Marauder=37 Dauthi Mercenary=25 Dauthi Mindripper=12 -Dauthi Slayer=23 +Dauthi Slayer=31 Dauthi Trapper=41 -Dauthi Warlord=78 -Dawn Charm=45 -Dawn Elemental=107 +Dauthi Warlord=112 +Dawn Charm=486 +Dawn Elemental=116 Dawn of the Dead=35 Dawn's Reflection=32 Dawnfluke=25 Dawnglare Invoker=25 -Dawnglow Infusion=32 +Dawnglow Infusion=25 Dawning Purist=25 Dawnray Archer=25 -Dawnstrider=124 -Day of Destiny=96 +Dawnstrider=72 +Dawntreader Elk=26 +Day of Destiny=25 Day of Judgment=166 -Day of the Dragons=109 -Daybreak Coronet=222 -Daybreak Ranger=93 -Daze=417 +Day of the Dragons=127 +Daybreak Coronet=180 +Daybreak Ranger=84 +Daze=163 Dazzling Beauty=28 Dead Reckoning=46 Dead Ringers=7 -Dead Weight=11 -Dead-Iron Sledge=43 +Dead Weight=20 +Dead-Iron Sledge=25 Dead/Gone=31 -Deadapult=140 +Deadapult=50 +Deadeye Navigator=52 Deadfall=99 -Deadhead=46 +Deadhead=48 +Deadly Allure=25 Deadly Grub=41 Deadly Insect=25 -Deadly Recluse=33 +Deadly Recluse=25 Deadshot=25 Deadshot Minotaur=25 Deadwood Treefolk=25 Deal Damage=42 -Dearly Departed=26 -Death Baron=858 +Dearly Departed=27 +Death Baron=780 Death Bomb=28 Death Charmer=599 -Death Cloud=163 +Death Cloud=108 Death Cultist=25 -Death Grasp=31 +Death Grasp=48 Death Match=16 Death Mutation=25 -Death Pit Offering=85 -Death Pits of Rath=45 +Death Pit Offering=37 +Death Pits of Rath=47 Death Pulse=25 Death Rattle=25 Death Spark=25 Death Speakers=30 -Death Stroke=47 -Death Ward=34 -Death Watch=100 -Death Wish=47 +Death Stroke=2100 +Death Ward=36 +Death Watch=40 +Death Wish=49 Death of a Thousand Stings=25 Death or Glory=25 +Death's Caress=32 Death's Duet=52 -Death's Shadow=73 +Death's Shadow=67 Death's-Head Buzzard=408 -Death-Hood Cobra=25 -Death-Mask Duplicant=25 -Deathbringer Liege=630 -Deathbringer Thoctar=78 +Death-Hood Cobra=32 +Death-Mask Duplicant=26 +Deathbringer Liege=784 +Deathbringer Thoctar=148 Deathcoil Wurm=260 Deathcurse Ogre=25 Deathforge Shaman=37 Deathgazer=27 -Deathgreeter=24 -Deathgrip=25 +Deathgreeter=48 +Deathgrip=28 Deathknell Kami=25 -Deathlace=173 -Deathless Angel=203 -Deathmark=40 +Deathlace=161 +Deathless Angel=231 +Deathmark=36 Deathmark Prelate=100 Deathmask Nezumi=25 -Deathrender=316 -Deathspore Thallid=51 -Debt of Loyalty=160 -Debtors' Knell=537 +Deathrender=415 +Deathspore Thallid=20 +Debt of Loyalty=132 +Debtors' Knell=608 Decaying Soil=25 -Deceiver Exarch=25 -Deception=104 -Decimate=268 -Decimator Web=41 +Deceiver Exarch=181 +Deception=99 +Decimate=340 +Decimator Web=46 Declaration of Naught=38 Decompose=100 Decomposition=25 Deconstruct=25 -Decree of Annihilation=117 -Decree of Justice=286 -Decree of Pain=380 -Decree of Savagery=41 -Decree of Silence=85 +Decree of Annihilation=50 +Decree of Justice=446 +Decree of Pain=419 +Decree of Savagery=82 +Decree of Silence=110 Dedicated Martyr=38 -Deep Analysis=44 +Deep Analysis=475 Deep Reconnaissance=40 Deep Spawn=26 Deep Water=11 -Deep Wood=56 -Deep-Sea Kraken=141 -Deep-Slumber Titan=25 +Deep Wood=47 +Deep-Sea Kraken=138 +Deep-Slumber Titan=55 Deepcavern Imp=24 -Deepchannel Mentor=55 +Deepchannel Mentor=66 Deepfire Elemental=25 Deeptread Merrow=25 Deepwood Drummer=28 @@ -2382,95 +2438,103 @@ Defender en-Vec=60 Defender of Chaos=42 Defender of Law=399 Defender of the Order=100 -Defense Grid=131 -Defense of the Heart=605 +Defense Grid=128 +Defense of the Heart=744 Defensive Formation=20 Defensive Maneuvers=28 Defensive Stance=12 -Defiant Elf=25 +Defiant Elf=28 Defiant Falcon=41 -Defiant Stand=38 +Defiant Stand=39 Defiant Vanguard=38 -Defiler of Souls=152 +Defiler of Souls=137 Defiling Tears=100 -Deflection=55 +Deflection=25 Deft Duelist=25 Deftblade Elite=16 +Defy Death=40 Defy Gravity=25 Dega Disciple=28 Dega Sanctuary=40 -Degavolver=62 +Degavolver=25 Deglamer=25 Dehydration=28 -Deity of Scars=225 +Deity of Scars=288 Deja Vu=52 -Delay=42 +Delay=44 Delaying Shield=30 Delif's Cone=100 Delif's Cube=40 -Delirium=41 +Delirium=48 Delirium Skeins=24 -Delraich=25 +Delraich=136 Deluge=25 -Delusions of Mediocrity=43 -Delver of Secrets=257 +Delusions of Mediocrity=25 +Delver of Secrets=85 Dematerialize=28 Dementia Bat=25 Dementia Sliver=44 -Demigod of Revenge=442 +Demigod of Revenge=492 Demolish=12 -Demon Token=30 +Demon Token=100 Demon of Death's Gate=137 Demon's Herald=28 -Demon's Horn=25 +Demon's Horn=23 Demon's Jester=25 -Demonfire=52 +Demonfire=81 Demonic Appetite=25 -Demonic Attorney=304 -Demonic Collusion=38 -Demonic Consultation=47 +Demonic Attorney=173 +Demonic Collusion=58 +Demonic Consultation=78 Demonic Dread=49 -Demonic Hordes=716 -Demonic Torment=99 -Demonic Tutor=1131 +Demonic Hordes=704 +Demonic Rising=42 +Demonic Taskmaster=49 +Demonic Torment=169 +Demonic Tutor=1011 +Demonlord of Ashmouth=109 Demonmail Hauberk=139 -Demonspine Whip=28 +Demonspine Whip=35 Demoralize=28 Demystify=12 Denied!=25 -Denizen of the Deep=127 -Dense Canopy=41 -Dense Foliage=142 +Denizen of the Deep=171 +Dense Canopy=38 +Dense Foliage=159 Deny Reality=31 -Denying Wind=25 -Deprive=37 -Deranged Assistant=32 -Deranged Hermit=471 +Denying Wind=90 +Deprive=36 +Deranged Assistant=28 +Deranged Hermit=516 +Deranged Outcast=33 Derelor=25 Dermoplasm=100 Descendant of Kiyomaro=40 Descendant of Masumaro=25 Descendant of Soramaro=42 +Descendants' Path=130 +Descent into Madness=83 Desecrated Earth=35 Desecration Elemental=56 Desecrator Hag=27 -Desert=67 +Desert=81 Desert Drake=27 Desert Nomads=25 -Desert Sandstorm=75 -Desert Twister=32 -Deserted Temple=238 -Desertion=281 -Desolation=25 -Desolation Angel=131 -Desolation Giant=43 -Desperate Charge=50 -Desperate Gambit=40 -Desperate Ravings=125 -Desperate Research=47 -Desperate Ritual=63 -Despise=75 -Despoil=22 +Desert Sandstorm=99 +Desert Twister=76 +Deserted Temple=318 +Desertion=202 +Desolate Lighthouse=199 +Desolation=45 +Desolation Angel=229 +Desolation Giant=47 +Desperate Charge=88 +Desperate Gambit=50 +Desperate Ravings=25 +Desperate Research=149 +Desperate Ritual=72 +Despise=41 +Despoil=11 Despondency=40 Despotic Scepter=50 Destructive Flow=23 @@ -2478,75 +2542,78 @@ Destructive Force=27 Destructive Urge=56 Detainment Spell=24 Detonate=26 -Detritivore=38 -Deus of Calamity=273 +Detritivore=50 +Deus of Calamity=221 Devastate=29 -Devastating Dreams=83 -Devastating Summons=31 -Devastation=715 -Devil's Play=42 -Devoted Caretaker=127 -Devoted Druid=25 +Devastating Dreams=238 +Devastating Summons=36 +Devastation=316 +Devastation Tide=166 +Devil's Play=41 +Devoted Caretaker=62 +Devoted Druid=41 Devoted Hero=42 Devoted Retainer=40 Devour in Shadow=25 Devouring Deep=16 -Devouring Greed=40 -Devouring Light=38 +Devouring Greed=50 +Devouring Light=50 Devouring Rage=25 -Devouring Strossus=199 +Devouring Strossus=74 Devouring Swarm=35 +Devout Chaplain=33 Devout Harpist=28 -Devout Lightcaster=26 +Devout Lightcaster=39 Devout Monk=25 Devout Witness=37 Dewdrop Spy=25 -Diabolic Edict=105 -Diabolic Intent=628 +Diabolic Edict=68 +Diabolic Intent=601 Diabolic Machine=34 -Diabolic Servitude=25 -Diabolic Tutor=43 -Diabolic Vision=50 +Diabolic Servitude=15 +Diabolic Tutor=27 +Diabolic Vision=12 Diamond Faerie=25 -Diamond Kaleidoscope=40 -Diamond Valley=4842 -Diaochan, Artful Beauty=1119 +Diamond Kaleidoscope=47 +Diamond Valley=4687 +Diaochan, Artful Beauty=5050 Dichotomancy=56 Didgeridoo=157 -Diligent Farmhand=19 +Diligent Farmhand=36 Dimensional Breach=26 Diminish=25 Diminishing Returns=66 -Dimir Aqueduct=69 -Dimir Cutpurse=69 -Dimir Doppelganger=100 +Dimir Aqueduct=25 +Dimir Cutpurse=70 +Dimir Doppelganger=187 Dimir Guildmage=149 Dimir House Guard=40 -Dimir Infiltrator=46 -Dimir Machinations=25 -Dimir Signet=69 -Din of the Fireherd=46 -Dingus Egg=210 -Dingus Staff=38 +Dimir Infiltrator=36 +Dimir Machinations=33 +Dimir Signet=62 +Din of the Fireherd=40 +Dingus Egg=198 +Dingus Staff=99 Diplomatic Escort=25 Diplomatic Immunity=25 -Dire Undercurrents=87 +Dire Undercurrents=68 Dire Wolves=99 -Diregraf Ghoul=192 +Diregraf Captain=88 +Diregraf Ghoul=162 Dirge of Dread=25 -Dirtcowl Wurm=150 +Dirtcowl Wurm=356 Dirtwater Wraith=14 Dirty Wererat=25 -Disappear=25 +Disappear=175 Disarm=25 -Disaster Radius=41 +Disaster Radius=25 Disciple of Grace=37 -Disciple of Griselbrand=36 +Disciple of Griselbrand=27 Disciple of Kangee=13 Disciple of Law=39 Disciple of Malice=40 Disciple of Tevesh Szat=25 -Disciple of the Vault=25 +Disciple of the Vault=21 Discombobulate=37 Discordant Dirge=50 Discordant Spirit=50 @@ -2554,201 +2621,203 @@ Disease Carriers=25 Diseased Vermin=50 Disembowel=114 Disempower=41 -Disenchant=23 +Disenchant=29 Disentomb=25 -Disfigure=25 -Disharmony=258 -Disintegrate=79 +Disfigure=70 +Disharmony=202 +Disintegrate=89 Dismal Failure=24 -Dismantle=25 +Dismantle=50 Dismantling Blow=100 -Dismember=194 -Dismiss=16 +Dismember=124 +Dismiss=15 Disorder=26 Disorient=25 -Dispatch=103 -Dispel=32 +Dispatch=147 +Dispel=31 Dispeller's Capsule=25 -Dispense Justice=47 +Dispense Justice=42 Dispersal Shield=46 -Disperse=25 +Disperse=27 Dispersing Orb=25 Disrupt=25 -Disrupting Scepter=174 -Disrupting Shoal=224 +Disrupting Scepter=170 +Disrupting Shoal=186 Disruption Aura=25 -Disruptive Pitmage=25 +Disruptive Pitmage=47 Disruptive Student=16 -Dissipate=62 -Dissipation Field=39 -Distant Melody=34 -Distant Memories=25 -Distorting Lens=22 +Dissipate=63 +Dissipation Field=35 +Distant Melody=25 +Distant Memories=28 +Distorting Lens=29 Distorting Wake=25 -Distortion Strike=44 -Distress=31 -Disturbed Burial=40 +Distortion Strike=41 +Distress=25 +Disturbed Burial=31 Disturbing Plot=29 Dive Bomber=28 Divebomber Griffin=25 Divergent Growth=45 Diversionary Tactics=25 -Divert=175 -Divination=24 +Divert=129 +Divination=20 Divine Congregation=25 +Divine Deflection=134 Divine Favor=47 -Divine Intervention=891 +Divine Intervention=763 Divine Light=31 Divine Offering=17 -Divine Presence=99 +Divine Presence=43 Divine Reckoning=32 Divine Retribution=39 -Divine Sacrament=174 -Divine Transformation=45 +Divine Sacrament=56 +Divine Transformation=56 Divine Verdict=25 -Diviner's Wand=40 -Diving Griffin=35 +Diviner's Wand=25 +Diving Griffin=22 Divining Witch=25 -Divinity of Pride=619 -Dizzy Spell=25 +Divinity of Pride=644 +Dizzy Spell=33 Dizzying Gaze=25 -Djinn Illuminatus=81 -Djinn of Wishes=27 +Djinn Illuminatus=119 +Djinn of Wishes=29 Djinn of the Lamp=220 -Do or Die=151 +Do or Die=110 Dodecapod=29 Dogged Hunter=30 Dogpile=25 -Dolmen Gate=144 +Dolmen Gate=199 Domestication=25 -Dominaria's Judgment=16 +Dominaria's Judgment=25 Dominate=20 -Dominating Licid=169 +Dominating Licid=99 Domineer=25 -Dominus of Fealty=128 -Donate=125 -Dong Zhou, the Tyrant=1074 -Doom Blade=74 +Dominus of Fealty=133 +Donate=164 +Dong Zhou, the Tyrant=2263 +Doom Blade=44 Doom Cannon=100 -Doomed Necromancer=128 -Doomed Traveler=37 -Doomgape=119 -Doomsday=140 -Doomsday Specter=62 -Door of Destinies=640 -Door to Nothingness=93 -Doran, the Siege Tower=235 +Doomed Necromancer=67 +Doomed Traveler=50 +Doomgape=200 +Doomsday=122 +Doomsday Specter=74 +Door of Destinies=591 +Door to Nothingness=125 +Doran, the Siege Tower=308 Dormant Gomazoa=25 -Dormant Sliver=48 -Dormant Volcano=40 -Dosan the Falling Leaf=43 +Dormant Sliver=27 +Dormant Volcano=41 +Dosan the Falling Leaf=103 Dosan's Oldest Chant=25 -Double Cleave=46 +Double Cleave=25 Double Cross=25 Double Deal=25 Double Dip=25 Double Header=28 -Double Negative=25 +Double Negative=16 Double Play=25 -Double Take=13 -Doubling Chant=38 -Doubling Cube=306 -Doubling Season=1961 -Doubtless One=40 +Double Take=10 +Doubling Chant=33 +Doubling Cube=235 +Doubling Season=1810 +Doubtless One=38 Douse=41 Douse in Gloom=25 -Dovescape=72 +Dovescape=138 Downdraft=40 Downhill Charge=25 Dowsing Shaman=25 -Draco=362 +Draco=227 Draconian Cylix=69 -Dracoplasm=40 -Drafna's Restoration=63 +Dracoplasm=99 +Drafna's Restoration=31 Drag Down=36 Dragon Appeasement=47 -Dragon Arch=187 -Dragon Blood=47 -Dragon Breath=43 -Dragon Broodmother=275 -Dragon Engine=25 +Dragon Arch=199 +Dragon Blood=30 +Dragon Breath=36 +Dragon Broodmother=350 +Dragon Engine=41 Dragon Fangs=45 -Dragon Fodder=25 -Dragon Mage=154 +Dragon Fodder=34 +Dragon Mage=201 Dragon Mask=22 -Dragon Roost=113 -Dragon Scales=15 +Dragon Roost=70 +Dragon Scales=400 Dragon Shadow=40 -Dragon Token=46 -Dragon Tyrant=254 +Dragon Token=68 +Dragon Tyrant=161 Dragon Whelp=36 Dragon Wings=25 Dragon's Claw=11 Dragon's Herald=25 -Dragonmaster Outcast=480 -Dragonskull Summit=287 -Dragonsoul Knight=26 -Dragonspeaker Shaman=208 +Dragonmaster Outcast=541 +Dragonskull Summit=271 +Dragonsoul Knight=25 +Dragonspeaker Shaman=188 Dragonstalker=25 -Dragonstorm=207 -Drain Life=26 -Drain Power=260 +Dragonstorm=236 +Drain Life=24 +Drain Power=186 Drain the Well=25 -Draining Whelk=100 +Draining Whelk=139 Drake Familiar=40 Drake Hatchling=28 Drake Umbra=30 Drake-Skull Cameo=29 Dralnu's Crusade=149 Dralnu's Pet=175 -Dralnu, Lich Lord=92 -Dramatic Entrance=99 -Drana, Kalastria Bloodchief=140 +Dralnu, Lich Lord=170 +Dramatic Entrance=175 +Drana, Kalastria Bloodchief=145 Drastic Revelation=47 Drawn Together=100 -Dread=123 +Dread=75 Dread Charge=97 Dread Drone=47 -Dread Reaper=150 -Dread Return=70 +Dread Reaper=89 +Dread Return=129 Dread Slag=29 +Dread Slaver=46 Dread Specter=25 -Dread Statuary=50 +Dread Statuary=25 Dread Warlock=40 Dread Wight=99 -Dread of Night=34 -Dreadship Reef=33 +Dread of Night=50 +Dreadship Reef=100 Dreadwing=25 -Dream Cache=9 +Dream Cache=26 Dream Chisel=25 -Dream Coat=99 +Dream Coat=94 Dream Fighter=25 Dream Fracture=85 -Dream Halls=323 -Dream Leash=28 +Dream Halls=333 +Dream Leash=25 Dream Prowler=26 -Dream Salvage=25 +Dream Salvage=50 Dream Stalker=25 Dream Thief=25 Dream Thrush=28 -Dream Tides=39 -Dream Twist=31 +Dream Tides=46 +Dream Twist=32 Dream's Grip=40 -Dreamborn Muse=9 +Dreamborn Muse=22 Dreamcatcher=40 Dreams of the Dead=11 Dreamscape Artist=40 Dreamspoiler Witches=40 -Dreamstone Hedron=29 +Dreamstone Hedron=25 Dreamwinder=28 -Dredge=25 +Dredge=611 Dreg Reaver=49 -Dregs of Sorrow=89 -Dregscape Zombie=28 +Dregs of Sorrow=49 +Dregscape Zombie=36 Drekavac=25 -Drelnoch=249 -Drift of Phantasms=40 -Drift of the Dead=11 +Drelnoch=200 +Drift of Phantasms=20 +Drift of the Dead=100 Drifter il-Dal=25 Drifting Djinn=25 Drifting Meadow=36 @@ -2757,95 +2826,100 @@ Drill-Skimmer=25 Drinker of Sorrow=27 Dripping Dead=14 Dripping-Tongue Zubera=25 +Drogskol Captain=95 +Drogskol Reaver=263 Dromad Purebred=25 Dromar's Attendant=25 -Dromar's Cavern=110 +Dromar's Cavern=47 Dromar's Charm=25 -Dromar, the Banisher=233 +Dromar, the Banisher=299 Dromosaur=28 Droning Bureaucrats=25 -Drooling Groodion=37 +Drooling Groodion=24 Drooling Ogre=25 -Drop of Honey=2690 +Drop of Honey=2337 Dross Crocodile=25 Dross Golem=25 Dross Harvester=25 Dross Hopper=25 Dross Prowler=44 Dross Ripper=20 -Dross Scorpion=40 +Dross Scorpion=34 Drought=99 -Drove of Elves=221 -Drowned=440 -Drowned Catacomb=500 -Drowned Rusalka=40 +Drove of Elves=269 +Drowned=362 +Drowned Catacomb=428 +Drowned Rusalka=30 Drowner Initiate=67 Drowner of Secrets=25 Drudge Reavers=25 -Drudge Skeletons=23 +Drudge Skeletons=28 Drudge Spell=25 Druid Lyrist=25 -Druid of the Anima=47 -Druid's Call=166 -Druidic Satchel=43 -Drumhunter=47 -Dry Spell=36 -Dryad Arbor=206 -Dryad Sophisticate=25 +Druid of the Anima=40 +Druid's Call=122 +Druidic Satchel=34 +Druids' Repository=57 +Drumhunter=25 +Dry Spell=22 +Dryad Arbor=189 +Dryad Sophisticate=45 Dryad's Caress=25 Dryad's Favor=25 -Dual Nature=26 +Dual Casting=63 +Dual Nature=49 Duct Crawler=26 Due Respect=25 -Dueling Grounds=148 +Dueling Grounds=175 Duergar Assailant=43 Duergar Cave-Guard=32 -Duergar Hedge-Mage=35 +Duergar Hedge-Mage=25 Duergar Mine-Captain=41 -Duh=32 +Duh=25 Dumb Ass=25 Dune-Brood Nephilim=25 Dunerider Outlaw=40 +Dungeon Geists=195 Dungeon Shade=38 -Dungrove Elder=351 -Duplicant=271 +Dungrove Elder=236 +Duplicant=242 Duplicity=49 -Duress=22 +Duress=19 Durkwood Baloth=25 Durkwood Boars=22 Durkwood Tracker=25 Dusk Imp=27 -Dusk Urchins=25 -Duskdale Wurm=24 +Dusk Urchins=90 +Duskdale Wurm=42 Duskhunter Bat=35 -Duskmantle, House of Shadow=44 +Duskmantle, House of Shadow=33 Duskrider Falcon=25 Duskrider Peregrine=12 Duskwalker=13 Duskworker=25 -Dust Bowl=369 +Dust Bowl=352 Dust Corona=25 -Dust Elemental=49 +Dust Elemental=50 Dust of Moments=50 -Dust to Dust=31 -Dwarven Armorer=14 +Dust to Dust=30 +Dwarven Armorer=37 Dwarven Armory=25 Dwarven Berserker=25 Dwarven Blastminer=25 Dwarven Bloodboiler=100 Dwarven Catapult=27 -Dwarven Demolition Team=118 -Dwarven Driller=75 -Dwarven Grunt=46 -Dwarven Hold=74 +Dwarven Demolition Team=90 +Dwarven Driller=100 +Dwarven Grunt=26 +Dwarven Hold=87 Dwarven Landslide=40 Dwarven Lieutenant=25 -Dwarven Miner=12 +Dwarven Miner=38 Dwarven Nomad=40 Dwarven Patrol=25 Dwarven Pony=40 Dwarven Recruiter=40 -Dwarven Ruins=23 +Dwarven Ruins=21 Dwarven Scorcher=28 Dwarven Sea Clan=30 Dwarven Shrine=37 @@ -2855,131 +2929,133 @@ Dwarven Strike Force=46 Dwarven Thaumaturgist=79 Dwarven Trader=25 Dwarven Vigilantes=11 -Dwarven Warriors=31 +Dwarven Warriors=25 Dwarven Weaponsmith=12 Dwell on the Past=40 -Dying Wail=38 -Dystopia=126 +Dying Wail=43 +Dystopia=100 Eager Cadet=41 Early Frost=40 -Early Harvest=52 +Early Harvest=60 Earnest Fellowship=37 Earsplitting Rats=40 Earth Elemental=22 Earth Rift=25 -Earth Servant=45 +Earth Servant=40 Earth Surge=28 Earthbind=23 Earthblighter=66 Earthbrawn=25 -Earthcraft=847 +Earthcraft=856 Earthen Goo=25 Earthlink=73 Earthlore=500 -Earthquake=152 +Earthquake=126 Earthshaker=25 -Earwig Squad=52 +Earwig Squad=100 Eastern Paladin=37 -Eater of Days=32 -Eater of the Dead=50 -Ebon Dragon=260 +Eater of Days=31 +Eater of the Dead=25 +Ebon Dragon=399 Ebon Drake=25 Ebon Praetor=42 Ebon Stronghold=28 Ebonblade Reaper=37 Ebony Charm=34 -Ebony Horse=142 +Ebony Horse=95 Ebony Owl Netsuke=25 Ebony Rhino=100 Ebony Treefolk=39 Echo Chamber=25 Echo Circlet=25 -Echo Mage=122 +Echo Mage=100 Echo Tracer=16 Echoing Calm=25 Echoing Courage=25 Echoing Decay=25 Echoing Ruin=25 -Echoing Truth=45 +Echoing Truth=26 Edge of Autumn=40 -Edge of the Divinity=62 -Edgewalker=62 +Edge of the Divinity=25 +Edgewalker=175 Eel Umbra=15 Eerie Procession=46 Ego Erasure=30 -Eiganjo Castle=138 +Eiganjo Castle=112 Eiganjo Free-Riders=25 -Eight-and-a-Half-Tails=328 +Eight-and-a-Half-Tails=308 Eightfold Maze=399 Ekundu Cyclops=28 Ekundu Griffin=12 -El-Hajjaj=99 -Eladamri's Call=219 -Eladamri's Vineyard=174 -Eladamri, Lord of Leaves=563 +El-Hajjaj=40 +Eladamri's Call=285 +Eladamri's Vineyard=151 +Eladamri, Lord of Leaves=585 Eland Umbra=25 -Elder Cathar=31 +Elbrus, the Binding Blade=162 +Elder Cathar=22 Elder Druid=18 -Elder Land Wurm=45 +Elder Land Wurm=180 Elder Mastery=40 Elder Pine of Jukai=25 -Elder Spawn=149 -Elder of Laurels=28 -Eldrazi Conscription=318 -Eldrazi Monument=280 -Eldrazi Temple=153 +Elder Spawn=150 +Elder of Laurels=30 +Eldrazi Conscription=372 +Eldrazi Monument=330 +Eldrazi Temple=186 Electric Eel=41 -Electrolyze=129 -Electropotence=80 +Electrolyze=126 +Electropotence=32 Electrostatic Bolt=14 Electryte=10 -Elemental Appeal=28 +Elemental Appeal=32 Elemental Augury=58 -Elemental Mastery=50 +Elemental Mastery=147 Elemental Resonance=56 Elephant Ambush=36 Elephant Grass=112 -Elephant Graveyard=2519 -Elephant Guide=40 +Elephant Graveyard=1525 +Elephant Guide=58 Elephant Resurgence=25 Elephant Token=50 -Elesh Norn, Grand Cenobite=1908 +Elesh Norn, Grand Cenobite=1887 Elf Replica=25 -Elfhame Palace=29 -Elfhame Sanctuary=65 -Elite Archers=36 +Elfhame Palace=40 +Elfhame Sanctuary=38 +Elgaud Inquisitor=99 +Elite Archers=99 Elite Cat Warrior=40 -Elite Inquisitor=70 +Elite Inquisitor=83 Elite Javelineer=26 -Elite Vanguard=50 -Elixir of Immortality=40 -Elixir of Vitality=25 +Elite Vanguard=38 +Elixir of Immortality=44 +Elixir of Vitality=33 Elkin Bottle=49 -Elkin Lair=99 +Elkin Lair=41 Elsewhere Flask=34 -Elspeth Tirel=1535 -Elspeth, Knight-Errant=2061 -Elven Cache=33 +Elspeth Tirel=1112 +Elspeth, Knight-Errant=2217 +Elven Cache=37 Elven Fortress=28 Elven Lyre=25 Elven Palisade=25 -Elven Riders=28 +Elven Riders=29 Elven Rite=52 Elven Warhounds=31 -Elves of Deep Shadow=31 +Elves of Deep Shadow=49 Elvish Aberration=24 -Elvish Archdruid=119 -Elvish Archers=157 +Elvish Archdruid=82 +Elvish Archers=117 Elvish Bard=14 Elvish Berserker=26 -Elvish Branchbender=25 -Elvish Champion=226 -Elvish Eulogist=28 -Elvish Farmer=70 +Elvish Branchbender=46 +Elvish Champion=333 +Elvish Eulogist=25 +Elvish Farmer=67 Elvish Fury=44 Elvish Guidance=54 Elvish Handservant=25 -Elvish Harbinger=100 +Elvish Harbinger=104 Elvish Healer=25 Elvish Herder=100 Elvish Hexhunter=25 @@ -2990,139 +3066,141 @@ Elvish Lookout=25 Elvish Lyrist=25 Elvish Pathcutter=28 Elvish Pioneer=10 -Elvish Piper=216 -Elvish Promenade=254 +Elvish Piper=459 +Elvish Promenade=239 Elvish Ranger=26 Elvish Scout=700 Elvish Scrapper=25 Elvish Skysweeper=25 -Elvish Soultiller=85 -Elvish Spirit Guide=345 -Elvish Vanguard=220 -Elvish Visionary=29 -Elvish Warrior=10 +Elvish Soultiller=44 +Elvish Spirit Guide=267 +Elvish Vanguard=280 +Elvish Visionary=36 +Elvish Warrior=8 +Emancipation Angel=74 Embalmed Brawler=16 Embargo=25 Ember Beast=27 Ember Gale=25 -Ember Hauler=58 +Ember Hauler=40 Ember Shot=41 Ember Weaver=49 Ember-Fist Zubera=25 -Embermage Goblin=25 +Embermage Goblin=52 Embersmith=50 Emberstrike Duo=25 Emberwilde Augur=25 Emberwilde Caliph=49 -Emberwilde Djinn=74 +Emberwilde Djinn=129 Emblazoned Golem=25 Emblem of the Warmind=56 Embolden=37 -Emcee=39 -Emerald Charm=25 +Emcee=100 +Emerald Charm=43 Emerald Dragonfly=22 -Emerald Medallion=230 +Emerald Medallion=204 Emerald Oryx=25 Emerge Unscathed=49 -Emeria Angel=139 -Emeria, the Sky Ruin=136 -Emissary of Despair=31 +Emeria Angel=116 +Emeria, the Sky Ruin=194 +Emissary of Despair=25 Emissary of Hope=25 Emmessi Tome=25 Emperor Crocodile=22 -Empress Galina=129 -Empty City Ruse=200 -Empty the Catacombs=33 -Empty the Warrens=31 +Empress Galina=104 +Empty City Ruse=366 +Empty the Catacombs=37 +Empty the Warrens=27 Empty-Shrine Kannushi=25 -Empyrial Archangel=313 -Empyrial Armor=22 -Empyrial Plate=125 -Emrakul's Hatcher=40 -Emrakul, the Aeons Torn=1120 +Empyrial Archangel=407 +Empyrial Armor=38 +Empyrial Plate=99 +Emrakul's Hatcher=25 +Emrakul, the Aeons Torn=1256 Enatu Golem=40 Enchanted Being=25 -Enchanted Evening=150 +Enchanted Evening=125 Enchantment Alteration=25 -Enchantress's Presence=218 -Enclave Cryptologist=21 +Enchantress's Presence=279 +Enclave Cryptologist=31 Enclave Elite=25 -Encroach=25 +Encroach=41 Endangered Armodon=25 Endbringer's Revel=25 Endemic Plague=57 -Endless Cockroaches=278 -Endless Horizons=120 -Endless Ranks of the Dead=81 +Endless Cockroaches=507 +Endless Horizons=110 +Endless Ranks of the Dead=70 Endless Scream=43 -Endless Swarm=56 -Endless Whispers=49 +Endless Swarm=135 +Endless Whispers=99 Endless Wurm=150 Endoskeleton=10 -Endrek Sahr, Master Breeder=54 +Endrek Sahr, Master Breeder=55 Endure=25 -Enduring Ideal=140 -Enduring Renewal=105 +Enduring Ideal=181 +Enduring Renewal=137 Enemy of the Guildpact=25 Energizer=49 Energy Arc=40 Energy Bolt=50 -Energy Chamber=134 -Energy Field=529 -Energy Flux=48 +Energy Chamber=147 +Energy Field=395 +Energy Flux=27 Energy Storm=75 Energy Tap=29 Energy Vortex=145 Enervate=26 Enfeeblement=27 -Engineered Explosives=1026 -Engineered Plague=87 +Engineered Explosives=977 +Engineered Plague=43 Engulfing Flames=38 -Engulfing Slagwurm=45 +Engulfing Slagwurm=64 Enigma Eidolon=25 -Enigma Sphinx=87 -Enlightened Tutor=783 -Enlisted Wurm=25 +Enigma Sphinx=116 +Enlightened Tutor=892 +Enlisted Wurm=40 Enlistment Officer=50 Enormous Baloth=39 Enrage=25 Enraging Licid=25 -Enshrined Memories=97 -Enslave=23 +Enshrined Memories=45 +Enslave=22 Enslaved Dwarf=28 Enslaved Horror=25 Enslaved Scout=28 Ensnare=25 -Ensnaring Bridge=333 +Ensnaring Bridge=377 Ensouled Scimitar=28 -Entangler=125 +Entangler=131 Entangling Trap=40 Entangling Vines=25 -Enter the Dungeon=152 -Entomb=1892 +Enter the Dungeon=214 +Entomb=1891 Entomber Exarch=16 Entrails Feaster=52 +Entreat the Angels=1359 Entropic Eidolon=25 -Entropic Specter=25 +Entropic Specter=49 Envelop=25 -Eon Hub=201 -Ephemeron=79 +Eon Hub=41 +Ephemeron=33 Epic Proportions=79 -Epic Struggle=194 -Epicenter=25 -Epochrasite=134 +Epic Struggle=126 +Epicenter=26 +Epochrasite=125 Equal Treatment=38 -Equilibrium=126 -Equinox=31 -Equipoise=42 -Eradicate=83 +Equilibrium=86 +Equinox=40 +Equipoise=116 +Eradicate=41 Erase=152 -Erayo, Soratami Ascendant=735 -Erg Raiders=22 -Erhnam Djinn=384 +Erayo, Soratami Ascendant=738 +Erg Raiders=33 +Erhnam Djinn=252 Erithizon=21 -Eron the Relentless=29 -Erosion=13 +Eron the Relentless=66 +Erosion=8 Errand of Duty=25 Errant Doomsayers=25 Errant Ephemeron=25 @@ -3130,13 +3208,13 @@ Errant Minion=33 Errantry=26 Erratic Explosion=50 Erratic Mutation=25 -Erratic Portal=93 +Erratic Portal=153 Ersatz Gnomes=40 -Ertai's Familiar=149 +Ertai's Familiar=39 Ertai's Meddling=25 Ertai's Trickery=25 -Ertai, Wizard Adept=306 -Ertai, the Corrupted=103 +Ertai, Wizard Adept=257 +Ertai, the Corrupted=92 Escape Artist=25 Escape Routes=28 Escaped Null=25 @@ -3146,234 +3224,244 @@ Esper Charm=25 Esper Cormorants=25 Esper Panorama=36 Esper Sojourners=25 -Esper Stormblade=25 +Esper Stormblade=39 Esperzoa=25 -Essence Bottle=25 +Essence Bottle=35 Essence Drain=35 Essence Feed=25 Essence Filter=25 Essence Flare=250 Essence Fracture=25 +Essence Harvest=26 Essence Leak=28 Essence Scatter=25 -Essence Sliver=261 +Essence Sliver=217 Essence Vortex=25 -Essence Warden=42 -Essence of the Wild=47 -Etched Champion=385 -Etched Monstrosity=90 -Etched Oracle=25 -Eternal Dominion=184 -Eternal Dragon=311 -Eternal Flame=107 +Essence Warden=34 +Essence of the Wild=43 +Etched Champion=277 +Etched Monstrosity=104 +Etched Oracle=62 +Eternal Dominion=123 +Eternal Dragon=365 +Eternal Flame=99 Eternal Warrior=15 -Eternal Witness=328 +Eternal Witness=299 Eternity Snare=25 -Eternity Vessel=49 +Eternity Vessel=74 Ether Well=100 -Ethercaste Knight=25 +Ethercaste Knight=52 Ethereal Champion=14 -Ethereal Haze=37 -Ethereal Usher=25 +Ethereal Haze=41 +Ethereal Usher=37 Ethereal Whiskergill=25 Etherium Abomination=25 Etherium Astrolabe=25 -Etherium Sculptor=154 -Ethersworn Adjudicator=211 -Ethersworn Canonist=597 +Etherium Sculptor=201 +Ethersworn Adjudicator=293 +Ethersworn Canonist=685 Ethersworn Shieldmage=25 -Etherwrought Page=25 +Etherwrought Page=33 Eunuchs' Intrigues=50 -Eureka=5160 -Evacuation=67 +Eureka=5104 +Evacuation=85 Evangelize=10 Evaporate=25 Evasive Action=30 Even the Odds=40 Everbark Shaman=25 -Everflowing Chalice=77 -Everglades=25 +Everflowing Chalice=100 +Everglades=132 Everglove Courier=55 -Everlasting Torment=155 +Everlasting Torment=187 Evermind=25 -Evershrike=183 +Evershrike=100 Evil Eye of Orms-By-Gore=157 Evil Eye of Orms-by-Gore=40 Evil Eye of Urborg=25 -Evil Presence=26 -Evil Twin=40 +Evil Presence=25 +Evil Twin=46 Evincar's Justice=29 Eviscerator=52 Evolution Charm=25 Evolution Vat=47 -Evolving Wilds=30 -Exalted Angel=317 -Exalted Dragon=32 +Evolving Wilds=20 +Exalted Angel=369 +Exalted Dragon=58 Excavation=42 Excavator=50 Excise=20 -Exclude=50 -Exclusion Ritual=12 +Exclude=100 +Exclusion Ritual=34 Excommunicate=7 -Excruciator=35 +Excruciator=37 Execute=25 Executioner's Capsule=44 Exhaustion=46 -Exhume=100 +Exhume=75 Exhumer Thrull=25 -Exile=40 +Exile=25 Exile into Darkness=25 Exiled Boggart=25 Exiled Doomsayer=25 -Exorcist=159 +Exorcist=150 Exoskeletal Armor=20 -Exotic Curse=16 +Exotic Curse=25 Exotic Disease=56 -Exotic Orchard=119 -Expedition Map=47 +Exotic Orchard=116 +Expedition Map=31 Expendable Troops=28 -Experiment Kraj=122 +Experiment Kraj=50 Exploding Borders=25 -Exploration=1895 -Explore=60 +Exploration=1756 +Explore=29 Explorer's Scope=25 Explosive Growth=28 -Explosive Revelation=25 -Explosive Vegetation=80 -Expunge=38 -Exsanguinate=31 -Extinction=187 -Extinguish=39 -Extirpate=473 +Explosive Revelation=12 +Explosive Vegetation=69 +Expunge=49 +Exquisite Blood=58 +Exsanguinate=162 +Extinction=93 +Extinguish=27 +Extirpate=516 Extortion=40 Extra Arms=25 -Extract=129 -Extractor Demon=64 -Extraplanar Lens=352 +Extract=89 +Extractor Demon=90 +Extraplanar Lens=486 Extravagant Spirit=38 -Extruder=38 -Exuberant Firestoker=25 +Extruder=43 +Exuberant Firestoker=49 Eye Spy=40 -Eye for an Eye=52 +Eye for an Eye=34 Eye of Nowhere=38 Eye of Ramos=25 -Eye of Singularity=25 -Eye of Ugin=227 +Eye of Singularity=30 +Eye of Ugin=283 Eye of Yawgmoth=99 -Eye of the Storm=25 +Eye of the Storm=74 Eye to Eye=25 Eyeblight's Ending=30 Eyes of the Watcher=25 -Eyes of the Wisent=70 -Ezuri's Archers=25 -Ezuri's Brigade=30 -Ezuri, Renegade Leader=126 +Eyes of the Wisent=47 +Ezuri's Archers=34 +Ezuri's Brigade=31 +Ezuri, Renegade Leader=81 Fa'adiyah Seer=28 -Fable of Wolf and Owl=151 -Fabricate=52 +Fable of Wolf and Owl=164 +Fabricate=62 Face of Fear=25 Face to Face=25 -Faceless Butcher=77 +Faceless Butcher=120 Faceless Devourer=25 Faces of the Past=25 Facevaulter=40 -Fact or Fiction=138 +Fact or Fiction=120 Fade Away=15 Fade from Memory=25 -Faerie Conclave=78 +Faerie Conclave=38 Faerie Harbinger=25 -Faerie Macabre=25 +Faerie Macabre=125 Faerie Mechanist=40 Faerie Noble=99 Faerie Squadron=7 -Faerie Swarm=43 +Faerie Swarm=28 Faerie Tauntings=37 -Faerie Trickery=66 +Faerie Trickery=30 Faith Healer=25 -Faith's Fetters=27 +Faith's Fetters=39 +Faith's Shield=29 Faithful Squire=25 -Falkenrath Marauders=35 -Falkenrath Noble=62 -Fallen Angel=88 +Faithless Looting=213 +Falkenrath Aristocrat=290 +Falkenrath Exterminator=165 +Falkenrath Marauders=33 +Falkenrath Noble=61 +Falkenrath Torturer=25 +Fallen Angel=77 Fallen Askari=37 Fallen Cleric=28 -Fallen Ferromancer=16 -Fallen Ideal=31 -Falling Star=498 +Fallen Ferromancer=34 +Fallen Ideal=37 +Falling Star=325 Falling Timber=41 Fallow Earth=30 Fallow Wurm=40 Fallowsage=25 -False Cure=190 -False Dawn=100 -False Defeat=196 +False Cure=182 +False Dawn=25 +False Defeat=650 False Demise=26 False Memories=51 -False Mourning=105 -False Orders=64 +False Mourning=233 +False Orders=249 False Peace=26 -False Prophet=68 +False Prophet=57 False Summoning=33 Falter=40 Familiar Ground=22 -Familiar's Ruse=43 -Famine=1275 +Familiar's Ruse=74 +Famine=50 Famished Ghoul=25 Fanatical Devotion=25 Fanatical Fever=99 -Fang Skulkin=49 -Fangren Firstborn=89 +Fang Skulkin=25 +Fangren Firstborn=79 Fangren Hunter=46 Fangren Marauder=46 Fangren Pathcutter=25 -Fanning the Flames=15 +Fanning the Flames=99 Far Wanderings=49 -Farhaven Elf=82 -Farmstead=90 +Farbog Boneflinger=25 +Farbog Explorer=34 +Farhaven Elf=25 +Farmstead=142 Farrel's Mantle=25 Farrel's Zealot=99 Farrelite Priest=29 -Farseek=32 +Farseek=35 Farsight Mask=25 -Fastbond=1071 -Fasting=25 +Fastbond=1150 +Fasting=225 Fat Ass=25 Fatal Attraction=48 -Fatal Blow=23 -Fatal Frenzy=50 +Fatal Blow=25 +Fatal Frenzy=56 Fatal Lore=62 Fatal Mutation=56 -Fate Transfer=40 -Fatespinner=80 -Fatestitcher=40 +Fate Transfer=31 +Fatespinner=132 +Fatestitcher=33 Fathom Seer=25 -Fathom Trawl=50 -Fatigue=25 -Fault Line=86 +Fathom Trawl=25 +Fatigue=32 +Fault Line=74 Fault Riders=28 Faultgrinder=25 -Fauna Shaman=251 +Fauna Shaman=276 Favor of the Mighty=25 -Favor of the Overbeing=25 +Favor of the Overbeing=34 Favorable Destiny=25 +Favorable Winds=46 Fear=27 -Feast of Blood=32 +Feast of Blood=48 Feast of Flesh=25 Feast of Worms=29 Feast of the Unicorn=22 -Feast or Famine=635 -Fecundity=34 +Feast or Famine=599 +Fecundity=26 Feebleness=25 -Feedback=23 +Feedback=45 Feedback Bolt=25 Feeding Frenzy=40 -Feeling of Dread=33 +Feeling of Dread=32 Feint=25 -Feldon's Cane=52 -Felidar Sovereign=223 -Fellwar Stone=31 +Feldon's Cane=76 +Felidar Sovereign=306 +Fellwar Stone=86 Femeref Archers=24 -Femeref Enchantress=157 +Femeref Enchantress=155 Femeref Healer=11 Femeref Knight=11 Femeref Scouts=28 @@ -3381,133 +3469,136 @@ Fen Stalker=28 Fencer Clique=25 Fencer's Magemark=16 Fend Off=28 -Fendeep Summoner=39 +Fendeep Summoner=99 Feral Animist=25 Feral Contest=25 Feral Deceiver=25 -Feral Hydra=92 +Feral Hydra=104 Feral Instinct=28 Feral Lightning=24 Feral Ridgewolf=34 Feral Shadow=29 -Feral Thallid=39 +Feral Thallid=25 Feral Throwback=77 Ferocious Charge=25 -Ferocity=27 +Ferocity=21 Feroz's Ban=24 Ferropede=25 Ferrovore=25 Fertile Ground=22 Fertile Imagination=25 Fertilid=40 -Fervent Charge=54 +Fervent Cathar=25 +Fervent Charge=49 Fervent Denial=40 -Fervor=85 +Fervor=43 Festercreep=25 Festerhide Boar=125 Festering Evil=38 Festering Goblin=26 Festering March=25 -Festering Wound=40 +Festering Wound=34 Festival=40 -Festival of Trokin=34 +Festival of Trokin=102 Festival of the Guildpact=24 -Fetid Heath=820 +Fetid Heath=710 Fetid Horror=25 -Feudkiller's Verdict=33 +Feudkiller's Verdict=50 Fever Charm=25 -Fevered Convulsions=57 +Fevered Convulsions=38 Fevered Strength=25 Fickle Efreet=54 Fiddlehead Kami=35 -Field Marshal=347 +Field Marshal=447 Field Surgeon=25 -Field of Dreams=300 +Field of Dreams=498 Field of Reality=25 -Field of Souls=85 -Fieldmist Borderpost=42 -Fiend Hunter=64 -Fierce Empath=61 +Field of Souls=48 +Fieldmist Borderpost=58 +Fiend Hunter=58 +Fiend of the Shadows=34 +Fierce Empath=38 Fiery Bombardment=50 Fiery Conclusion=25 Fiery Fall=25 Fiery Gambit=99 Fiery Hellhound=15 -Fiery Justice=47 +Fiery Justice=56 Fiery Mantle=31 Fiery Temper=23 -Fight or Flight=49 -Fight to the Death=83 +Fight or Flight=11 +Fight to the Death=68 Fighting Chance=43 Fighting Drake=26 -Figure of Destiny=527 -Filigree Angel=66 +Figure of Destiny=425 +Filigree Angel=121 Filigree Fracture=40 Filigree Sages=47 Fill with Fright=25 Filth=79 Filthy Cur=28 -Final Fortune=185 -Final Judgment=207 -Final Punishment=24 +Final Fortune=214 +Final Judgment=219 +Final Punishment=37 Final Revels=25 Final Strike=58 Final-Sting Faerie=25 -Finest Hour=83 -Fire Ambush=300 +Finest Hour=193 +Fire Ambush=561 Fire Ants=69 Fire Bowman=100 -Fire Covenant=19 +Fire Covenant=25 Fire Diamond=29 -Fire Dragon=200 -Fire Drake=43 +Fire Dragon=401 +Fire Drake=26 Fire Elemental=173 Fire Imp=29 Fire Juggler=25 -Fire Servant=96 +Fire Servant=152 Fire Snake=29 Fire Sprites=31 Fire Tempest=168 -Fire Whip=38 +Fire Whip=30 Fire and Brimstone=100 Fire at Will=25 Fire-Belly Changeling=25 Fire-Field Ogre=25 -Fire-Lit Thicket=373 -Fire/Ice=205 -Fireball=29 -Fireblast=117 -Firebolt=70 +Fire-Lit Thicket=375 +Fire/Ice=65 +Fireball=34 +Fireblast=110 +Firebolt=26 Firebrand Ranger=25 Firebreathing=10 Firecat Blitz=25 Firefly=25 Firefright Mage=28 -Firemane Angel=71 +Firemane Angel=125 Firemaw Kavu=25 -Fires of Yavimaya=62 +Fires of Undeath=29 +Fires of Yavimaya=119 Firescreamer=28 -Fireshrieker=66 +Fireshrieker=32 Fireslinger=25 -Firespout=99 -Firestorm=676 -Firestorm Hellkite=102 -Firestorm Phoenix=287 -Firewake Sliver=24 +Firespout=68 +Firestorm=835 +Firestorm Hellkite=100 +Firestorm Phoenix=268 +Firewake Sliver=50 Firewild Borderpost=25 First Come, First Served=41 First Volley=25 -Fishliver Oil=28 -Fissure=49 +Fishliver Oil=38 +Fissure=45 Fissure Vent=25 -Fist of Suns=219 +Fist of Suns=126 Fistful of Force=25 -Fists of Ironwood=41 +Fists of Ironwood=30 Fists of the Anvil=25 -Fists of the Demigod=25 +Fists of the Demigod=33 Fit of Rage=25 Flaccify=25 -Flagstones of Trokair=442 +Flagstones of Trokair=399 Flailing Drake=25 Flailing Manticore=79 Flailing Ogre=25 @@ -3515,92 +3606,92 @@ Flailing Soldier=25 Flame Burst=40 Flame Elemental=25 Flame Fusillade=29 -Flame Jab=25 -Flame Javelin=55 -Flame Jet=25 -Flame Rift=116 -Flame Slash=41 -Flame Spirit=187 -Flame Wave=50 +Flame Jab=31 +Flame Javelin=81 +Flame Jet=45 +Flame Rift=122 +Flame Slash=25 +Flame Spirit=193 +Flame Wave=99 Flame-Kin War Scout=25 -Flame-Kin Zealot=25 -Flameblast Dragon=46 +Flame-Kin Zealot=37 +Flameblast Dragon=43 Flameborn Hellion=25 -Flamebreak=236 +Flamebreak=225 Flamecore Elemental=25 Flamekin Bladewhirl=25 Flamekin Brawler=25 -Flamekin Harbinger=105 +Flamekin Harbinger=149 Flamekin Spitfire=25 -Flames of the Blood Hand=55 +Flames of the Blood Hand=99 Flameshot=12 Flamestick Courier=25 -Flametongue Kavu=48 +Flametongue Kavu=46 Flamewave Invoker=15 Flaming Gambit=25 Flaming Sword=28 Flanking Troops=258 -Flare=27 +Flare=141 Flaring Flame-Kin=79 Flaring Pain=25 -Flash=218 +Flash=210 Flash Conscription=41 -Flash Counter=25 -Flash Flood=25 +Flash Counter=28 +Flash Flood=26 Flash Foliage=25 Flash of Defiance=28 Flash of Insight=47 Flashfires=35 -Flashfreeze=28 +Flashfreeze=36 Flay=28 Flayed Nim=25 -Flayer Husk=46 +Flayer Husk=31 +Flayer of the Hatebound=33 Fledgling Djinn=25 -Fledgling Dragon=143 -Fledgling Griffin=40 +Fledgling Dragon=69 +Fledgling Griffin=99 Fledgling Imp=25 Fledgling Mawcor=25 Fledgling Osprey=15 Fleet-Footed Monk=36 Fleetfoot Panther=47 Fleeting Aven=25 -Fleeting Distraction=25 -Fleeting Image=50 +Fleeting Image=39 Flensermite=25 Flesh Allergy=37 Flesh Reaver=25 -Flesh-Eater Imp=30 -Fleshbag Marauder=31 +Flesh-Eater Imp=25 +Fleshbag Marauder=42 Fleshformer=25 Fleshgrafter=25 Fleshwrither=50 -Flicker=153 -Flickerform=74 +Flicker=58 +Flickerform=25 Flickering Spirit=25 -Flickering Ward=73 -Flickerwisp=140 +Flickering Ward=155 +Flickerwisp=75 Flight=24 -Flight Spellbomb=37 +Flight Spellbomb=25 Flight of Fancy=25 -Fling=39 +Fling=21 Flint Golem=25 Floating Shield=40 Floating-Dream Zubera=25 -Flock of Rabid Sheep=192 +Flock of Rabid Sheep=49 Flood=37 -Flood Plain=81 +Flood Plain=74 Floodbringer=25 Floodchaser=25 -Flooded Grove=509 -Flooded Shoreline=150 -Flooded Strand=2959 -Flooded Woodlands=35 +Flooded Grove=602 +Flooded Shoreline=88 +Flooded Strand=3277 +Flooded Woodlands=100 Floodgate=25 Floodwater Dam=51 -Floral Spuzzem=72 +Floral Spuzzem=99 Flourishing Defenses=25 Flow of Ideas=24 -Flow of Maggots=44 +Flow of Maggots=62 Flowering Field=25 Flowstone Armor=25 Flowstone Blade=28 @@ -3611,7 +3702,7 @@ Flowstone Embrace=25 Flowstone Flood=12 Flowstone Giant=28 Flowstone Hellion=25 -Flowstone Mauler=52 +Flowstone Mauler=25 Flowstone Overseer=31 Flowstone Salamander=15 Flowstone Sculpture=39 @@ -3621,144 +3712,145 @@ Flowstone Strike=28 Flowstone Surge=25 Flowstone Thopter=25 Flowstone Wall=28 -Fluctuator=206 +Fluctuator=158 Flurry of Wings=40 -Flux=27 -Flying Carpet=54 -Flying Men=148 -Fodder Cannon=31 +Flux=48 +Flying Carpet=48 +Flying Men=76 +Fodder Cannon=38 Fodder Launch=25 -Fog=31 -Fog Bank=101 +Fog=25 +Fog Bank=122 Fog Elemental=25 Fog Patch=25 Fog of Gnats=45 -Foil=358 -Fold into AEther=40 +Foil=302 +Fold into AEther=38 Folk Medicine=69 Folk of An-Havva=50 Folk of the Pines=50 -Followed Footsteps=279 -Fomori Nomad=25 -Font of Mythos=188 -Food Chain=211 -Fool's Demise=65 +Followed Footsteps=290 +Fomori Nomad=31 +Font of Mythos=254 +Food Chain=490 +Fool's Demise=37 Fool's Tome=25 Foot Soldiers=29 Footbottom Feast=25 Foothill Guide=28 -Footsteps of the Goryo=39 -Foratog=25 -Forbid=32 -Forbidden Alchemy=975 +Footsteps of the Goryo=34 +Foratog=22 +Forbid=33 +Forbidden Alchemy=321 Forbidden Crypt=36 Forbidden Lore=75 -Forbidden Orchard=438 -Forbidden Ritual=41 -Forbidding Watchtower=52 +Forbidden Orchard=402 +Forbidden Ritual=47 +Forbidding Watchtower=44 Force Bubble=25 Force Spike=31 Force Void=100 -Force of Nature=302 -Force of Savagery=57 -Force of Will=5070 -Forced Fruition=90 -Forced March=130 -Forced Retreat=95 -Forced Worship=25 -Forcefield=7464 +Force of Nature=353 +Force of Savagery=33 +Force of Will=5184 +Forced Fruition=91 +Forced March=100 +Forced Retreat=99 +Forced Worship=34 +Forcefield=6343 Forcemage Advocate=28 Foresee=25 Foreshadow=39 Foresight=25 Forest=5 -Forest Bear=135 -Forethought Amulet=99 +Forest Bear=162 +Forethought Amulet=250 Forfend=15 Forge Armor=40 +Forge Devil=32 Forget=24 -Forgotten Ancient=180 -Forgotten Cave=21 +Forgotten Ancient=168 +Forgotten Cave=25 Forgotten Harvest=100 Forgotten Lore=99 Foriysian Brigade=25 Foriysian Interceptor=25 Foriysian Totem=8 -Fork=1179 -Forked Bolt=38 -Forked Lightning=89 +Fork=1277 +Forked Bolt=47 +Forked Lightning=199 Forked-Branch Garami=25 -Form of the Dragon=63 -Form of the Squirrel=116 +Form of the Dragon=31 +Form of the Squirrel=140 Formation=100 -Forsaken City=102 +Forsaken City=243 Forsaken Wastes=108 -Fortified Area=37 +Fortified Area=94 Fortify=25 Fortitude=16 -Fortune Thief=49 +Fortune Thief=137 Fossil Find=19 Foster=39 Foul Familiar=25 Foul Imp=14 Foul Presence=25 Foul Spirit=131 -Fountain Watch=125 +Fountain Watch=102 Fountain of Cho=37 -Fountain of Youth=36 -Fowl Play=25 +Fountain of Youth=40 +Fowl Play=48 Foxfire=26 Foxfire Oak=25 -Fraction Jackson=150 +Fraction Jackson=199 Fractured Loyalty=25 -Fracturing Gust=65 +Fracturing Gust=130 Framed!=39500 -Frankenstein's Monster=125 -Frankie Peanuts=109 +Frankenstein's Monster=84 +Frankie Peanuts=116 Frantic Purification=28 Frantic Salvage=35 -Frantic Search=42 +Frantic Search=47 Frazzle=25 Frazzled Editor=25 Free-Range Chicken=25 Free-for-All=100 -Freed from the Real=36 +Freed from the Real=95 Freewind Equenaut=25 Freewind Falcon=40 -Frenetic Efreet=51 +Frenetic Efreet=62 Frenetic Ogre=25 Frenetic Raptor=25 Frenetic Sliver=25 -Frenzied Goblin=31 -Frenzied Tilling=40 -Frenzy Sliver=32 -Fresh Meat=40 +Frenzied Goblin=38 +Frenzied Tilling=100 +Frenzy Sliver=36 +Fresh Meat=43 Fresh Volunteers=28 Freyalise Supplicant=21 Freyalise's Charm=25 Freyalise's Radiance=25 Freyalise's Winds=28 Frightcrawler=28 -Frightful Delusion=37 +Frightful Delusion=32 Frightshroud Courier=32 Frog Tongue=40 -Frogmite=40 -Frogtosser Banneret=40 +Frogmite=35 +Frogtosser Banneret=38 Frontier Guide=40 Frontline Sage=25 Frontline Strategist=30 Frost Breath=25 Frost Giant=49 -Frost Marsh=82 +Frost Marsh=127 Frost Ogre=25 Frost Raptor=25 -Frost Titan=186 +Frost Titan=166 Frostling=36 -Frostweb Spider=25 +Frostweb Spider=39 Frostwielder=28 Frostwind Invoker=25 -Frozen AEther=25 -Frozen Shade=34 +Frozen AEther=49 +Frozen Shade=41 Frozen Solid=25 Fruition=102 Fuel for the Cause=46 @@ -3766,157 +3858,162 @@ Fugitive Druid=25 Fugitive Wizard=14 Fugue=22 Fulgent Distraction=25 -Full Moon's Rise=39 -Fulminator Mage=229 +Full Moon's Rise=44 +Fulminator Mage=148 Fumarole=25 -Fume Spitter=41 -Fumiko the Lowblood=119 -Funeral Charm=37 +Fume Spitter=37 +Fumiko the Lowblood=80 +Funeral Charm=45 Funeral March=38 Funeral Pyre=25 -Fungal Behemoth=75 -Fungal Bloom=64 +Fungal Behemoth=44 +Fungal Bloom=46 Fungal Reaches=25 -Fungal Shambler=89 +Fungal Shambler=50 Fungus Elemental=74 -Fungus Sliver=70 -Fungusaur=110 +Fungus Sliver=50 +Fungusaur=98 Furious Assault=25 Furnace Brood=52 Furnace Celebration=37 -Furnace Dragon=69 -Furnace Scamp=11 +Furnace Dragon=74 +Furnace Scamp=31 Furnace Spirit=28 -Furnace Whelp=13 -Furnace of Rath=50 -Furor of the Bitten=25 +Furnace Whelp=10 +Furnace of Rath=103 +Furor of the Bitten=32 Fury Charm=40 -Fury Sliver=40 -Fury of the Horde=69 -Furyborn Hellkite=98 -Furystoke Giant=192 -Fusion Elemental=47 +Fury Sliver=48 +Fury of the Horde=62 +Furyborn Hellkite=61 +Furystoke Giant=49 +Fusion Elemental=74 Fylamarid=44 Fylgja=11 Fyndhorn Bow=100 Fyndhorn Brownie=16 -Fyndhorn Druid=25 -Fyndhorn Elder=23 -Fyndhorn Elves=35 +Fyndhorn Druid=16 +Fyndhorn Elder=36 +Fyndhorn Elves=21 Fyndhorn Pollen=50 -Gabriel Angelfire=150 -Gaddock Teeg=288 -Gaea's Anthem=176 -Gaea's Avenger=286 +Gabriel Angelfire=211 +Gaddock Teeg=408 +Gaea's Anthem=239 +Gaea's Avenger=369 Gaea's Balance=40 -Gaea's Blessing=102 +Gaea's Blessing=46 Gaea's Bounty=16 -Gaea's Cradle=5213 -Gaea's Embrace=62 -Gaea's Herald=39 -Gaea's Liege=176 +Gaea's Cradle=5767 +Gaea's Embrace=22 +Gaea's Herald=30 +Gaea's Liege=212 Gaea's Might=32 -Gaea's Revenge=111 +Gaea's Revenge=95 Gaea's Skyfolk=25 -Gaea's Touch=47 +Gaea's Touch=48 Gainsay=25 Gale Force=25 -Galepowder Mage=45 +Galepowder Mage=69 Galina's Knight=25 Gallantry=20 Gallowbraid=99 -Gallows Warden=16 -Galvanic Arc=25 -Galvanic Blast=48 +Gallows Warden=25 +Gallows at Willow Hill=31 +Galvanic Arc=36 +Galvanic Blast=62 Galvanic Juggernaut=48 Galvanic Key=25 -Galvanoth=27 -Gamble=471 -Game Preserve=99 +Galvanoth=32 +Gamble=582 +Game Preserve=119 Game of Chaos=56 Game-Trail Changeling=40 -Gamekeeper=41 +Gamekeeper=49 Gang of Elk=25 Gangrenous Goliath=33 Gangrenous Zombies=25 -Gargantuan Gorilla=74 -Gargoyle Castle=52 +Gargantuan Gorilla=33 +Gargoyle Castle=25 Gargoyle Sentinel=25 -Garruk Relentless=1197 -Garruk Wildspeaker=365 -Garruk's Companion=25 -Garruk's Horde=31 +Garruk Relentless=943 +Garruk Wildspeaker=361 +Garruk's Companion=9 +Garruk's Horde=30 Garruk's Packleader=25 -Garruk, Primal Hunter=1320 -Garza Zol, Plague Queen=85 +Garruk, Primal Hunter=905 +Garza Zol, Plague Queen=169 Garza's Assassin=25 -Gaseous Form=20 +Gaseous Form=16 Gate Hound=25 -Gate to Phyrexia=433 -Gate to the AEther=79 -Gatekeeper of Malakir=88 +Gate to Phyrexia=584 +Gate to the AEther=100 +Gatekeeper of Malakir=92 Gathan Raiders=38 Gather Courage=25 -Gather Specimens=47 +Gather Specimens=64 +Gather the Townsfolk=68 Gatherer of Graces=49 -Gatstaf Shepherd=38 -Gauntlet of Might=5893 -Gauntlet of Power=561 -Gauntlets of Chaos=41 -Gavony Township=100 +Gatstaf Shepherd=67 +Gauntlet of Might=5915 +Gauntlet of Power=451 +Gauntlets of Chaos=67 +Gavony Ironwright=25 +Gavony Township=99 Gaze of Adamaro=56 Gaze of Justice=40 -Gaze of Pain=25 -Gaze of the Gorgon=37 -Geist of Saint Traft=1843 -Geist-Honored Monk=41 +Gaze of Pain=50 +Gaze of the Gorgon=30 +Geist of Saint Traft=1731 +Geist-Honored Monk=38 Geistcatcher's Rig=25 -Geistflame=30 -Gelatinous Genesis=25 -Gelectrode=97 +Geistflame=34 +Gelatinous Genesis=44 +Gelectrode=80 Gelid Shackles=25 -Gemhide Sliver=92 -Gemini Engine=25 +Gemhide Sliver=52 +Gemini Engine=31 Gempalm Avenger=25 -Gempalm Incinerator=97 -Gempalm Polluter=22 +Gempalm Incinerator=99 +Gempalm Polluter=25 Gempalm Sorcerer=25 Gempalm Strider=37 -Gemstone Array=18 -Gemstone Caverns=157 -Gemstone Mine=251 +Gemstone Array=43 +Gemstone Caverns=129 +Gemstone Mine=247 General Jarkeld=25 -General's Kabuto=221 -General's Regalia=37 -Genesis=842 -Genesis Chamber=100 -Genesis Wave=69 +General's Kabuto=104 +General's Regalia=179 +Genesis=928 +Genesis Chamber=93 +Genesis Wave=76 Genju of the Cedars=25 Genju of the Falls=31 Genju of the Fens=25 Genju of the Fields=25 -Genju of the Realm=140 +Genju of the Realm=156 Genju of the Spires=25 -Geosurge=28 +Geosurge=46 Geothermal Crevice=25 -Gerrard Capashen=81 -Gerrard's Battle Cry=99 -Gerrard's Command=30 +Geralf's Messenger=498 +Geralf's Mindcrusher=36 +Gerrard Capashen=66 +Gerrard's Battle Cry=42 +Gerrard's Command=25 Gerrard's Irregulars=12 -Gerrard's Verdict=89 +Gerrard's Verdict=77 Gerrard's Wisdom=31 Gerrymandering=31 Get a Life=31 -Geth's Grimoire=34 -Geth's Verdict=50 -Geth, Lord of the Vault=179 +Geth's Grimoire=62 +Geth's Verdict=55 +Geth, Lord of the Vault=127 Geyser Glider=50 Ghalma's Warden=25 -Ghastlord of Fugue=248 -Ghastly Demise=58 +Ghastlord of Fugue=116 +Ghastly Demise=100 Ghastly Discovery=25 Ghastly Remains=49 -Ghazban Ogre=37 +Ghazban Ogre=22 Ghazban Ogress=25 Ghitu Encampment=23 Ghitu Fire=100 @@ -3926,34 +4023,36 @@ Ghitu Slinger=33 Ghitu War Cry=28 Ghor-Clan Bloodscale=25 Ghor-Clan Savage=25 -Ghost Council of Orzhova=114 +Ghost Council of Orzhova=122 Ghost Hounds=100 -Ghost Quarter=116 -Ghost Ship=29 +Ghost Quarter=65 +Ghost Ship=20 Ghost Tactician=28 -Ghost Town=46 +Ghost Town=35 Ghost Warden=25 Ghost-Lit Nourisher=12 Ghost-Lit Raider=25 Ghost-Lit Redeemer=28 Ghost-Lit Stalker=25 Ghost-Lit Warder=25 -Ghostfire=25 -Ghostflame Sliver=40 +Ghostfire=31 +Ghostflame Sliver=44 Ghosthelm Courier=25 Ghostly Changeling=25 Ghostly Flame=50 -Ghostly Possession=32 -Ghostly Prison=269 -Ghostly Visit=50 +Ghostly Flicker=50 +Ghostly Possession=28 +Ghostly Prison=221 +Ghostly Visit=99 Ghostly Wings=599 Ghosts of the Damned=25 -Ghosts of the Innocent=28 -Ghostway=83 +Ghosts of the Innocent=37 +Ghostway=133 Ghoul's Feast=25 Ghoulcaller's Bell=15 -Ghoulcaller's Chant=37 -Ghoulraiser=20 +Ghoulcaller's Chant=32 +Ghoulraiser=16 +Ghoultree=54 Giant Albatross=25 Giant Ambush Beetle=26 Giant Badger=88 @@ -3962,52 +4061,53 @@ Giant Cockroach=26 Giant Crab=39 Giant Dustwasp=25 Giant Fan=127 -Giant Growth=51 -Giant Harbinger=38 -Giant Mantis=25 +Giant Growth=55 +Giant Harbinger=37 +Giant Mantis=36 Giant Octopus=40 -Giant Oyster=35 +Giant Oyster=22 Giant Scorpion=25 -Giant Shark=62 +Giant Shark=99 Giant Slug=14 -Giant Solifuge=99 -Giant Spider=39 +Giant Solifuge=66 +Giant Spider=40 Giant Strength=28 -Giant Tortoise=50 -Giant Trap Door Spider=31 +Giant Tortoise=31 +Giant Trap Door Spider=25 Giant Turtle=25 Giant Warthog=29 Giant's Ire=454 Giantbaiting=25 -Gibbering Descent=52 +Gibbering Descent=25 Gibbering Hyenas=25 Gibbering Kami=25 -Gideon Jura=708 -Gideon's Avenger=91 -Gideon's Lawkeeper=25 -Gift of Estates=52 +Gideon Jura=656 +Gideon's Avenger=66 +Gideon's Lawkeeper=39 +Gift of Estates=36 Gift of Granite=25 -Gift of the Deity=56 +Gift of the Deity=38 Gift of the Gargantuan=25 Gift of the Woods=28 -Gifts Ungiven=747 -Gigadrowse=31 -Gigantiform=50 -Gigantomancer=92 -Gigapede=110 -Gilded Drake=1086 +Gifts Ungiven=907 +Gigadrowse=36 +Gigantiform=35 +Gigantomancer=33 +Gigapede=77 +Gilded Drake=1187 Gilded Light=25 -Gilded Lotus=615 -Gilder Bairn=124 +Gilded Lotus=675 +Gilder Bairn=175 Gilt-Leaf Ambush=40 -Gilt-Leaf Archdruid=112 -Gilt-Leaf Palace=107 +Gilt-Leaf Archdruid=99 +Gilt-Leaf Palace=122 Gilt-Leaf Seer=121 -Giltspire Avenger=72 -Gitaxian Probe=211 +Giltspire Avenger=68 +Gisela, Blade of Goldnight=754 +Gitaxian Probe=34 Glacial Chasm=62 Glacial Crevasses=99 -Glacial Fortress=397 +Glacial Fortress=352 Glacial Plating=40 Glacial Ray=25 Glacial Wall=16 @@ -4015,66 +4115,67 @@ Glaciers=1500 Glade Gnarr=28 Gladecover Scout=34 Glamer Spinners=7 -Glamerdye=49 -Glare of Subdual=125 +Glamerdye=34 +Glare of Subdual=99 Glarecaster=31 Glarewielder=25 Glass Asp=25 Glass Golem=25 Glassdust Hulk=25 -Glasses of Urza=106 +Glasses of Urza=53 Glaze Fiend=25 Gleam of Resistance=25 -Gleancrawler=48 -Gleeful Sabotage=40 -Gleemax=229 -Glen Elendra Archmage=545 -Glen Elendra Liege=281 +Gleancrawler=50 +Gleeful Sabotage=49 +Gleemax=273 +Glen Elendra Archmage=597 +Glen Elendra Liege=257 Glen Elendra Pranksters=25 Gliding Licid=25 Glimmerdust Nap=25 Glimmering Angel=40 -Glimmerpoint Stag=25 -Glimmerpost=38 -Glimmervoid=891 -Glimpse of Nature=1210 -Glimpse the Unthinkable=1201 -Glint Hawk=28 +Glimmerpoint Stag=40 +Glimmerpost=61 +Glimmervoid=939 +Glimpse of Nature=1166 +Glimpse the Unthinkable=1180 +Glint Hawk=36 Glint Hawk Idol=29 Glint-Eye Nephilim=62 Glintwing Invoker=16 -Glissa Sunseeker=280 +Glissa Sunseeker=96 Glissa's Courier=15 -Glissa's Scorn=15 -Glissa, the Traitor=228 -Glistener Elf=76 -Glistening Oil=33 +Glissa's Scorn=32 +Glissa, the Traitor=188 +Glistener Elf=38 +Glistening Oil=41 Glitterfang=25 Glittering Lion=38 Glittering Lynx=25 -Glittering Wish=100 -Global Ruin=56 +Glittering Wish=114 +Global Ruin=62 Gloom=41 +Gloom Surgeon=43 Gloomdrifter=25 Gloomhunter=25 Gloomlance=16 Gloomwidow=25 Gloomwidow's Feast=25 -Glorious Anthem=144 +Glorious Anthem=87 Glorious Charge=40 -Glory=234 +Glory=197 Glory Seeker=25 -Glory of Warfare=112 +Glory of Warfare=88 Gloryscale Viashino=25 Glowering Rogon=16 Glowing Anemone=16 Glowrider=25 Gluetius Maximus=25 Gluttonous Slime=25 -Gluttonous Zombie=36 +Gluttonous Zombie=35 Glyph of Delusion=15 Glyph of Destruction=25 -Glyph of Doom=28 +Glyph of Doom=25 Glyph of Life=25 Glyph of Reincarnation=25 Gnarled Effigy=25 @@ -4082,35 +4183,35 @@ Gnarled Mass=25 Gnat Alley Creeper=12 Gnat Miser=36 Gnathosaur=25 -Gnaw to the Bone=25 -Go for the Throat=167 +Gnaw to the Bone=99 +Go for the Throat=143 Goatnapper=25 Gobhobbler Rats=27 Goblin Archaeologist=25 -Goblin Arsonist=29 +Goblin Arsonist=25 Goblin Artillery=46 Goblin Artisans=39 Goblin Assassin=87 -Goblin Assault=114 -Goblin Balloon Brigade=40 +Goblin Assault=95 +Goblin Balloon Brigade=47 Goblin Bangchuckers=25 Goblin Berserker=26 -Goblin Bomb=253 -Goblin Bombardment=93 +Goblin Bomb=166 +Goblin Bombardment=82 Goblin Bookie=44 Goblin Bowling Team=31 -Goblin Brawler=31 +Goblin Brawler=25 Goblin Brigand=26 Goblin Bully=30 -Goblin Burrows=32 -Goblin Bushwhacker=31 +Goblin Burrows=34 +Goblin Bushwhacker=25 Goblin Cadets=25 Goblin Cannon=8 -Goblin Cavaliers=38 -Goblin Caves=104 -Goblin Charbelcher=222 +Goblin Cavaliers=33 +Goblin Caves=50 +Goblin Charbelcher=225 Goblin Chariot=22 -Goblin Chieftain=62 +Goblin Chieftain=45 Goblin Chirurgeon=40 Goblin Clearcutter=25 Goblin Cohort=25 @@ -4118,70 +4219,70 @@ Goblin Commando=374 Goblin Deathraiders=25 Goblin Digging Team=16 Goblin Dirigible=25 -Goblin Dynamo=35 +Goblin Dynamo=55 Goblin Elite Infantry=18 -Goblin Festival=50 +Goblin Festival=40 Goblin Fire Fiend=25 Goblin Firebug=28 -Goblin Fireslinger=42 +Goblin Fireslinger=34 Goblin Firestarter=108 -Goblin Flectomancer=50 -Goblin Flotilla=43 +Goblin Flectomancer=49 +Goblin Flotilla=77 Goblin Furrier=25 Goblin Game=100 -Goblin Gardener=22 -Goblin Gaveleer=40 -Goblin General=213 +Goblin Gardener=40 +Goblin Gaveleer=25 +Goblin General=137 Goblin Glider=43 -Goblin Goon=92 +Goblin Goon=80 Goblin Grappler=7 Goblin Grenade=52 -Goblin Grenadiers=7 -Goblin Guide=446 +Goblin Grenadiers=25 +Goblin Guide=401 Goblin Hero=22 -Goblin King=217 +Goblin King=212 Goblin Kites=12 -Goblin Lackey=781 +Goblin Lackey=834 Goblin Legionnaire=150 Goblin Lookout=25 -Goblin Lore=118 +Goblin Lore=125 Goblin Lyre=100 Goblin Machinist=45 -Goblin Marshal=125 -Goblin Masons=28 -Goblin Matron=55 +Goblin Marshal=97 +Goblin Masons=32 +Goblin Matron=42 Goblin Medics=47 Goblin Mime=399 -Goblin Mountaineer=25 +Goblin Mountaineer=27 Goblin Mutant=28 -Goblin Offensive=103 +Goblin Offensive=84 Goblin Outlander=50 Goblin Patrol=32 Goblin Piker=26 -Goblin Piledriver=1172 +Goblin Piledriver=1580 Goblin Psychopath=25 -Goblin Pyromancer=58 +Goblin Pyromancer=66 Goblin Raider=26 -Goblin Razerunners=23 -Goblin Recruiter=126 +Goblin Razerunners=58 +Goblin Recruiter=95 Goblin Replica=25 Goblin Rimerunner=25 -Goblin Ringleader=173 -Goblin Rock Sled=7 -Goblin Roughrider=47 -Goblin Ruinblaster=26 +Goblin Ringleader=162 +Goblin Rock Sled=39 +Goblin Roughrider=25 +Goblin Ruinblaster=38 Goblin S.W.A.T. Team=42 Goblin Sappers=20 -Goblin Scouts=40 +Goblin Scouts=36 Goblin Secret Agent=40 -Goblin Settler=3506 -Goblin Sharpshooter=644 +Goblin Settler=3083 +Goblin Sharpshooter=436 Goblin Shortcutter=25 Goblin Shrine=34 -Goblin Ski Patrol=25 +Goblin Ski Patrol=149 Goblin Sky Raider=23 Goblin Skycutter=25 -Goblin Sledder=50 +Goblin Sledder=25 Goblin Snowman=22 Goblin Soothsayer=40 Goblin Spelunkers=34 @@ -4190,241 +4291,250 @@ Goblin Striker=25 Goblin Swine-Rider=25 Goblin Taskmaster=25 Goblin Tinkerer=25 -Goblin Token=68 -Goblin Trenches=30 -Goblin Tunneler=26 +Goblin Token=78 +Goblin Trenches=25 +Goblin Tunneler=25 Goblin Turncoat=12 -Goblin Tutor=142 +Goblin Tutor=157 Goblin Vandal=20 Goblin War Buggy=111 Goblin War Cry=99 -Goblin War Drums=23 +Goblin War Drums=31 Goblin War Paint=40 -Goblin War Strike=41 +Goblin War Strike=48 Goblin War Wagon=25 -Goblin Warchief=232 -Goblin Wardriver=40 -Goblin Warrens=46 -Goblin Welder=476 -Goblin Wizard=480 +Goblin Warchief=184 +Goblin Wardriver=63 +Goblin Warrens=40 +Goblin Welder=487 +Goblin Wizard=383 Goblins of the Flarg=14 -Godhead of Awe=163 -Godless Shrine=1695 +Godhead of Awe=218 +Godless Shrine=1583 Godo's Irregulars=25 -Godo, Bandit Warlord=92 +Godo, Bandit Warlord=180 Gods' Eye, Gate to the Reikai=79 -Godsire=480 +Godsire=498 Godtoucher=25 Godtracker of Jund=40 Goham Djinn=25 -Gold Myr=27 +Gold Myr=22 Golden Bear=65 -Golden Urn=20 -Golden Wish=75 +Golden Urn=31 +Golden Wish=100 Goldenglow Moth=29 Goldmeadow Dodger=40 -Goldmeadow Harrier=25 +Goldmeadow Harrier=39 Goldmeadow Lookout=16 Goldmeadow Stalwart=35 -Golem Artisan=48 -Golem Foundry=25 +Goldnight Commander=25 +Goldnight Redeemer=25 +Golem Artisan=30 +Golem Foundry=31 Golem's Heart=50 Golem-Skin Gauntlets=45 -Golgari Brownscale=40 +Golgari Brownscale=35 Golgari Germination=31 -Golgari Grave-Troll=152 +Golgari Grave-Troll=208 Golgari Guildmage=30 -Golgari Rot Farm=47 +Golgari Rot Farm=35 Golgari Rotwurm=25 Golgari Signet=13 -Golgari Thug=105 +Golgari Thug=114 Golgothian Sylex=99 Goliath Beetle=28 -Goliath Sphinx=32 -Goliath Spider=24 +Goliath Sphinx=62 +Goliath Spider=36 Gomazoa=24 Gore Vassal=25 -Gorehorn Minotaurs=25 +Gorehorn Minotaurs=201 Goretusk Firebeast=27 Gorger Wurm=25 -Gorgon Flail=73 -Gorgon Recluse=40 +Gorgon Flail=25 +Gorgon Recluse=37 Gorilla Berserkers=40 Gorilla Chieftain=22 -Gorilla Shaman=38 +Gorilla Shaman=45 Gorilla Titan=39 -Gorilla War Cry=25 -Gorilla Warrior=14 -Goryo's Vengeance=104 +Gorilla War Cry=16 +Gorilla Warrior=13 +Goryo's Vengeance=201 Gossamer Chains=25 Gossamer Phantasm=25 -Gosta Dirk=208 +Gosta Dirk=135 Govern the Guildless=25 Grab the Reins=37 -Graceful Adept=34 +Graceful Adept=41 Graceful Antelope=25 Graceful Reprieve=40 -Grafted Exoskeleton=27 -Grafted Skullcap=89 -Grafted Wargear=69 -Grand Abolisher=548 -Grand Arbiter Augustin IV=550 -Grand Architect=96 -Grand Coliseum=181 +Grafdigger's Cage=239 +Grafted Exoskeleton=25 +Grafted Skullcap=36 +Grafted Wargear=62 +Grand Abolisher=359 +Grand Arbiter Augustin IV=578 +Grand Architect=87 +Grand Coliseum=105 Grand Melee=26 -Grandmother Sengir=100 +Grandmother Sengir=77 Granger Guildmage=25 -Granite Gargoyle=320 +Granite Gargoyle=557 Granite Grip=33 Granite Shard=25 Granny's Payback=31 Granulate=25 -Grapeshot=66 +Grapeshot=48 Grapeshot Catapult=28 Graphic Violence=11 Grappler Spider=25 -Grappling Hook=43 -Grasp of Darkness=34 +Grappling Hook=33 +Grasp of Darkness=31 Grasp of Phantoms=15 Grassland Crusader=15 Grasslands=25 -Gratuitous Violence=129 +Gratuitous Violence=25 Grave Bramble=35 Grave Consequences=38 -Grave Defiler=104 -Grave Pact=361 +Grave Defiler=68 +Grave Pact=342 Grave Peril=25 Grave Robbers=100 Grave Scrabbler=31 Grave Servitude=100 -Grave Titan=727 -Grave-Shell Scarab=150 -Gravebane Zombie=39 +Grave Titan=599 +Grave-Shell Scarab=75 +Gravebane Zombie=11 Gravebind=35 -Graveborn Muse=78 +Graveborn Muse=46 +Gravecrawler=531 Gravedigger=25 Gravegouger=25 Gravel Slinger=25 Gravelgill Axeshark=49 Gravelgill Duo=25 -Graven Cairns=209 +Graven Cairns=197 Graven Dominator=57 -Gravespawn Sovereign=76 -Gravestorm=86 -Graveyard Shovel=34 -Gravitational Shift=25 -Gravity Sphere=531 -Gravity Well=25 +Gravepurge=32 +Gravespawn Sovereign=50 +Gravestorm=22 +Gravetiller Wurm=32 +Graveyard Shovel=99 +Gravitational Shift=33 +Gravity Sphere=926 +Gravity Well=45 Graxiplon=25 -Gray Ogre=23 -Graypelt Hunter=11 -Graypelt Refuge=70 -Grayscaled Gharial=40 +Gray Ogre=29 +Graypelt Hunter=25 +Graypelt Refuge=33 +Grayscaled Gharial=35 Grazing Gladehart=37 Grazing Kelpie=25 Great Defender=40 -Great Furnace=66 -Great Sable Stag=117 -Great Wall=120 -Great Whale=100 -Greatbow Doyen=85 -Greater Auramancy=392 +Great Furnace=74 +Great Sable Stag=112 +Great Wall=89 +Great Whale=187 +Greatbow Doyen=70 +Greater Auramancy=548 Greater Basilisk=37 Greater Forgeling=25 -Greater Gargadon=104 -Greater Good=176 -Greater Harvester=25 -Greater Morphling=100 +Greater Gargadon=150 +Greater Good=514 +Greater Harvester=62 +Greater Morphling=199 Greater Mossdog=29 Greater Realm of Preservation=25 Greater Werewolf=25 Greatsword=34 -Greed=100 +Greed=57 Greel's Caress=15 Greel, Mind Raker=25 Green Mana Battery=37 Green Scarab=25 -Green Sun's Zenith=646 -Green Ward=73 -Greener Pastures=44 +Green Sun's Zenith=693 +Green Ward=77 +Greener Pastures=40 Greenhilt Trainee=25 Greenseeker=25 Greenweaver Druid=37 -Gremlin Mine=16 -Grid Monitor=25 +Gremlin Mine=32 +Grid Monitor=39 Grief Tyrant=25 -Griffin Canyon=92 +Griffin Canyon=131 Griffin Guide=25 Griffin Rider=34 Griffin Sentinel=12 Grifter's Blade=25 -Grim Affliction=34 +Grim Affliction=32 +Grim Backwoods=40 Grim Discovery=25 -Grim Feast=40 +Grim Feast=100 +Grim Flowering=32 Grim Harvest=40 -Grim Lavamancer=236 -Grim Monolith=1661 -Grim Poppet=88 -Grim Reminder=45 -Grim Tutor=16754 +Grim Lavamancer=220 +Grim Monolith=1497 +Grim Poppet=75 +Grim Reminder=100 +Grim Tutor=16100 Grimclaw Bats=25 -Grimgrin, Corpse-Born=190 -Grimoire Thief=211 -Grimoire of the Dead=88 -Grindclock=44 +Grimgrin, Corpse-Born=132 +Grimoire Thief=122 +Grimoire of the Dead=72 +Grindclock=64 Grinding Station=10 -Grindstone=1289 -Grinning Demon=175 +Grindstone=1343 +Grinning Demon=87 Grinning Ignus=37 -Grinning Totem=49 +Grinning Totem=25 Grip of Amnesia=25 Grip of Chaos=25 +Griselbrand=1017 Gristle Grinner=40 Gristleback=25 Grixis Battlemage=25 Grixis Charm=25 -Grixis Grimblade=35 +Grixis Grimblade=79 Grixis Illusionist=25 -Grixis Panorama=36 +Grixis Panorama=29 Grixis Slavedriver=47 Grixis Sojourners=25 -Grizzled Leotau=35 -Grizzled Outcasts=49 +Grizzled Leotau=38 +Grizzled Outcasts=34 Grizzled Wolverine=25 -Grizzly Bears=25 -Grizzly Fate=31 +Grizzly Bears=26 +Grizzly Fate=25 Groffskithur=29 Grollub=25 Grotag Siege-Runner=25 Grotag Thrasher=11 Grotesque Hybrid=25 Ground Rift=49 -Ground Seal=69 -Groundbreaker=159 +Ground Seal=116 +Groundbreaker=182 Groundling Pouncer=27 -Groundskeeper=46 -Groundswell=54 -Grove of the Burnwillows=829 -Growth Spasm=25 +Groundskeeper=54 +Groundswell=30 +Grove of the Burnwillows=907 +Growth Spasm=36 Growth Spurt=25 -Grozoth=108 -Gruesome Deformity=30 -Gruesome Encore=25 +Grozoth=71 +Gruesome Deformity=32 +Gruesome Encore=32 Gruul Guildmage=40 Gruul Nodorog=25 Gruul Scrapper=15 Gruul Signet=13 -Gruul Turf=28 -Gruul War Plow=99 -Guan Yu's 1,000-Li March=1488 -Guan Yu, Sainted Warrior=498 +Gruul Turf=25 +Gruul War Plow=103 +Guan Yu's 1,000-Li March=1157 +Guan Yu, Sainted Warrior=1299 Guard Dogs=25 Guard Duty=25 -Guard Gomazoa=22 -Guardian Angel=54 -Guardian Beast=3499 +Guard Gomazoa=25 +Guardian Angel=118 +Guardian Beast=3507 Guardian Idol=40 -Guardian Seraph=56 +Guardian Seraph=69 Guardian Zendikon=40 Guardian of Cloverdell=25 Guardian of Solitude=25 @@ -4436,281 +4546,291 @@ Guardians' Pledge=25 Guerrilla Tactics=24 Guided Passage=39 Guided Strike=28 -Guiding Spirit=199 -Guile=233 -Guiltfeeder=207 +Guiding Spirit=112 +Guile=121 +Guiltfeeder=184 Guilty Conscience=36 Gulf Squid=45 Guma=40 Gurzigost=62 Gus=25 -Gush=47 +Gush=40 Gust-Skimmer=25 Gustcloak Cavalier=25 Gustcloak Harrier=25 Gustcloak Runner=25 -Gustcloak Savior=78 +Gustcloak Savior=56 Gustcloak Sentinel=8 Gustcloak Skirmisher=8 Gustha's Scepter=38 Gustrider Exuberant=25 -Gut Shot=139 +Gut Shot=117 Gutless Ghoul=25 -Gutter Grime=28 -Guttural Response=66 +Gutter Grime=27 +Guttural Response=90 Gutwrencher Oni=25 -Guul Draz Assassin=199 -Guul Draz Specter=33 -Guul Draz Vampire=28 -Gwafa Hazid, Profiteer=94 -Gwendlyn Di Corci=1240 +Guul Draz Assassin=210 +Guul Draz Specter=51 +Guul Draz Vampire=36 +Gwafa Hazid, Profiteer=75 +Gwendlyn Di Corci=1860 Gwyllion Hedge-Mage=52 -Haakon, Stromgald Scourge=213 +Haakon, Stromgald Scourge=300 Haazda Exonerator=25 -Haazda Shield Mate=79 -Hada Freeblade=50 -Hada Spy Patrol=25 +Haazda Shield Mate=99 +Hada Freeblade=40 +Hada Spy Patrol=28 Hag Hedge-Mage=25 Hagra Crocodile=25 Hagra Diabolist=37 -Hail Storm=25 +Hail Storm=28 Hail of Arrows=28 -Hair-Strung Koto=25 +Hair-Strung Koto=100 Hakim, Loreweaver=225 Halam Djinn=25 Halberdier=25 Halcyon Glaze=40 -Halfdane=699 -Halimar Depths=52 -Halimar Excavator=38 +Halfdane=399 +Halimar Depths=54 +Halimar Excavator=25 Halimar Wavewatch=25 Hall of Gemstone=50 -Hall of the Bandit Lord=695 +Hall of the Bandit Lord=33 Hallow=25 -Hallowed Burial=188 -Hallowed Fountain=2701 +Hallowed Burial=186 +Hallowed Fountain=2505 Hallowed Ground=10 Hallowed Healer=599 Halls of Mist=39 -Halo Hunter=35 +Halo Hunter=31 Halt Order=25 -Hamlet Captain=25 -Hamletback Goliath=145 +Hamlet Captain=31 +Hamletback Goliath=55 Hammer Mage=25 -Hammer of Bogardan=116 +Hammer of Bogardan=61 Hammer of Ruin=25 -Hammerfist Giant=25 +Hammerfist Giant=35 Hammerhead Shark=32 -Hammerheim=162 +Hammerheim=475 Hammerheim Deadeye=25 Hana Kami=35 Hanabi Blast=25 Hand of Cruelty=75 Hand of Death=31 -Hand of Emrakul=25 -Hand of Honor=94 -Hand of Justice=33 -Hand of the Praetors=109 +Hand of Emrakul=37 +Hand of Honor=91 +Hand of Justice=42 +Hand of the Praetors=73 Hand to Hand=40 Handcuffs=62 Hankyu=40 -Hanna's Custody=149 -Hanna, Ship's Navigator=631 -Hanweir Watchkeep=37 +Hanna's Custody=240 +Hanna, Ship's Navigator=298 +Hanweir Watchkeep=22 Hapless Researcher=25 -Harabaz Druid=43 -Harbinger of Night=100 +Harabaz Druid=41 +Harbinger of Night=39 Harbinger of Spring=25 Harbor Guardian=25 -Harbor Serpent=25 -Harm's Way=25 +Harbor Serpent=30 +Harm's Way=36 Harmattan Efreet=12 Harmless Assault=25 Harmonic Convergence=39 -Harmonic Sliver=135 -Harmonize=133 -Harmony of Nature=298 +Harmonic Sliver=274 +Harmonize=114 +Harmony of Nature=175 Harpoon Sniper=25 Harrier Griffin=14 -Harrow=31 +Harrow=29 Harsh Deceiver=25 -Harsh Judgment=54 +Harsh Judgment=31 Harsh Justice=125 -Harsh Mercy=33 +Harsh Mercy=56 Haru-Onna=12 Harvest Gwyllion=25 Harvest Mage=28 -Harvest Pyre=119 -Harvest Wurm=32 +Harvest Pyre=102 +Harvest Wurm=25 Harvester Druid=25 -Hasran Ogress=70 +Harvester of Souls=60 +Hasran Ogress=139 Hatchet Bully=25 -Hatching Plans=25 +Hatching Plans=50 Hate Weaver=26 Hateflayer=50 -Hatred=362 -Haunted Angel=28 +Hatred=268 +Haunted Angel=50 Haunted Cadaver=28 -Haunted Crossroads=79 +Haunted Crossroads=74 +Haunted Fengraf=25 Haunting Apparition=25 -Haunting Echoes=51 +Haunting Echoes=34 Haunting Hymn=25 Haunting Misery=40 Haunting Wind=56 -Havenwood Battleground=27 +Havengul Lich=559 +Havengul Runebinder=29 +Havenwood Battleground=23 Havenwood Wurm=37 Havoc=38 -Havoc Demon=100 +Havoc Demon=87 Hawkeater Moth=25 Hazduhr the Abbot=100 Haze Frog=25 -Haze of Rage=35 +Haze of Rage=43 Hazerider Drake=25 -Hazezon Tamar=1062 +Hazezon Tamar=1380 Hazy Homunculus=57 -He Who Hungers=100 -Head Games=35 +He Who Hungers=174 +Head Games=39 Head to Head=40 -Headhunter=25 +Headhunter=99 Headless Horseman=25 Headlong Rush=44 Headstone=37 -Heal=26 +Heal=150 Heal the Scars=16 Healer's Headdress=19 Healing Leaves=25 Healing Salve=12 Heap Doll=47 -Heart Sliver=41 -Heart Warden=46 +Heart Sliver=75 +Heart Warden=51 Heart Wolf=16 Heart of Bogardan=25 Heart of Light=27 -Heart of Ramos=56 -Heart of Yavimaya=66 -Heartbeat of Spring=75 -Hearth Charm=26 +Heart of Ramos=25 +Heart of Yavimaya=34 +Heartbeat of Spring=110 +Hearth Charm=34 Hearth Kami=25 Hearthcage Giant=30 -Hearthfire Hobgoblin=77 +Hearthfire Hobgoblin=58 Heartlash Cinder=40 -Heartless Hidetsugu=116 -Heartless Summoning=127 -Heartmender=78 -Heartseeker=112 +Heartless Hidetsugu=44 +Heartless Summoning=82 +Heartmender=83 +Heartseeker=41 Heartstabber Mosquito=11 -Heartstone=25 +Heartstone=37 Heartwood Dryad=999 Heartwood Giant=25 Heartwood Shard=37 -Heartwood Storyteller=100 +Heartwood Storyteller=114 Heartwood Treefolk=38 Heat Ray=155 -Heat Shimmer=50 +Heat Shimmer=35 Heat Stroke=50 -Heat Wave=312 +Heat Wave=249 Heat of Battle=25 -Heaven's Gate=51 +Heaven's Gate=150 Heavy Arbalest=50 Heavy Ballista=27 -Heavy Fog=50 -Hecatomb=50 -Hedge Troll=25 -Hedron Crab=122 -Hedron Matrix=27 +Heavy Fog=225 +Hecatomb=56 +Hedge Troll=100 +Hedron Crab=127 +Hedron Matrix=28 Hedron Rover=25 Hedron Scrabbler=25 -Hedron-Field Purists=33 +Hedron-Field Purists=31 Heed the Mists=25 -Heedless One=173 +Heedless One=211 Heidar, Rimewind Master=25 -Heightened Awareness=25 +Heightened Awareness=33 +Heirs of Stromkirk=25 Helionaut=25 Heliophial=19 Helium Squirter=58 -Helix Pinnacle=115 +Helix Pinnacle=200 Hell Swarm=25 -Hell's Caretaker=232 -Hell's Thunder=142 +Hell's Caretaker=244 +Hell's Thunder=173 Hell-Bent Raider=25 -Hellcarver Demon=73 -Helldozer=113 -Hellfire=691 -Hellfire Mongrel=25 +Hellcarver Demon=80 +Helldozer=115 +Hellfire=739 +Hellfire Mongrel=28 Hellhole Rats=48 Hellion Eruption=25 -Hellkite Charger=37 -Hellkite Hatchling=55 -Hellkite Igniter=30 -Hellkite Overlord=496 -Hellspark Elemental=107 -Helm of Awakening=244 -Helm of Chatzuk=194 -Helm of Kaldra=282 -Helm of Obedience=233 -Helm of Possession=135 +Hellkite Charger=55 +Hellkite Hatchling=40 +Hellkite Igniter=29 +Hellkite Overlord=425 +Hellrider=230 +Hellspark Elemental=117 +Helm of Awakening=105 +Helm of Chatzuk=190 +Helm of Kaldra=216 +Helm of Obedience=273 +Helm of Possession=250 Helm of the Ghastlord=25 +Helvault=260 Hematite Golem=36 Hematite Talisman=37 Henchfiend of Ukor=25 Henge Guardian=40 Henge of Ramos=37 -Herald of Leshrac=129 -Herald of Serra=91 +Herald of Leshrac=99 +Herald of Serra=97 +Herald of War=91 Herbal Poultice=25 Herd Gnarr=29 -Heretic's Punishment=26 -Heritage Druid=88 +Heretic's Punishment=30 +Heritage Druid=87 Hermetic Study=40 -Hermit Druid=122 -Hero of Bladehold=1278 -Hero of Oxid Ridge=366 -Hero's Demise=38 +Hermit Druid=111 +Hero of Bladehold=972 +Hero of Oxid Ridge=224 +Hero's Demise=50 Hero's Resolve=26 -Heroes Remembered=57 -Heroes' Reunion=50 +Heroes Remembered=62 +Heroes' Reunion=49 Heroic Defiance=11 Heroism=25 Hesitation=40 -Hex=76 -Hex Parasite=186 +Hex=79 +Hex Parasite=101 Hexplate Golem=12 -Hibernation=25 -Hibernation Sliver=62 -Hibernation's End=81 +Hibernation=28 +Hibernation Sliver=41 +Hibernation's End=77 Hickory Woodlot=25 Hidden Ancients=48 -Hidden Gibbons=31 +Hidden Gibbons=140 Hidden Guerrillas=46 -Hidden Herd=68 +Hidden Herd=50 Hidden Horror=37 Hidden Path=103 -Hidden Predators=69 +Hidden Predators=179 Hidden Retreat=48 Hidden Spider=75 -Hidden Stag=51 -Hide/Seek=175 +Hidden Stag=36 +Hide/Seek=183 Hideous End=25 Hideous Laughter=25 Hideous Visage=25 Hidetsugu's Second Rite=103 -High Ground=25 -High Market=360 +High Ground=26 +High Market=483 High Seas=47 -High Tide=115 +High Tide=154 +Highborn Ghoul=21 Highland Berserker=42 Highland Giant=29 -Highland Weald=52 +Highland Weald=34 Highway Robber=39 -Higure, the Still Wind=175 +Higure, the Still Wind=125 Hikari, Twilight Guardian=25 -Hill Giant=23 +Hill Giant=24 Hillcomber Giant=25 -Hinder=70 -Hindering Light=25 +Hinder=49 +Hindering Light=63 Hindering Touch=42 -Hint of Insanity=35 -Hinterland Harbor=305 +Hint of Insanity=25 +Hinterland Harbor=345 +Hinterland Hermit=13 Hipparion=26 Hired Giant=27 Hired Muscle=25 @@ -4718,76 +4838,78 @@ Hisoka's Defiance=25 Hisoka's Guard=32 Hisoka, Minamo Sensei=100 Hissing Iguanar=40 -Hissing Miasma=40 +Hissing Miasma=35 Hit/Run=18 -Hive Mind=153 -Hivestone=98 -Hivis of the Scale=100 +Hive Mind=102 +Hivestone=50 +Hivis of the Scale=48 Hoar Shade=25 -Hoard-Smelter Dragon=50 +Hoard-Smelter Dragon=107 Hoarder's Greed=25 -Hoarding Dragon=85 +Hoarding Dragon=99 Hobble=25 Hobgoblin Dragoon=40 -Hokori, Dust Drinker=64 -Hold the Line=121 +Hokori, Dust Drinker=63 +Hold the Line=66 Holistic Wisdom=51 Hollow Dogs=28 Hollow Specter=66 -Hollow Trees=86 +Hollow Trees=91 Hollow Warrior=25 -Hollowborn Barghest=62 +Hollowborn Barghest=60 +Hollowhenge Beast=375 Hollowhenge Scavenger=15 +Hollowhenge Spirit=25 Hollowsage=40 Holy Armor=40 -Holy Day=13 -Holy Light=32 +Holy Day=9 +Holy Light=38 Holy Strength=42 Homarid=100 Homarid Shaman=35 Homarid Spawning Bed=41 Homarid Warrior=26 -Homing Sliver=41 -Homura, Human Ascendant=51 -Honden of Cleansing Fire=44 -Honden of Infinite Rage=99 -Honden of Life's Web=40 +Homing Sliver=25 +Homura, Human Ascendant=26 +Honden of Cleansing Fire=37 +Honden of Infinite Rage=55 +Honden of Life's Web=38 Honden of Night's Reach=25 -Honden of Seeing Winds=25 +Honden of Seeing Winds=33 Honor Guard=31 -Honor of the Pure=218 +Honor of the Pure=198 Honor-Worn Shaku=25 -Honorable Passage=25 +Honorable Passage=26 Honorable Scout=11 Hooded Kavu=25 Hoodwink=25 Hoof Skulkin=25 -Hoofprints of the Stag=33 +Hoofprints of the Stag=60 Hope Charm=28 Hope and Glory=42 Hopping Automaton=40 -Horde of Boggarts=52 -Horde of Notions=100 -Horizon Canopy=674 +Horde of Boggarts=108 +Horde of Notions=45 +Horizon Canopy=623 Horizon Drake=99 Horizon Seed=25 Horizon Spellbomb=47 Horn of Deafening=87 -Horn of Greed=126 +Horn of Greed=137 Horn of Plenty=25 Horn of Ramos=25 Horned Cheetah=29 Horned Helm=52 -Horned Kavu=28 -Horned Sliver=181 +Horned Kavu=15 +Horned Sliver=85 Horned Troll=27 Horned Turtle=24 -Hornet Cannon=45 +Hornet Cannon=40 Hornet Cobra=226 Hornet Harasser=25 Hornet Sting=25 Horobi's Whisper=25 -Horobi, Death's Wail=25 +Horobi, Death's Wail=7 Horrible Hordes=25 Horrifying Revelation=37 Horror of Horrors=27 @@ -4796,243 +4918,255 @@ Hostile Realm=25 Hostility=88 Hot Springs=58 Hotheaded Giant=25 -Hour of Reckoning=58 +Hound of Griselbrand=92 +Hour of Reckoning=64 Hoverguard Observer=25 Hoverguard Sweepers=27 -Hovermyr=38 -Howl from Beyond=25 +Hovermyr=25 +Howl from Beyond=23 Howl of the Night Pack=25 -Howling Banshee=28 +Howling Banshee=31 Howling Fury=40 Howling Gale=25 -Howling Mine=279 +Howling Mine=269 Howling Wolf=41 -Howltooth Hollow=51 +Howltooth Hollow=40 Hua Tuo, Honored Physician=4425 -Huang Zhong, Shu General=957 -Hulking Cyclops=26 +Huang Zhong, Shu General=498 +Hulking Cyclops=29 Hulking Goblin=33 Hulking Ogre=26 -Hull Breach=44 -Hum of the Radix=25 -Humble=25 +Hull Breach=25 +Hum of the Radix=50 +Human Frailty=10 +Humble=31 Humble Budoka=28 -Humility=788 -Hunding Gjornersen=49 +Humility=832 +Hunding Gjornersen=57 Hundred-Talon Kami=25 Hundred-Talon Strike=25 Hundroog=16 +Hunger of the Howlpack=26 Hunger of the Nim=25 Hungry Hungry Heifer=31 Hungry Mist=28 Hungry Spriggan=25 Hunt Down=665 -Hunted Dragon=299 -Hunted Horror=103 -Hunted Lammasu=37 -Hunted Phantasm=25 -Hunted Troll=48 +Hunted Dragon=99 +Hunted Ghoul=25 +Hunted Horror=127 +Hunted Lammasu=105 +Hunted Phantasm=80 +Hunted Troll=145 Hunted Wumpus=25 Hunter Sliver=195 Hunter of Eyeblights=46 Hunter's Insight=31 Hunters' Feast=25 -Hunting Cheetah=1712 +Hunting Cheetah=2200 Hunting Drake=28 -Hunting Grounds=248 +Hunting Grounds=224 Hunting Kavu=25 -Hunting Moa=28 +Hunting Moa=30 Hunting Triad=40 -Hunting Wilds=55 -Hurkyl's Recall=87 -Hurloon Minotaur=36 +Hunting Wilds=25 +Huntmaster of the Fells=1669 +Hurkyl's Recall=152 +Hurloon Minotaur=40 Hurloon Shaman=25 Hurloon Wrangler=25 Hurly-Burly=25 Hurr Jackal=112 -Hurricane=83 +Hurricane=70 Hush=16 Hyalopterous Lemure=31 -Hydroblast=90 +Hydroblast=173 Hydromorph Guardian=28 Hydromorph Gull=25 Hyena Umbra=25 -Hymn of Rebirth=56 -Hymn to Tourach=95 -Hypergenesis=121 +Hymn of Rebirth=25 +Hymn to Tourach=89 +Hypergenesis=113 Hyperion Blacksmith=49 Hypervolt Grasp=25 Hypnotic Cloud=28 -Hypnotic Specter=126 -Hypnox=44 +Hypnotic Specter=131 +Hypnox=36 Hypochondria=25 -Hysterical Blindness=25 -Hystrodon=48 -Ib Halfheart, Goblin Tactician=63 +Hysterical Blindness=32 +Hystrodon=51 +Ib Halfheart, Goblin Tactician=82 Icatian Crier=25 Icatian Infantry=75 -Icatian Javelineers=33 +Icatian Javelineers=35 Icatian Lieutenant=48 Icatian Moneychanger=100 Icatian Phalanx=162 Icatian Priest=27 Icatian Scout=149 -Icatian Skirmishers=34 -Icatian Store=55 +Icatian Skirmishers=44 +Icatian Store=50 Icatian Town=23 Ice Cage=25 Ice Cauldron=99 Ice Cave=25 Ice Floe=54 -Ice Storm=895 +Ice Storm=1015 Iceberg=124 Icefall=40 Icequake=25 Ichneumon Druid=25 Ichor Explosion=25 -Ichor Rats=39 +Ichor Rats=62 Ichor Slick=25 -Ichor Wellspring=26 -Ichorclaw Myr=44 -Ichorid=412 -Icy Manipulator=236 +Ichor Wellspring=30 +Ichorclaw Myr=52 +Ichorid=503 +Icy Manipulator=224 Icy Prison=55 -Ideas Unbound=35 -Identity Crisis=44 +Ideas Unbound=50 +Identity Crisis=96 Idle Thoughts=25 -Idyllic Tutor=463 -Ifh-Biff Efreet=473 +Idyllic Tutor=480 +Ifh-Biff Efreet=389 Igneous Golem=38 Igneous Pouncer=28 Ignite Disorder=25 Ignite Memories=25 Ignoble Soldier=25 Ignorant Bliss=25 -Ihsan's Shade=112 -Iizuka the Ruthless=93 +Ihsan's Shade=52 +Iizuka the Ruthless=74 Ikiral Outrider=25 -Ill-Gotten Gains=211 -Illicit Auction=109 +Ill-Gotten Gains=189 +Illicit Auction=27 Illuminate=50 Illuminated Folio=29 Illuminated Wings=15 Illumination=25 Illusion/Reality=19 Illusionary Forces=700 -Illusionary Mask=6337 +Illusionary Mask=5296 Illusionary Presence=999 -Illusionary Servant=25 +Illusionary Servant=31 Illusionary Terrain=25 Illusionary Wall=137 -Illusions of Grandeur=270 +Illusions of Grandeur=255 Illusory Demon=25 Imagecrafter=35 -Imaginary Pet=41 -Immaculate Magistrate=452 +Imaginary Pet=44 +Immaculate Magistrate=444 +Immerwolf=35 Immobilizing Ink=28 -Immolating Souleater=16 +Immolating Souleater=28 Immolation=28 -Immortal Coil=42 -Imp's Mischief=56 +Immortal Coil=47 +Imp's Mischief=25 Impatience=37 Impelled Giant=25 -Impending Disaster=56 -Imperial Edict=524 -Imperial Hellkite=175 -Imperial Mask=50 -Imperial Recruiter=18015 -Imperial Seal=40765 +Impending Disaster=76 +Imperial Edict=88 +Imperial Hellkite=99 +Imperial Mask=25 +Imperial Recruiter=27000 +Imperial Seal=69000 Imperiosaur=40 -Imperious Perfect=400 -Implements of Sacrifice=39 +Imperious Perfect=404 +Implements of Sacrifice=87 Implode=25 Imposing Visage=22 -Imprison=321 +Imprison=213 Impromptu Raid=25 Improvised Armor=9 -Imps' Taunt=29 -Impulse=52 +Imps' Taunt=40 +Impulse=33 Impulsive Maneuvers=45 -In the Eye of Chaos=1916 +In the Eye of Chaos=1403 In the Web of War=100 -Iname as One=99 -Iname, Death Aspect=25 +Iname as One=190 +Iname, Death Aspect=100 Iname, Life Aspect=88 -Incandescent Soulstoke=136 +Incandescent Soulstoke=208 Incendiary=44 -Incendiary Command=68 -Incinerate=26 +Incendiary Command=63 +Incinerate=53 Incite=25 Incite Hysteria=25 Incite War=52 -Incoming!=127 +Incoming!=145 +Increasing Ambition=36 +Increasing Confusion=58 +Increasing Devotion=69 +Increasing Savagery=58 +Increasing Vengeance=41 Incremental Blight=46 Incremental Growth=25 Incurable Ogre=25 -Indebted Samurai=25 +Indebted Samurai=45 Indentured Djinn=9 Indentured Oaf=25 Independent Troops=50 -Indestructibility=67 +Indestructibility=112 Indestructible Aura=26 Index=31 Indigo Faerie=25 -Indomitable Ancients=78 -Indomitable Archangel=107 -Indomitable Will=40 +Indomitable Ancients=144 +Indomitable Archangel=104 +Indomitable Will=25 Indrik Stomphowler=25 Induce Despair=25 -Induce Paranoia=79 +Induce Paranoia=14 Inertia Bubble=25 Inescapable Brute=25 -Inexorable Tide=48 +Inexorable Tide=2060 Infantry Veteran=16 Infected Vermin=25 Infectious Horror=45 -Infectious Host=29 +Infectious Host=35 Infectious Rage=25 Infernal Caretaker=16 -Infernal Contract=55 +Infernal Contract=56 Infernal Darkness=652 Infernal Denizen=99 Infernal Genesis=42 Infernal Harvest=25 -Infernal Kirin=100 -Infernal Medusa=52 -Infernal Plunge=34 -Infernal Spawn of Evil=647 -Infernal Spawn of Infernal Spawn of Evil=146 -Infernal Tribute=47 -Infernal Tutor=466 -Inferno=51 +Infernal Kirin=20 +Infernal Medusa=144 +Infernal Plunge=37 +Infernal Spawn of Evil=187 +Infernal Spawn of Infernal Spawn of Evil=270 +Infernal Tribute=58 +Infernal Tutor=527 +Inferno=54 Inferno Elemental=47 -Inferno Titan=359 +Inferno Titan=299 Inferno Trap=25 -Infest=25 +Infest=36 Infested Roothold=62 -Infiltrate=40 -Infiltration Lens=62 +Infiltrate=38 +Infiltration Lens=51 Infiltrator il-Kor=25 Infiltrator's Magemark=25 -Infinite Authority=150 +Infinite Authority=179 Infinite Hourglass=44 +Infinite Reflection=47 Inflame=15 Information Dealer=25 Infuse=999 Infused Arrows=25 Ingenious Thief=31 -Ingot Chewer=40 +Ingot Chewer=31 Inheritance=40 Initiate of Blood=36 Initiates of the Ebon Hand=25 Ink Dissolver=25 -Ink-Eyes, Servant of Oni=325 +Ink-Eyes, Servant of Oni=269 Ink-Treader Nephilim=195 Inkfathom Divers=40 -Inkfathom Infiltrator=75 +Inkfathom Infiltrator=170 Inkfathom Witch=25 -Inkmoth Nexus=943 -Inkwell Leviathan=149 +Inkmoth Nexus=530 +Inkwell Leviathan=599 Inner Calm, Outer Strength=25 Inner Fire=25 Inner Sanctum=25 @@ -5040,17 +5174,17 @@ Inner-Chamber Guard=25 Inner-Flame Acolyte=25 Inner-Flame Igniter=28 Innocence Kami=25 -Innocent Blood=93 -Inquisition=262 -Inquisition of Kozilek=243 +Innocent Blood=97 +Inquisition=25 +Inquisition of Kozilek=289 Inquisitor Exarch=25 Inquisitor's Flail=35 Inquisitor's Snare=25 -Insatiable Souleater=16 -Insect Token=49 +Insatiable Souleater=25 +Insect Token=2475 Inside Out=25 -Insidious Bookworms=25 -Insidious Dreams=188 +Insidious Bookworms=16 +Insidious Dreams=148 Insight=31 Insist=25 Insolence=599 @@ -5058,63 +5192,63 @@ Inspiration=26 Inspired Charge=11 Inspired Sprite=40 Inspirit=22 -Instigator=25 -Instigator Gang=58 -Instill Energy=49 +Instigator=38 +Instigator Gang=39 +Instill Energy=42 Instill Furor=25 Instill Infection=37 Insubordination=28 -Insurrection=52 -Intangible Virtue=68 -Interdict=100 +Insurrection=56 +Intangible Virtue=113 +Interdict=39 Intervene=25 -Intervention Pact=102 -Intet, the Dreamer=202 -Intimidation=81 +Intervention Pact=79 +Intet, the Dreamer=72 +Intimidation=100 Intimidation Bolt=25 Intimidator Initiate=25 Into Thin Air=25 Into the Core=43 Into the Fray=25 -Into the Maw of Hell=33 +Into the Maw of Hell=28 Into the North=25 -Into the Roil=38 -Intrepid Hero=92 -Intruder Alarm=257 -Intuition=1362 -Inundate=85 -Invader Parasite=23 -Invasion Plans=50 +Into the Roil=25 +Intrepid Hero=153 +Intruder Alarm=188 +Intuition=1463 +Inundate=31 +Invader Parasite=29 +Invasion Plans=32 Invert the Skies=33 -Invigorate=116 +Invigorate=80 Invigorating Boon=25 Invigorating Falls=40 -Invincible Hymn=69 -Inviolability=25 -Invisibility=47 -Invisible Stalker=64 -Invoke Prejudice=3056 -Invoke the Firemind=102 -Invulnerability=30 -Ion Storm=25 +Invincible Hymn=100 +Inviolability=149 +Invisibility=51 +Invisible Stalker=94 +Invoke Prejudice=2351 +Invoke the Firemind=67 +Invulnerability=35 +Ion Storm=39 Iona's Judgment=25 -Iona, Shield of Emeria=872 +Iona, Shield of Emeria=1080 Ior Ruin Expedition=42 Ire of Kaminari=25 -Iridescent Angel=233 -Iridescent Drake=44 -Irini Sengir=44 +Iridescent Angel=108 +Iridescent Drake=67 +Irini Sengir=47 Iron Lance=40 -Iron Maiden=25 -Iron Myr=25 +Iron Maiden=56 +Iron Myr=28 Iron Star=50 Iron Tusk Elephant=25 -Iron Will=28 +Iron Will=45 Iron-Barb Hellion=25 Iron-Heart Chimera=51 Ironclaw Buzzardiers=25 Ironclaw Curse=55 -Ironclaw Orcs=29 +Ironclaw Orcs=48 Ironfist Crusher=41 Ironhoof Ox=27 Ironroot Treefolk=44 @@ -5122,196 +5256,197 @@ Ironshell Beetle=25 Irradiate=25 Irresistible Prey=25 Irrigation Ditch=14 -Isamaru, Hound of Konda=276 +Isamaru, Hound of Konda=242 Isao, Enlightened Bushi=85 Ishi-Ishi, Akki Crackshot=81 Island=5 -Island Fish Jasconius=159 -Island Sanctuary=87 -Island of Wak-Wak=3409 +Island Fish Jasconius=170 +Island Sanctuary=229 +Island of Wak-Wak=2347 Isleback Spawn=26 -Isochron Scepter=501 -Isolated Chapel=648 -Isolation Cell=39 -Isperia the Inscrutable=25 -It That Betrays=347 -Ith, High Arcanist=25 +Isochron Scepter=496 +Isolated Chapel=646 +Isolation Cell=34 +Isperia the Inscrutable=28 +It That Betrays=467 +Ith, High Arcanist=185 Ivory Charm=28 Ivory Crane Netsuke=25 -Ivory Cup=144 +Ivory Cup=142 Ivory Gargoyle=62 Ivory Giant=25 Ivory Guardians=39 -Ivory Mask=44 -Ivory Tower=187 +Ivory Mask=36 +Ivory Tower=160 Ivy Dancer=25 -Ivy Elemental=175 -Ivy Seer=25 -Iwamori of the Open Fist=36 +Ivy Elemental=65 +Ivy Seer=85 +Iwamori of the Open Fist=65 Ixidor's Will=11 Ixidor, Reality Sculptor=100 -Ixidron=25 -Izzet Boilerworks=40 +Ixidron=64 +Izzet Boilerworks=32 Izzet Chronarch=54 -Izzet Guildmage=45 -Izzet Signet=31 +Izzet Guildmage=40 +Izzet Signet=49 Jabari's Banner=30 Jabari's Influence=27 -Jace Beleren=479 -Jace's Archivist=54 +Jace Beleren=473 +Jace's Archivist=37 Jace's Erasure=25 -Jace's Ingenuity=49 -Jace, Memory Adept=1122 -Jace, the Mind Sculptor=4792 -Jack-in-the-Mox=266 +Jace's Ingenuity=25 +Jace, Memory Adept=960 +Jace, the Mind Sculptor=5009 +Jack-in-the-Mox=188 Jackal Familiar=28 -Jackal Pup=99 +Jackal Pup=25 Jackalope Herd=49 -Jacques le Vert=437 +Jacques le Vert=350 Jaddi Lifestrider=25 Jade Idol=25 Jade Leech=25 -Jade Mage=25 -Jade Monolith=60 -Jade Statue=216 +Jade Mage=37 +Jade Monolith=51 +Jade Statue=193 Jaded Response=28 Jagged Lightning=37 Jagged Poppet=25 -Jagged-Scar Archers=116 +Jagged-Scar Archers=132 Jagwasp Swarm=25 -Jalum Grifter=103 -Jalum Tome=71 +Jalum Grifter=69 +Jalum Tome=59 Jamuraan Lion=11 -Jandor's Ring=83 -Jandor's Saddlebags=52 +Jandor's Ring=126 +Jandor's Saddlebags=50 Jangling Automaton=28 -Jareth, Leonine Titan=369 -Jasmine Boreal=50 -Jasmine Seer=40 +Jar of Eyeballs=32 +Jareth, Leonine Titan=280 +Jasmine Boreal=117 +Jasmine Seer=45 Jawbone Skulkin=52 Jaws of Stone=50 -Jaya Ballard, Task Mage=100 -Jayemdae Tome=193 -Jedit Ojanen=62 -Jedit Ojanen of Efrava=60 +Jaya Ballard, Task Mage=75 +Jayemdae Tome=294 +Jedit Ojanen=38 +Jedit Ojanen of Efrava=130 Jedit's Dragoons=25 -Jenara, Asura of War=285 -Jerrard of the Closed Fist=100 -Jeska, Warrior Adept=85 -Jester's Cap=124 -Jester's Mask=150 -Jester's Scepter=100 +Jenara, Asura of War=635 +Jerrard of the Closed Fist=115 +Jeska, Warrior Adept=75 +Jester's Cap=144 +Jester's Mask=187 +Jester's Scepter=110 Jester's Sombrero=100 -Jet Medallion=430 +Jet Medallion=441 Jetting Glasskite=25 Jeweled Amulet=31 -Jeweled Bird=62 +Jeweled Bird=113 Jeweled Spirit=100 Jeweled Torque=31 Jhessian Balmgiver=41 Jhessian Infiltrator=25 Jhessian Lookout=25 -Jhessian Zombies=45 -Jhoira of the Ghitu=358 -Jhoira's Timebug=25 -Jhoira's Toolbox=25 -Jhovall Queen=25 +Jhessian Zombies=25 +Jhoira of the Ghitu=425 +Jhoira's Timebug=37 +Jhoira's Toolbox=37 +Jhovall Queen=125 Jhovall Rider=25 -Jihad=2612 +Jihad=1835 Jilt=27 -Jin-Gitaxias, Core Augur=546 +Jin-Gitaxias, Core Augur=446 Jinx=375 Jinxed Choker=25 -Jinxed Idol=32 +Jinxed Idol=34 Jinxed Ring=50 -Jiwari, the Earth Aflame=26 -Jodah's Avenger=40 -Johan=316 +Jiwari, the Earth Aflame=34 +Jodah's Avenger=25 +Johan=177 Johnny, Combo Player=192 Johtull Wurm=8 Join the Ranks=35 -Joiner Adept=108 -Jokulhaups=144 -Jokulmorder=159 +Joiner Adept=111 +Jokulhaups=49 +Jokulmorder=25 Jolrael's Centaur=25 Jolrael's Favor=25 -Jolrael, Empress of Beasts=28 +Jolrael, Empress of Beasts=27 Jolt=10 Jolting Merfolk=25 -Jor Kadeen, the Prevailer=54 +Jor Kadeen, the Prevailer=48 Joraga Bard=25 -Joraga Treespeaker=98 -Joraga Warcaller=303 -Jotun Grunt=79 +Joraga Treespeaker=135 +Joraga Warcaller=254 +Jotun Grunt=61 Jotun Owl Keeper=40 Journey of Discovery=25 -Journey to Nowhere=24 -Journeyer's Kite=395 +Journey to Nowhere=36 +Journeyer's Kite=125 Joven=161 Joven's Ferrets=25 Joven's Tools=25 -Jovial Evil=764 +Jovial Evil=448 Joyous Respite=40 -Jugan, the Rising Star=247 -Juggernaut=24 +Jugan, the Rising Star=351 +Juggernaut=26 Juju Bubble=25 -Jukai Messenger=49 +Jukai Messenger=25 Jumbo Imp=31 -Jump=37 +Jump=33 Jund Battlemage=40 -Jund Charm=69 +Jund Charm=25 Jund Hackblade=25 -Jund Panorama=25 +Jund Panorama=31 Jund Sojourners=25 Jungle Barrier=31 -Jungle Basin=102 -Jungle Lion=49 -Jungle Patrol=48 -Jungle Shrine=70 +Jungle Basin=48 +Jungle Lion=69 +Jungle Patrol=25 +Jungle Shrine=104 Jungle Troll=29 Jungle Weaver=45 Jungle Wurm=15 -Juniper Order Advocate=40 +Juniper Order Advocate=19 Juniper Order Druid=25 -Juniper Order Ranger=66 -Junk Diver=99 +Juniper Order Ranger=105 +Junk Diver=138 Junk Golem=26 -Junktroller=45 +Junktroller=36 Junkyo Bell=36 -Juntu Stakes=37 -Junun Efreet=160 -Jushi Apprentice=33 +Juntu Stakes=11 +Junun Efreet=241 +Jushi Apprentice=115 Just Fate=52 -Justice=762 +Justice=62 Juvenile Gloomwidow=25 -Juxtapose=64 -Juzam Djinn=13953 -Jwar Isle Refuge=74 +Juxtapose=63 +Juzam Djinn=13005 +Jwar Isle Refuge=73 Jwari Scuttler=25 -Jwari Shapeshifter=51 -Kabira Crossroads=49 -Kabira Evangel=29 -Kabira Vindicator=38 +Jwari Shapeshifter=35 +Kabira Crossroads=25 +Kabira Evangel=35 +Kabira Vindicator=25 Kaboom!=25 -Kabuto Moth=32 -Kaervek the Merciless=114 +Kabuto Moth=25 +Kaervek the Merciless=57 Kaervek's Hex=29 Kaervek's Purge=25 -Kaervek's Spite=70 -Kaervek's Torch=31 +Kaervek's Spite=97 +Kaervek's Torch=25 Kagemaro's Clutch=25 -Kagemaro, First to Suffer=165 +Kagemaro, First to Suffer=115 Kaho, Minamo Historian=100 -Kaijin of the Vanishing Touch=40 -Kalastria Highborn=255 +Kaijin of the Vanishing Touch=25 +Kalastria Highborn=233 Kaleidostone=40 -Kalitas, Bloodchief of Ghet=208 -Kalonian Behemoth=45 +Kalitas, Bloodchief of Ghet=302 +Kalonian Behemoth=73 Kamahl's Desire=25 Kamahl's Sledge=25 Kamahl's Summons=25 -Kamahl, Fist of Krosa=187 -Kamahl, Pit Fighter=93 +Kamahl, Fist of Krosa=175 +Kamahl, Pit Fighter=104 Kami of Ancient Law=32 Kami of Empty Graves=25 Kami of False Hope=42 @@ -5320,40 +5455,40 @@ Kami of Lunacy=25 Kami of Old Stone=54 Kami of Tattered Shoji=25 Kami of Twisted Reflection=25 -Kami of the Crescent Moon=100 -Kami of the Honored Dead=50 +Kami of the Crescent Moon=137 +Kami of the Honored Dead=25 Kami of the Hunt=25 Kami of the Painted Road=34 Kami of the Palace Fields=25 Kami of the Tended Garden=15 Kami of the Waning Moon=25 -Kangee, Aerie Keeper=79 -Karakas=4640 -Kargan Dragonlord=339 -Karma=19 -Karmic Guide=580 -Karmic Justice=281 -Karn Liberated=971 +Kangee, Aerie Keeper=139 +Karakas=4662 +Kargan Dragonlord=340 +Karma=17 +Karmic Guide=627 +Karmic Justice=155 +Karn Liberated=1131 Karn's Touch=25 -Karn, Silver Golem=727 +Karn, Silver Golem=373 Karona's Zealot=25 Karona, False God=56 -Karoo=52 +Karoo=72 Karoo Meerkat=40 -Karplusan Forest=121 +Karplusan Forest=156 Karplusan Giant=25 -Karplusan Minotaur=79 +Karplusan Minotaur=169 Karplusan Strider=22 Karplusan Wolverine=25 Karplusan Yeti=25 -Karrthus, Tyrant of Jund=446 +Karrthus, Tyrant of Jund=504 Karstoderm=25 -Kashi-Tribe Elite=45 +Kashi-Tribe Elite=55 Kashi-Tribe Reaver=20 Kashi-Tribe Warriors=25 Kasimir the Lone Wolf=100 Katabatic Winds=74 -Kataki, War's Wage=479 +Kataki, War's Wage=448 Kathari Bomber=50 Kathari Remnant=25 Kathari Screecher=25 @@ -5363,107 +5498,110 @@ Kavu Climber=25 Kavu Glider=28 Kavu Howler=25 Kavu Lair=12 -Kavu Mauler=47 +Kavu Mauler=25 Kavu Monarch=58 -Kavu Predator=159 +Kavu Predator=193 Kavu Primarch=29 Kavu Recluse=28 Kavu Runner=27 Kavu Scout=28 -Kavu Titan=69 -Kaysa=124 -Kazandu Blademaster=8 -Kazandu Refuge=32 -Kazandu Tuskcaller=49 +Kavu Titan=31 +Kaysa=114 +Kazandu Blademaster=25 +Kazandu Refuge=37 +Kazandu Tuskcaller=61 Kazuul Warlord=25 -Kazuul, Tyrant of the Cliffs=35 +Kazuul, Tyrant of the Cliffs=27 Kederekt Creeper=50 -Kederekt Leviathan=50 -Kederekt Parasite=33 -Keen Sense=35 +Kederekt Leviathan=28 +Kederekt Parasite=68 +Keen Sense=25 Keen-Eyed Archers=27 Keeneye Aven=28 -Keening Banshee=40 -Keening Stone=134 +Keening Banshee=31 +Keening Stone=82 Keep Watch=61 Keeper of Kookus=40 -Keeper of Progenitus=58 +Keeper of Progenitus=77 Keeper of Tresserhorn=37 Keeper of the Beasts=40 -Keeper of the Dead=50 +Keeper of the Dead=37 Keeper of the Flame=40 Keeper of the Light=40 Keeper of the Mind=32 -Keeper of the Nine Gales=12 +Keeper of the Nine Gales=86 Keeper of the Sacred Word=25 Keepers of the Faith=28 Kei Takahashi=111 -Keiga, the Tide Star=553 +Keiga, the Tide Star=336 Keldon Arsonist=25 Keldon Battlewagon=11 Keldon Berserker=28 -Keldon Champion=25 -Keldon Firebombers=35 +Keldon Champion=51 +Keldon Firebombers=54 Keldon Halberdier=25 Keldon Mantle=28 -Keldon Marauders=35 +Keldon Marauders=32 Keldon Megaliths=25 -Keldon Necropolis=25 +Keldon Necropolis=175 Keldon Twilight=33 Keldon Vandals=25 -Keldon Warlord=48 +Keldon Warlord=71 Kelinore Bat=25 Kelsinko Ranger=25 Kemba's Legion=25 Kemba's Skyguard=35 -Kemba, Kha Regent=41 +Kemba, Kha Regent=31 Kemuri-Onna=41 -Kentaro, the Smiling Cat=62 -Kessig Cagebreakers=38 -Kessig Wolf=100 -Kessig Wolf Run=168 -Kezzerdrix=29 -Khabal Ghoul=1047 -Khalni Garden=31 +Kentaro, the Smiling Cat=75 +Kessig Cagebreakers=36 +Kessig Malcontents=29 +Kessig Recluse=30 +Kessig Wolf=88 +Kessig Wolf Run=113 +Kezzerdrix=95 +Khabal Ghoul=1126 +Khalni Garden=25 Khalni Gem=25 Khalni Heart Expedition=25 -Khalni Hydra=385 -Kher Keep=87 -Kiki-Jiki, Mirror Breaker=795 +Khalni Hydra=423 +Kher Keep=116 +Kiki-Jiki, Mirror Breaker=947 Kiku's Shadow=25 -Kiku, Night's Flower=173 -Kill Switch=56 -Kill! Destroy!=31 +Kiku, Night's Flower=99 +Kill Switch=25 +Kill! Destroy!=81 Kill-Suit Cultist=25 -Killer Bees=43 +Killer Bees=85 Killer Instinct=99 Killer Whale=52 -Kiln Fiend=36 +Killing Wave=153 +Kiln Fiend=25 Kiln Walker=25 -Kilnmouth Dragon=147 +Kilnmouth Dragon=182 Kindercatch=125 Kindle=36 Kindle the Carnage=12 Kindled Fury=11 King Cheetah=45 King Crab=1750 -King Suleiman=1031 -King's Assassin=404 +King Suleiman=659 +King's Assassin=285 Kingfisher=28 Kinsbaile Balloonist=25 -Kinsbaile Borderguard=110 -Kinsbaile Cavalier=202 +Kinsbaile Borderguard=86 +Kinsbaile Cavalier=222 Kinsbaile Skirmisher=25 Kinscaer Harpoonist=25 -Kira, Great Glass-Spinner=1454 -Kird Ape=65 +Kira, Great Glass-Spinner=1346 +Kird Ape=84 Kiri-Onna=49 Kirtar's Desire=25 -Kirtar's Wrath=38 -Kismet=57 +Kirtar's Wrath=121 +Kismet=49 Kiss of Death=130 Kiss of the Amesha=50 -Kitchen Finks=522 +Kitchen Finks=601 Kite Shield=40 Kitesail=41 Kitesail Apprentice=25 @@ -5473,7 +5611,7 @@ Kithkin Greatheart=25 Kithkin Harbinger=25 Kithkin Healer=25 Kithkin Mourncaller=25 -Kithkin Rabble=42 +Kithkin Rabble=35 Kithkin Shielddare=25 Kithkin Spellduster=25 Kithkin Zealot=46 @@ -5484,12 +5622,12 @@ Kitsune Dawnblade=79 Kitsune Diviner=25 Kitsune Healer=25 Kitsune Loreweaver=25 -Kitsune Mystic=26 +Kitsune Mystic=25 Kitsune Palliator=37 Kitsune Riftwalker=25 -Kiyomaro, First to Stand=61 +Kiyomaro, First to Stand=97 Kjeldoran Dead=8 -Kjeldoran Elite Guard=11 +Kjeldoran Elite Guard=50 Kjeldoran Escort=25 Kjeldoran Frostbeast=100 Kjeldoran Gargoyle=25 @@ -5497,85 +5635,85 @@ Kjeldoran Guard=25 Kjeldoran Home Guard=25 Kjeldoran Javelineer=25 Kjeldoran Knight=46 -Kjeldoran Outpost=339 +Kjeldoran Outpost=316 Kjeldoran Outrider=25 Kjeldoran Phalanx=42 Kjeldoran Pride=28 Kjeldoran Royal Guard=37 -Kjeldoran Skycaptain=16 +Kjeldoran Skycaptain=37 Kjeldoran Skyknight=25 Kjeldoran War Cry=25 Kjeldoran Warrior=25 -Knacksaw Clique=99 -Knight Errant=102 -Knight Exemplar=203 +Knacksaw Clique=33 +Knight Errant=105 +Knight Exemplar=244 Knight of Cliffhaven=25 Knight of Dawn=49 -Knight of Dusk=27 -Knight of Meadowgrain=174 -Knight of New Alara=100 -Knight of Stromgald=25 +Knight of Dusk=46 +Knight of Meadowgrain=153 +Knight of New Alara=108 +Knight of Stromgald=44 Knight of Sursi=40 -Knight of Valor=38 +Knight of Valor=40 Knight of the Hokey Pokey=31 -Knight of the Holy Nimbus=65 +Knight of the Holy Nimbus=33 Knight of the Mists=38 -Knight of the Reliquary=896 +Knight of the Reliquary=864 Knight of the Skyward Eye=47 -Knight of the White Orchid=171 -Knight-Captain of Eos=63 -Knighthood=54 +Knight of the White Orchid=208 +Knight-Captain of Eos=116 +Knighthood=55 Knights of Thorn=157 -Knollspine Dragon=143 -Knollspine Invocation=35 -Knotvine Mystic=43 -Knotvine Paladin=91 -Knowledge Exploitation=61 -Knowledge Pool=29 -Knowledge Vault=207 -Knucklebone Witch=81 -Kobold Drill Sergeant=251 -Kobold Overlord=1319 -Kobold Taskmaster=91 -Kobolds of Kher Keep=109 -Kodama of the Center Tree=11 -Kodama of the North Tree=140 +Knollspine Dragon=198 +Knollspine Invocation=25 +Knotvine Mystic=42 +Knotvine Paladin=72 +Knowledge Exploitation=50 +Knowledge Pool=31 +Knowledge Vault=299 +Knucklebone Witch=99 +Kobold Drill Sergeant=163 +Kobold Overlord=999 +Kobold Taskmaster=50 +Kobolds of Kher Keep=84 +Kodama of the Center Tree=100 +Kodama of the North Tree=99 Kodama of the South Tree=25 Kodama's Might=49 -Kodama's Reach=30 -Kokusho, the Evening Star=793 -Konda's Banner=380 -Konda's Hatamoto=73 -Konda, Lord of Eiganjo=293 +Kodama's Reach=35 +Kokusho, the Evening Star=690 +Konda's Banner=269 +Konda's Hatamoto=41 +Konda, Lord of Eiganjo=257 Kongming's Contraptions=925 -Kongming, Sleeping Dragon=795 +Kongming, Sleeping Dragon=1999 Kookus=179 -Kor Aeronaut=35 +Kor Aeronaut=25 Kor Cartographer=45 Kor Chant=28 Kor Dirge=25 -Kor Duelist=25 -Kor Firewalker=38 -Kor Haven=565 -Kor Hookmaster=31 +Kor Duelist=38 +Kor Firewalker=31 +Kor Haven=419 +Kor Hookmaster=13 Kor Line-Slinger=25 Kor Outfitter=35 Kor Sanctifiers=45 -Kor Skyfisher=25 -Kor Spiritdancer=112 -Korlash, Heir to Blackblade=459 -Kormus Bell=173 +Kor Skyfisher=19 +Kor Spiritdancer=120 +Korlash, Heir to Blackblade=558 +Kormus Bell=258 Koskun Falls=100 Koskun Keep=33 -Koth of the Hammer=933 +Koth of the Hammer=565 Koth's Courier=25 Kozilek's Predator=25 -Kozilek, Butcher of Truth=1241 +Kozilek, Butcher of Truth=1407 Kraken Hatchling=25 Kraken's Eye=26 -Krakilin=56 +Krakilin=38 Kranioceros=25 -Krark's Thumb=54 +Krark's Thumb=47 Krark-Clan Engineers=25 Krark-Clan Grunt=25 Krark-Clan Ironworks=155 @@ -5583,53 +5721,53 @@ Krark-Clan Ogre=25 Krark-Clan Shaman=25 Krark-Clan Stoker=25 Krazy Kow=25 -Kresh the Bloodbraided=90 +Kresh the Bloodbraided=108 Kris Mage=25 Krosan Archer=28 Krosan Avenger=28 -Krosan Beast=178 -Krosan Cloudscraper=32 -Krosan Colossus=37 +Krosan Beast=249 +Krosan Cloudscraper=68 +Krosan Colossus=100 Krosan Constrictor=40 -Krosan Drover=39 -Krosan Grip=130 +Krosan Drover=40 +Krosan Grip=184 Krosan Groundshaker=25 Krosan Reclamation=8 -Krosan Restorer=41 -Krosan Tusker=36 -Krosan Verge=45 +Krosan Restorer=54 +Krosan Tusker=25 +Krosan Verge=78 Krosan Vorine=16 -Krosan Warchief=49 +Krosan Warchief=39 Krosan Wayfarer=25 Krovikan Elementalist=25 Krovikan Fetish=28 -Krovikan Horror=103 -Krovikan Mist=146 +Krovikan Horror=174 +Krovikan Mist=102 Krovikan Plague=29 Krovikan Rot=25 Krovikan Scoundrel=25 -Krovikan Sorcerer=26 +Krovikan Sorcerer=30 Krovikan Vampire=25 Krovikan Whispers=25 -Kruin Outlaw=58 +Kruin Outlaw=48 Kry Shield=45 -Kudzu=202 -Kukemssa Pirates=39 +Kudzu=173 +Kukemssa Pirates=46 Kukemssa Serpent=25 Kuldotha Flamefiend=25 -Kuldotha Forgemaster=44 -Kuldotha Phoenix=87 -Kuldotha Rebirth=19 +Kuldotha Forgemaster=42 +Kuldotha Phoenix=34 +Kuldotha Rebirth=29 Kuldotha Ringleader=26 -Kulrath Knight=158 +Kulrath Knight=104 Kumano's Blessing=25 Kumano's Pupils=25 -Kumano, Master Yamabushi=150 -Kuon, Ogre Ascendant=32 +Kumano, Master Yamabushi=99 +Kuon, Ogre Ascendant=100 Kurgadon=25 Kuro's Taken=35 Kuro, Pitlord=100 -Kusari-Gama=95 +Kusari-Gama=100 Kyoki, Sanity's Eclipse=100 Kyren Archive=51 Kyren Glider=28 @@ -5638,84 +5776,86 @@ Kyren Negotiations=100 Kyren Sniper=26 Kyren Toy=79 Kyscu Drake=37 -Lab Rats=28 -Laboratory Maniac=32 +Lab Rats=25 +Laboratory Maniac=34 Labyrinth Minotaur=23 Laccolith Grunt=99 Laccolith Rig=99 Laccolith Titan=25 Laccolith Warrior=25 Laccolith Whelp=99 -Lace with Moonglove=40 +Lace with Moonglove=37 Ladies' Knight=25 -Lady Caleria=125 -Lady Evangela=699 -Lady Orca=127 +Lady Caleria=349 +Lady Evangela=467 +Lady Orca=175 Lady Sun=2298 -Lady Zhurong, Warrior Queen=2600 +Lady Zhurong, Warrior Queen=3400 Lagac Lizard=40 Lairwatch Giant=25 -Lake of the Dead=294 +Lake of the Dead=301 +Lambholt Elder=34 Lammastide Weave=25 Lance=51 Lancers en-Kor=30 Land Aid '04=43 Land Cap=88 -Land Equilibrium=1339 -Land Grant=79 +Land Equilibrium=1102 +Land Grant=55 Land Leeches=29 -Land Tax=633 +Land Tax=792 Land's Edge=75 Landbind Ritual=8 Landfill=100 -Landslide=25 -Lantern Kami=40 -Lantern Spirit=12 +Landslide=37 +Lantern Kami=32 +Lantern Spirit=32 Lantern of Insight=8 Lantern-Lit Graveyard=49 Lapis Lazuli Talisman=16 Lapse of Certainty=25 -Laquatus's Champion=111 +Laquatus's Champion=103 Laquatus's Creativity=45 Laquatus's Disdain=25 -Larceny=50 -Lash Out=100 +Larceny=49 +Lash Out=25 Lashknife=28 Lashknife Barrier=45 -Lashwrithe=180 +Lashwrithe=131 Last Breath=25 Last Caress=25 -Last Chance=249 +Last Chance=399 Last Gasp=16 Last Kiss=25 Last Laugh=62 Last Rites=40 -Last Stand=26 -Last Word=49 +Last Stand=99 +Last Word=55 Last-Ditch Effort=42 Lat-Nam's Legacy=25 -Latchkey Faerie=40 +Latch Seeker=162 +Latchkey Faerie=25 Latulla's Orders=43 -Latulla, Keldon Overseer=25 +Latulla, Keldon Overseer=99 Laughing Hyena=25 -Launch=208 +Launch=15 Lava Axe=34 Lava Blister=46 Lava Burst=25 Lava Dart=40 -Lava Flow=251 +Lava Flow=69 Lava Hounds=37 Lava Runner=24 -Lava Spike=209 +Lava Spike=245 Lava Storm=40 Lava Tubes=35 Lava Zombie=40 -Lavaball Trap=25 +Lavaball Trap=35 Lavaborn Muse=25 -Lavaclaw Reaches=86 +Lavaclaw Reaches=128 Lavacore Elemental=25 Lavafume Invoker=25 -Lavalanche=62 +Lavalanche=104 Lavamancer's Skill=7 Lawbringer=28 Lay Bare=25 @@ -5723,44 +5863,44 @@ Lay Waste=12 Lay of the Land=25 Lead Astray=28 Lead Golem=30 -Lead the Stampede=25 +Lead the Stampede=32 Lead-Belly Chimera=51 Leaden Fists=25 -Leaden Myr=35 +Leaden Myr=34 Leaf Arrow=25 Leaf Dancer=41 Leaf Gilder=25 -Leaf-Crowned Elder=235 -Leafdrake Roost=99 +Leaf-Crowned Elder=305 +Leafdrake Roost=25 Leap=31 -Leap of Flame=99 +Leap of Flame=25 Leaping Lizard=32 Leashling=25 -Leatherback Baloth=92 -Leave No Trace=40 +Leatherback Baloth=49 +Leave No Trace=35 Leech Bonder=25 Leeches=75 Leeching Bite=25 -Leeching Licid=25 +Leeching Licid=40 Leechridden Swamp=49 Leering Emblem=25 Leering Gargoyle=49 Leery Fogbeast=11 -Legacy Weapon=116 -Legacy's Allure=20 -Legerdemain=20 -Legions of Lim-Dul=28 -Leonin Abunas=92 -Leonin Arbiter=35 +Legacy Weapon=61 +Legacy's Allure=69 +Legerdemain=35 +Legions of Lim-Dul=33 +Leonin Abunas=130 +Leonin Arbiter=30 Leonin Armorguard=50 -Leonin Battlemage=41 +Leonin Battlemage=25 Leonin Bladetrap=25 Leonin Bola=25 Leonin Den-Guard=25 Leonin Elder=25 -Leonin Relic-Warder=31 +Leonin Relic-Warder=28 Leonin Scimitar=25 -Leonin Shikari=284 +Leonin Shikari=214 Leonin Skyhunter=25 Leonin Squire=25 Leonin Sun Standard=79 @@ -5768,246 +5908,252 @@ Leshrac's Rite=28 Leshrac's Sigil=25 Lesser Gargadon=22 Lesser Werewolf=100 -Lethal Vapors=58 -Lethargy Trap=45 -Letter Bomb=97 -Leveler=108 -Leviathan=18 -Levitation=28 -Lexivore=35 -Ley Druid=152 +Lethal Vapors=75 +Lethargy Trap=25 +Letter Bomb=148 +Leveler=81 +Leviathan=53 +Levitation=24 +Lexivore=49 +Ley Druid=154 Ley Line=23 -Leyline of Anticipation=57 -Leyline of Lifeforce=93 +Leyline of Anticipation=73 +Leyline of Lifeforce=105 Leyline of Lightning=25 -Leyline of Punishment=42 -Leyline of Sanctity=334 -Leyline of Singularity=25 -Leyline of Vitality=47 -Leyline of the Meek=75 -Leyline of the Void=97 -Lhurgoyf=84 +Leyline of Punishment=36 +Leyline of Sanctity=320 +Leyline of Singularity=28 +Leyline of Vitality=49 +Leyline of the Meek=91 +Leyline of the Void=128 +Lhurgoyf=117 Liability=51 -Liar's Pendulum=29 +Liar's Pendulum=100 Liberate=1100 Liberated Dwarf=28 -Library of Alexandria=16763 -Library of Lat-Nam=89 -Library of Leng=121 -Lich=3114 -Lich Lord of Unx=341 -Lich's Mirror=188 -Lich's Tomb=57 -Lichenthrope=10 +Library of Alexandria=17456 +Library of Lat-Nam=37 +Library of Leng=103 +Lich=3356 +Lich Lord of Unx=411 +Lich's Mirror=231 +Lich's Tomb=100 +Lichenthrope=40 Liege of the Axe=25 Liege of the Hollows=100 -Liege of the Pit=414 -Liege of the Tangle=103 -Lieutenant Kirtar=76 -Life Burst=36 -Life Chisel=124 +Liege of the Pit=99 +Liege of the Tangle=69 +Lieutenant Kirtar=99 +Life Burst=47 +Life Chisel=117 Life Matrix=400 -Life and Limb=69 -Life from the Loam=1086 -Life's Finale=86 -Life/Death=51 -Lifeblood=257 -Lifeforce=41 -Lifegift=28 -Lifelace=124 -Lifeline=229 -Lifelink=93 +Life and Limb=92 +Life from the Loam=1199 +Life's Finale=62 +Life/Death=35 +Lifeblood=137 +Lifeforce=39 +Lifegift=85 +Lifelace=92 +Lifeline=318 +Lifelink=599 Lifesmith=50 Lifespark Spellbomb=25 Lifespinner=71 -Lifetap=22 +Lifetap=30 Lifted by Clouds=25 -Light from Within=146 -Light of Day=45 +Light from Within=150 +Light of Day=22 Light of Sanction=25 Lightbringer=28 -Lighthouse Chronologist=296 -Lightkeeper of Emeria=58 -Lightmine Field=58 -Lightning Angel=82 +Lighthouse Chronologist=386 +Lightkeeper of Emeria=7 +Lightmine Field=41 +Lightning Angel=77 Lightning Axe=25 -Lightning Blast=24 +Lightning Blast=30 Lightning Blow=100 -Lightning Bolt=75 -Lightning Cloud=50 -Lightning Coils=55 -Lightning Crafter=135 +Lightning Bolt=93 +Lightning Cloud=40 +Lightning Coils=37 +Lightning Crafter=214 Lightning Dart=25 -Lightning Dragon=324 -Lightning Elemental=26 -Lightning Greaves=172 -Lightning Helix=254 +Lightning Dragon=398 +Lightning Elemental=25 +Lightning Greaves=167 +Lightning Helix=250 Lightning Hounds=28 -Lightning Reaver=85 +Lightning Mauler=70 +Lightning Reaver=89 Lightning Reflexes=11 Lightning Rift=25 -Lightning Serpent=201 +Lightning Serpent=180 Lightning Storm=25 -Lightning Surge=12 +Lightning Surge=25 Lightning Talons=40 -Lightwielder Paladin=63 -Lignify=25 -Liliana Vess=501 -Liliana of the Veil=2457 -Liliana's Caress=122 -Liliana's Specter=81 +Lightwielder Paladin=62 +Lignify=38 +Liliana Vess=526 +Liliana of the Veil=2150 +Liliana's Caress=202 +Liliana's Specter=52 Lilting Refrain=20 -Lim-Dul the Necromancer=159 -Lim-Dul's Cohort=25 +Lim-Dul the Necromancer=240 +Lim-Dul's Cohort=50 Lim-Dul's Hex=25 -Lim-Dul's High Guard=25 -Lim-Dul's Paladin=37 -Lim-Dul's Vault=185 +Lim-Dul's High Guard=16 +Lim-Dul's Paladin=49 +Lim-Dul's Vault=175 Limestone Golem=25 -Limited Resources=104 -Lin Sivvi, Defiant Hero=126 -Linessa, Zephyr Mage=25 +Limited Resources=114 +Lin Sivvi, Defiant Hero=139 +Linessa, Zephyr Mage=57 Lingering Death=31 Lingering Mirage=25 +Lingering Souls=171 Lingering Tormentor=30 -Linvala, Keeper of Silence=498 -Lion's Eye Diamond=3404 +Linvala, Keeper of Silence=628 +Lion's Eye Diamond=4220 Lionheart Maverick=25 Liquid Fire=25 Liquify=25 -Liquimetal Coating=35 +Liquimetal Coating=33 Lithatog=40 Lithophage=100 Little Girl=62 -Liu Bei, Lord of Shu=399 -Livewire Lash=50 +Liu Bei, Lord of Shu=1275 +Livewire Lash=42 Living Airship=28 Living Armor=22 -Living Artifact=190 -Living Death=269 +Living Artifact=245 +Living Death=253 Living Destiny=25 -Living End=116 -Living Hive=63 -Living Inferno=25 -Living Lands=204 -Living Plane=1106 +Living End=187 +Living Hive=175 +Living Inferno=61 +Living Lands=199 +Living Plane=1185 Living Terrain=28 Living Tsunami=25 -Living Wall=36 -Living Wish=273 -Livonya Silone=11 +Living Wall=62 +Living Wish=364 +Livonya Silone=471 Lizard Warrior=36 Llanowar Augur=40 Llanowar Behemoth=25 Llanowar Cavalry=28 -Llanowar Dead=28 +Llanowar Dead=25 Llanowar Druid=100 Llanowar Elite=50 -Llanowar Elves=23 +Llanowar Elves=41 Llanowar Empath=40 Llanowar Knight=7 -Llanowar Mentor=25 -Llanowar Reborn=25 +Llanowar Mentor=41 +Llanowar Reborn=50 Llanowar Sentinel=22 Llanowar Vanguard=28 -Llanowar Wastes=162 -Llawan, Cephalid Empress=544 -Loafing Giant=49 -Loam Dweller=40 -Loam Lion=48 +Llanowar Wastes=136 +Llawan, Cephalid Empress=432 +Loafing Giant=25 +Loam Dweller=25 +Loam Lion=41 Loamdragger Giant=25 -Loaming Shaman=100 -Lobotomy=38 +Loaming Shaman=200 +Lobotomy=22 Loch Korrigan=25 Locket of Yesterdays=79 Lockjaw Snapper=41 Locust Miser=25 Locust Swarm=14 -Lodestone Bauble=123 -Lodestone Golem=104 -Lodestone Myr=101 +Lodestone Bauble=125 +Lodestone Golem=95 +Lodestone Myr=81 Logic Knot=19 Lone Missionary=40 -Lone Wolf=45 -Lonely Sandbar=46 -Long-Forgotten Gohei=62 -Long-Term Plans=25 -Longbow Archer=42 +Lone Revenant=52 +Lone Wolf=51 +Lonely Sandbar=25 +Long-Forgotten Gohei=38 +Long-Term Plans=26 +Longbow Archer=56 Longhorn Firebeast=40 Looming Hoverguard=25 Looming Shade=16 Loose Lips=40 -Looter il-Kor=25 -Lord Magnus=144 -Lord of Atlantis=449 -Lord of Extinction=538 -Lord of Shatterskull Pass=60 -Lord of Tresserhorn=42 -Lord of the Pit=178 -Lord of the Undead=588 -Lord of the Unreal=124 +Looter il-Kor=100 +Lord Magnus=103 +Lord of Atlantis=282 +Lord of Extinction=508 +Lord of Shatterskull Pass=64 +Lord of Tresserhorn=21 +Lord of the Pit=207 +Lord of the Undead=660 +Lord of the Unreal=60 Lore Broker=25 -Lorescale Coatl=65 -Lorthos, the Tidemaker=64 +Lorescale Coatl=87 +Lorthos, the Tidemaker=76 Lose Hope=49 Lost Auramancers=40 Lost Hours=25 Lost Leonin=25 -Lost Order of Jarkeld=75 +Lost Order of Jarkeld=100 Lost Soul=25 Lost in Thought=55 Lost in the Mist=33 -Lotus Bloom=507 -Lotus Blossom=116 -Lotus Cobra=498 -Lotus Guardian=70 -Lotus Petal=269 -Lotus Vale=469 +Lost in the Woods=43 +Lotus Bloom=500 +Lotus Blossom=96 +Lotus Cobra=535 +Lotus Guardian=28 +Lotus Petal=245 +Lotus Vale=448 Lovisa Coldeyes=62 Lowland Basilisk=31 Lowland Giant=25 Lowland Oaf=25 Lowland Tracker=25 Loxodon Anchorite=25 -Loxodon Convert=25 -Loxodon Gatekeeper=57 -Loxodon Hierarch=116 +Loxodon Convert=11 +Loxodon Gatekeeper=58 +Loxodon Hierarch=81 Loxodon Mender=25 Loxodon Mystic=27 Loxodon Partisan=25 Loxodon Peacekeeper=62 -Loxodon Punisher=102 +Loxodon Punisher=51 Loxodon Stalwart=25 -Loxodon Warhammer=108 -Loxodon Wayfarer=45 +Loxodon Warhammer=155 +Loxodon Wayfarer=30 +Loyal Cathar=67 Loyal Gyrfalcon=25 -Loyal Retainers=10916 -Loyal Sentry=31 -Lu Bu, Master-at-Arms=924 +Loyal Retainers=9999 +Loyal Sentry=57 +Lu Bu, Master-at-Arms=759 Lu Meng, Wu General=500 Lu Su, Wu Advisor=850 -Lu Xun, Scholar General=2045 +Lu Xun, Scholar General=2098 Lucent Liminid=28 -Ludevic's Test Subject=29 +Ludevic's Test Subject=44 Lull=38 -Lullmage Mentor=41 +Lullmage Mentor=35 Lumbering Satyr=25 -Lumberknot=25 +Lumberknot=99 Lumengrid Augur=25 Lumengrid Drake=25 Lumengrid Gargoyle=50 Lumengrid Sentinel=25 Lumengrid Warden=25 -Luminarch Ascension=124 +Luminarch Ascension=198 Luminesce=25 -Luminescent Rain=41 -Luminous Angel=159 +Luminescent Rain=25 +Luminous Angel=150 Luminous Guardian=25 Luminous Wake=25 Lumithread Field=25 Lunar Avenger=29 +Lunar Mystic=45 Lunge=32 -Lunk Errant=25 +Lunk Errant=29 Lure=38 Lure of Prey=64 Lurebound Scarecrow=25 @@ -6017,440 +6163,444 @@ Lurking Evil=41 Lurking Informant=31 Lurking Jackals=19 Lurking Nightstalker=25 -Lurking Predators=89 +Lurking Predators=100 Lurking Skirge=12 Lush Growth=35 -Lust for War=38 -Lux Cannon=103 +Lust for War=25 +Lux Cannon=82 Lymph Sliver=35 -Lynx=207 +Lynx=231 Lys Alana Bowmaster=40 -Lys Alana Huntmaster=114 -Lys Alana Scarblade=25 -Lyzolda, the Blood Witch=58 +Lys Alana Huntmaster=44 +Lys Alana Scarblade=107 +Lyzolda, the Blood Witch=44 Ma Chao, Western Warrior=1165 Macabre Waltz=25 Macetail Hystrodon=11 Machinate=25 -Mad Auntie=88 +Mad Auntie=32 Mad Dog=28 Madblind Mountain=27 Maddening Imp=51 Maddening Wind=150 -Madrush Cyclops=42 -Maelstrom Archangel=444 +Madrush Cyclops=26 +Maelstrom Archangel=537 Maelstrom Djinn=25 -Maelstrom Nexus=128 -Maelstrom Pulse=943 -Maga, Traitor to Mortals=23 -Mage Slayer=30 +Maelstrom Nexus=210 +Maelstrom Pulse=899 +Maga, Traitor to Mortals=100 +Mage Slayer=140 Mage il-Vec=28 Mage's Guile=7 -Magebane Armor=45 +Magebane Armor=49 Magefire Wings=25 -Mages' Contest=49 -Mageta The Lion=104 +Mages' Contest=11 +Mageta The Lion=113 Mageta's Boon=599 Magewright's Stone=41 Maggot Carrier=13 Maggot Therapy=25 -Magical Hack=198 +Magical Hack=184 Magical Hacker=43 -Magister Sphinx=67 -Magistrate's Scepter=390 +Magister Sphinx=31 +Magistrate's Scepter=283 Magistrate's Veto=56 Magma Burst=28 -Magma Giant=43 -Magma Jet=238 +Magma Giant=49 +Magma Jet=205 Magma Mine=45 -Magma Phoenix=42 +Magma Phoenix=33 Magma Rift=25 -Magma Sliver=246 +Magma Sliver=290 Magma Spray=25 Magma Vein=25 Magmasaur=20 Magmatic Core=25 Magmaw=25 Magnetic Flux=25 -Magnetic Mine=25 -Magnetic Mountain=30 +Magnetic Mine=26 +Magnetic Mountain=42 Magnetic Theft=25 Magnetic Web=41 Magnify=25 -Magnigoth Treefolk=75 -Magnivore=47 -Magosi, the Waterveil=49 -Magus of the Abyss=88 -Magus of the Arena=175 -Magus of the Bazaar=79 -Magus of the Candelabra=85 -Magus of the Coffers=64 -Magus of the Disk=123 -Magus of the Future=100 -Magus of the Jar=32 -Magus of the Library=31 -Magus of the Mirror=56 -Magus of the Moat=298 -Magus of the Moon=270 -Magus of the Scroll=25 -Magus of the Tabernacle=37 -Magus of the Unseen=90 -Magus of the Vineyard=41 -Mahamoti Djinn=353 -Major Teroh=69 +Magnigoth Treefolk=15 +Magnivore=25 +Magosi, the Waterveil=30 +Magus of the Abyss=46 +Magus of the Arena=26 +Magus of the Bazaar=55 +Magus of the Candelabra=69 +Magus of the Coffers=149 +Magus of the Disk=79 +Magus of the Future=47 +Magus of the Jar=35 +Magus of the Library=38 +Magus of the Mirror=25 +Magus of the Moat=202 +Magus of the Moon=320 +Magus of the Scroll=49 +Magus of the Tabernacle=63 +Magus of the Unseen=44 +Magus of the Vineyard=47 +Mahamoti Djinn=467 +Major Teroh=56 Make a Wish=37 -Makeshift Mannequin=138 +Makeshift Mannequin=38 Makeshift Mauler=12 Makindi Griffin=40 Makindi Shieldmate=25 -Malach of the Dawn=37 +Malach of the Dawn=38 Malachite Golem=27 Malachite Talisman=100 -Malakir Bloodwitch=77 +Malakir Bloodwitch=104 Malevolent Awakening=25 -Malfegor=123 +Malfegor=110 Malicious Advice=28 Malignant Growth=25 +Malignus=124 Mammoth Harness=50 -Mammoth Umbra=85 +Mammoth Umbra=12 Man of Measure=25 -Man-o'-War=50 +Man-o'-War=97 Mana Breach=22 Mana Cache=25 Mana Chains=25 Mana Clash=30 -Mana Crypt=5966 -Mana Cylix=34 -Mana Drain=10672 -Mana Echoes=125 +Mana Crypt=5306 +Mana Cylix=31 +Mana Drain=11686 +Mana Echoes=154 Mana Flair=28 -Mana Flare=552 +Mana Flare=339 Mana Geyser=18 -Mana Leak=117 +Mana Leak=66 Mana Leech=25 -Mana Matrix=494 +Mana Matrix=389 Mana Maze=49 Mana Prism=39 -Mana Reflection=467 +Mana Reflection=606 Mana Screw=41 Mana Seism=25 -Mana Severance=107 -Mana Short=197 +Mana Severance=100 +Mana Short=158 Mana Skimmer=25 -Mana Tithe=54 +Mana Tithe=76 Mana Vapors=79 -Mana Vault=977 -Mana Vortex=500 -Mana Web=142 -Manabarbs=89 -Manabond=349 +Mana Vault=760 +Mana Vortex=224 +Mana Web=175 +Manabarbs=95 +Manabond=305 Manacles of Decay=25 Manaforce Mace=25 -Manaforge Cinder=43 +Manaforge Cinder=49 Manakin=40 Manalith=25 -Manamorphose=142 -Manaplasm=25 -Mangara of Corondor=196 -Mangara's Blessing=37 +Manamorphose=159 +Manaplasm=75 +Mangara of Corondor=419 +Mangara's Blessing=35 Mangara's Equity=29 Mangara's Tome=37 Maniacal Rage=26 Manic Vandal=25 Manipulate Fate=25 Mannichi, the Fevered Dream=56 -Manor Gargoyle=29 -Manor Skeleton=19 -Manriki-Gusari=72 +Manor Gargoyle=31 +Manor Skeleton=32 +Manriki-Gusari=76 Manta Ray=29 -Manta Riders=40 +Manta Riders=35 Mantis Engine=25 Mantle of Leadership=30 -Maralen of the Mornsong=94 +Maralen of the Mornsong=75 Marauding Knight=56 Maraxus of Keld=69 -Marble Chalice=47 -Marble Diamond=30 -Marble Priest=99 -Marble Titan=24 -March of Souls=63 -March of the Machines=53 +Marble Chalice=36 +Marble Diamond=23 +Marble Priest=40 +Marble Titan=30 +March of Souls=25 +March of the Machines=43 Marhault Elsdragon=100 -Marisi's Twinclaws=46 +Marisi's Twinclaws=36 Maritime Guard=25 Marjhan=50 -Mark of Asylum=63 -Mark of Eviction=38 -Mark of Fury=40 -Mark of Mutiny=25 +Mark of Asylum=57 +Mark of Eviction=25 +Mark of Fury=58 +Mark of Mutiny=99 Mark of Sakiko=40 Mark of the Oni=40 -Marker Beetles=28 -Markov Patrician=25 -Maro=564 +Marker Beetles=40 +Markov Blademaster=76 +Markov Patrician=35 +Markov Warlord=13 +Maro=601 Marrow Chomper=50 -Marrow Shards=52 -Marrow-Gnawer=235 +Marrow Shards=30 +Marrow-Gnawer=240 Marsh Boa=38 Marsh Casualties=35 Marsh Crocodile=26 -Marsh Flats=843 +Marsh Flats=847 Marsh Flitter=25 Marsh Gas=16 Marsh Goblins=25 Marsh Lurker=28 Marsh Threader=25 Marsh Viper=19 -Marshal's Anthem=56 +Marshal's Anthem=38 Marshaling Cry=25 -Marshaling the Troops=2500 +Marshaling the Troops=1166 Marshdrinker Giant=28 -Martial Coup=192 +Martial Coup=285 Marton Stromgald=100 Martyr of Ashes=25 Martyr of Bones=25 Martyr of Frost=25 -Martyr of Sands=54 +Martyr of Sands=70 Martyr of Spores=25 -Martyr's Cause=33 -Martyr's Cry=85 +Martyr's Cause=41 +Martyr's Cry=74 Martyrdom=40 -Martyred Rusalka=25 -Martyrs of Korlis=26 +Martyred Rusalka=30 +Martyrs of Korlis=200 Martyrs' Tomb=25 -Masako the Humorless=52 -Mask of Avacyn=31 +Masako the Humorless=74 +Mask of Avacyn=39 Mask of Intolerance=25 -Mask of Law and Grace=50 -Mask of Memory=38 -Mask of Riddles=55 +Mask of Law and Grace=40 +Mask of Memory=25 +Mask of Riddles=61 Mask of the Mimic=37 -Masked Admirers=66 +Masked Admirers=80 Masked Gorgon=32 -Mass Calcify=108 -Mass Hysteria=65 -Mass Polymorph=46 +Mass Calcify=100 +Mass Hysteria=51 +Mass Polymorph=52 Mass of Ghouls=8 -Massacre=33 -Massacre Wurm=340 -Master Apothecary=64 +Massacre=34 +Massacre Wurm=308 +Master Apothecary=66 Master Decoy=25 Master Healer=13 Master Splicer=34 Master Thief=36 -Master Transmuter=450 +Master Transmuter=519 Master of Arms=38 -Master of Etherium=341 -Master of the Hunt=104 +Master of Etherium=326 +Master of the Hunt=253 Master of the Veil=25 -Master of the Wild Hunt=430 -Master's Call=25 -Masticore=283 +Master of the Wild Hunt=462 +Master's Call=34 +Masticore=171 Masumaro, First to Live=25 Matca Rioters=25 Matopi Golem=25 Matsu-Tribe Birdstalker=25 -Matsu-Tribe Decoy=49 -Matsu-Tribe Sniper=27 -Maul Splicer=25 -Mausoleum Guard=9 +Matsu-Tribe Decoy=25 +Matsu-Tribe Sniper=43 +Maul Splicer=24 +Mausoleum Guard=28 Mausoleum Turnkey=25 -Maw of the Mire=16 +Maw of the Mire=32 Mawcor=22 -Mayael the Anima=180 -Mayael's Aria=138 -Mayor of Avabruck=202 -Maze of Ith=2490 -Maze of Shadows=26 -Meadowboon=114 +Mayael the Anima=245 +Mayael's Aria=156 +Mayor of Avabruck=159 +Maze of Ith=2597 +Maze of Shadows=58 +Meadowboon=25 Measure of Wickedness=35 Meddle=37 -Meddling Kids=100 -Meddling Mage=92 +Meddling Kids=102 +Meddling Mage=206 Medicine Bag=25 Medicine Runner=29 -Meditate=395 -Meekstone=218 +Meditate=603 +Meekstone=180 Megatherium=25 -Megatog=42 -Meglonoth=124 -Megrim=27 -Meishin, the Mind Cage=313 +Megatog=25 +Meglonoth=140 +Megrim=30 +Meishin, the Mind Cage=100 Melancholy=42 -Melee=9 -Melesse Spirit=17 +Melee=39 +Melesse Spirit=25 Melira's Keepers=25 -Melira, Sylvok Outcast=123 -Meloku the Clouded Mirror=116 -Melt Terrain=16 -Meltdown=19 +Melira, Sylvok Outcast=131 +Meloku the Clouded Mirror=93 +Melt Terrain=34 +Meltdown=25 Melting=999 -Memnarch=321 -Memnite=127 -Memoricide=58 -Memory Crystal=25 -Memory Erosion=156 -Memory Jar=181 +Memnarch=352 +Memnite=107 +Memoricide=50 +Memory Crystal=76 +Memory Erosion=105 +Memory Jar=276 Memory Lapse=21 -Memory Plunder=139 -Memory Sluice=109 -Memory's Journey=25 +Memory Plunder=162 +Memory Sluice=74 +Memory's Journey=34 Menacing Ogre=27 Mending Hands=26 Meng Huo's Horde=50 -Meng Huo, Barbarian King=2700 -Mental Discipline=38 -Mental Misstep=140 +Meng Huo, Barbarian King=3499 +Mental Discipline=43 +Mental Misstep=90 Mental Note=50 -Mentor of the Meek=70 -Mephidross Vampire=457 -Mephitic Ooze=25 +Mentor of the Meek=50 +Mephidross Vampire=581 +Mephitic Ooze=46 Mercadia's Downfall=25 -Mercadian Atlas=36 -Mercadian Bazaar=25 +Mercadian Atlas=51 +Mercadian Bazaar=99 Mercadian Lift=25 Mercenaries=10 Mercenary Informer=54 -Mercenary Knight=498 -Merchant Scroll=89 -Merchant Ship=448 +Mercenary Knight=571 +Merchant Scroll=119 +Merchant Ship=301 Merchant of Secrets=26 Mercurial Kite=28 -Mercy Killing=47 -Merfolk Assassin=89 -Merfolk Looter=37 +Mercy Killing=46 +Merfolk Assassin=35 +Merfolk Looter=9 Merfolk Mesmerist=30 Merfolk Observer=25 Merfolk Raiders=38 Merfolk Seastalkers=28 Merfolk Seer=28 Merfolk Skyscout=25 -Merfolk Sovereign=51 -Merfolk Spy=40 -Merfolk Thaumaturgist=40 +Merfolk Sovereign=53 +Merfolk Spy=50 +Merfolk Thaumaturgist=25 Merfolk Traders=25 Merfolk Wayfinder=10 Merfolk of the Pearl Trident=23 -Merieke Ri Berit=37 +Merieke Ri Berit=128 Merrow Bonegnawer=25 -Merrow Commerce=58 +Merrow Commerce=100 Merrow Grimeblotter=25 Merrow Harbinger=25 Merrow Levitator=49 -Merrow Reejerey=186 +Merrow Reejerey=153 Merrow Wavebreakers=25 Merrow Witsniper=25 Merseine=7 -Mesa Chicken=32 -Mesa Enchantress=28 +Mesa Chicken=25 +Mesa Enchantress=34 Mesa Falcon=26 -Mesa Pegasus=28 +Mesa Pegasus=22 Mesmeric Fiend=31 -Mesmeric Orb=146 -Mesmeric Sliver=38 +Mesmeric Orb=82 +Mesmeric Sliver=37 Mesmeric Trance=25 Messenger Falcons=25 Metal Fatigue=25 Metallic Mastery=27 -Metallic Sliver=40 +Metallic Sliver=38 Metallurgeon=31 -Metalworker=1075 +Metalworker=862 Metamorphic Wurm=50 Metamorphose=14 Metamorphosis=22 Metathran Aerostat=49 Metathran Elite=25 -Metathran Soldier=52 +Metathran Soldier=103 Metathran Transport=25 Metathran Zombie=25 -Meteor Crater=95 +Meteor Crater=122 Meteor Shower=185 -Meteor Storm=50 -Metrognome=25 -Michiko Konda, Truth Seeker=210 -Midnight Banshee=136 -Midnight Charm=40 +Meteor Storm=25 +Metrognome=34 +Michiko Konda, Truth Seeker=223 +Midnight Banshee=149 +Midnight Charm=25 Midnight Covenant=25 -Midnight Haunting=71 +Midnight Haunting=57 Midnight Ritual=34 Midsummer Revel=48 -Might Sliver=83 +Might Sliver=44 Might Weaver=25 Might of Alara=25 -Might of Oaks=105 -Might of Old Krosa=25 +Might of Oaks=86 +Might of Old Krosa=97 Might of the Masses=37 Might of the Nephilim=25 -Mightstone=25 +Mightstone=40 Mighty Emergence=43 Mighty Leap=11 -Mijae Djinn=450 -Mikaeus, the Lunarch=246 -Mikokoro, Center of the Sea=250 +Mijae Djinn=193 +Mikaeus, the Lunarch=204 +Mikaeus, the Unhallowed=344 +Mikokoro, Center of the Sea=347 Militant Monk=28 -Militia's Pride=132 +Militia's Pride=102 Millikin=43 -Millstone=72 +Millstone=48 Mimeofacture=25 -Mimic Vat=131 +Mimic Vat=109 Minamo Scrollkeeper=25 Minamo Sightbender=25 Minamo's Meddling=42 -Minamo, School at Water's Edge=313 -Mind Bend=22 +Minamo, School at Water's Edge=380 +Mind Bend=20 Mind Bomb=42 Mind Burst=38 Mind Control=42 Mind Extraction=28 -Mind Funeral=334 +Mind Funeral=378 Mind Games=57 -Mind Harness=71 +Mind Harness=113 Mind Knives=29 Mind Maggots=25 -Mind Over Matter=403 +Mind Over Matter=354 Mind Peel=25 Mind Ravel=26 -Mind Rot=40 -Mind Shatter=32 +Mind Rot=39 +Mind Shatter=68 Mind Slash=24 Mind Sludge=23 -Mind Spring=63 -Mind Stone=31 +Mind Spring=35 +Mind Stone=56 Mind Swords=38 -Mind Twist=567 -Mind Unbound=32 +Mind Twist=354 +Mind Unbound=31 Mind Warp=42 Mind Whip=25 -Mind's Desire=63 -Mind's Eye=507 +Mind's Desire=39 +Mind's Eye=483 Mindbender Spores=79 Mindblaze=100 -Mindbreak Trap=253 -Mindcrank=60 +Mindbreak Trap=233 +Mindcrank=65 Mindculling=25 Mindlash Sliver=25 -Mindleech Mass=139 -Mindless Automaton=54 +Mindleech Mass=86 +Mindless Automaton=45 Mindless Null=25 Mindlock Orb=25 -Mindmoil=30 -Mindshrieker=40 -Mindslaver=101 -Mindslicer=62 +Mindmoil=57 +Mindshrieker=36 +Mindslaver=89 +Mindslicer=115 Mindstab=19 Mindstab Thrull=9 Mindstorm Crown=25 Mindwarper=25 -Mindwhip Sliver=39 -Mindwrack Liege=84 +Mindwhip Sliver=51 +Mindwrack Liege=115 Mine Bearer=61 Mine Excavation=25 -Mine Layer=141 +Mine Layer=69 Mine, Mine, Mine!=49 -Minion Reflector=25 -Minion of Leshrac=79 +Minion Reflector=56 +Minion of Leshrac=74 Minion of Tevesh Szat=99 -Minion of the Wastes=32 +Minion of the Wastes=34 Minions' Murmurs=25 Minister of Impediments=25 Minotaur Explorer=27 @@ -6458,63 +6608,63 @@ Minotaur Illusionist=25 Minotaur Tactician=28 Minotaur Warrior=38 Miracle Worker=40 -Miraculous Recovery=79 -Mirari=175 -Mirari's Wake=858 +Miraculous Recovery=104 +Mirari=92 +Mirari's Wake=722 Mire Blight=47 -Mire Boa=65 +Mire Boa=37 Mire Kavu=28 Mire Shade=37 Mire's Toll=25 -Miren, the Moaning Well=417 +Miren, the Moaning Well=419 Mirozel=52 -Mirran Crusader=448 -Mirran Mettle=25 +Mirran Crusader=324 +Mirran Mettle=34 Mirran Spy=25 -Mirri the Cursed=218 -Mirri's Guile=636 -Mirri, Cat Warrior=76 -Mirrodin's Core=36 -Mirror Entity=344 -Mirror Gallery=362 +Mirri the Cursed=225 +Mirri's Guile=774 +Mirri, Cat Warrior=55 +Mirrodin's Core=66 +Mirror Entity=362 +Mirror Gallery=298 Mirror Golem=128 -Mirror Mirror=127 +Mirror Mirror=116 Mirror Sheen=130 -Mirror Strike=109 -Mirror Universe=3650 +Mirror Strike=25 +Mirror Universe=2835 Mirror Wall=28 -Mirror of Fate=49 -Mirror-Mad Phantasm=36 -Mirror-Sigil Sergeant=152 -Mirrorweave=145 +Mirror of Fate=25 +Mirror-Mad Phantasm=35 +Mirror-Sigil Sergeant=175 +Mirrorweave=200 Mirrorwood Treefolk=25 -Mirrorworks=40 -Miscalculation=31 +Mirrorworks=46 +Miscalculation=45 Mischievous Poltergeist=30 -Mischievous Quanar=25 -Misdirection=880 -Mise=32 +Mischievous Quanar=49 +Misdirection=1063 +Mise=25 Misers' Cage=75 Misery Charm=46 -Misfortune=56 +Misfortune=49 Misfortune's Gain=50 Misguided Rage=25 -Mishra's Bauble=56 -Mishra's Factory=364 +Mishra's Bauble=83 +Mishra's Factory=301 Mishra's Groundbreaker=25 -Mishra's Helix=192 +Mishra's Helix=107 Mishra's War Machine=87 -Mishra's Workshop=28347 -Mishra, Artificer Prodigy=70 -Misinformation=31 +Mishra's Workshop=27773 +Mishra, Artificer Prodigy=114 +Misinformation=124 Miss Demeanor=62 Misshapen Fiend=47 Misstep=28 -Mist Dragon=113 +Mist Dragon=25 Mist Leopard=25 Mist of Stagnation=79 -Mistbind Clique=226 -Mistblade Shinobi=47 +Mistbind Clique=254 +Mistblade Shinobi=111 Mistform Dreamer=28 Mistform Mask=25 Mistform Mutant=25 @@ -6526,158 +6676,162 @@ Mistform Stalker=25 Mistform Ultimus=28 Mistform Wakecaster=56 Mistform Wall=25 -Mistform Warchief=48 -Mistmeadow Skulk=15 +Mistform Warchief=28 +Misthollow Griffin=292 +Mistmeadow Skulk=10 Mistmeadow Witch=50 Mistmoon Griffin=40 -Mistral Charger=25 +Mistral Charger=37 Mistveil Plains=64 -Mistvein Borderpost=28 -Misty Rainforest=1142 -Mitotic Manipulation=35 -Mitotic Slime=34 -Mizzium Transreliquat=25 -Mnemonic Nexus=48 -Mnemonic Sliver=37 +Mistvein Borderpost=25 +Misty Rainforest=1196 +Mitotic Manipulation=31 +Mitotic Slime=36 +Mizzium Transreliquat=52 +Mnemonic Nexus=25 +Mnemonic Sliver=40 Mnemonic Wall=25 -Moan of the Unhallowed=35 +Moan of the Unhallowed=37 Moaning Spirit=33 -Moat=5534 +Moat=5052 Mob Justice=40 Mob Mentality=41 Mobile Fort=12 -Mobilization=114 +Mobilization=137 Mobilize=35 Mogg Alarm=599 -Mogg Assassin=79 +Mogg Assassin=28 Mogg Bombers=25 Mogg Cannon=44 Mogg Conscripts=16 -Mogg Fanatic=22 -Mogg Flunkies=25 +Mogg Fanatic=24 +Mogg Flunkies=36 Mogg Hollows=58 -Mogg Infestation=31 +Mogg Infestation=64 Mogg Jailer=25 -Mogg Maniac=58 -Mogg Raider=100 +Mogg Maniac=61 +Mogg Raider=28 Mogg Salvage=29 -Mogg Sentry=22 +Mogg Sentry=40 Mogg Squad=25 Mogg Toady=25 -Mogg War Marshal=25 -Moggcatcher=86 +Mogg War Marshal=43 +Moggcatcher=76 Mold Adder=45 -Mold Demon=273 +Mold Demon=339 Mold Shambler=25 Molder=25 Molder Beast=25 Molder Slug=25 Moldervine Cloak=46 -Moldgraf Monstrosity=33 +Moldgraf Monstrosity=31 Mole Worms=25 -Molimo, Maro-Sorcerer=53 -Molten Disaster=31 +Molimo, Maro-Sorcerer=40 +Molten Disaster=67 Molten Firebird=56 Molten Frame=25 -Molten Hydra=60 -Molten Influence=107 -Molten Psyche=25 -Molten Rain=30 +Molten Hydra=74 +Molten Influence=93 +Molten Psyche=35 +Molten Rain=25 Molten Ravager=28 -Molten Sentry=30 +Molten Sentry=25 Molten Slagheap=25 -Molten-Tail Masticore=91 -Moltensteel Dragon=65 +Molten-Tail Masticore=60 +Moltensteel Dragon=57 Molting Harpy=39 Molting Skin=25 -Moment of Heroism=14 +Moment of Heroism=28 Moment of Silence=25 -Moment's Peace=36 +Moment's Peace=47 Momentary Blink=37 -Momentous Fall=38 +Momentous Fall=45 Momentum=37 -Momir Vig, Simic Visionary=309 +Momir Vig, Simic Visionary=222 +Mondronen Shaman=47 Moniker Mage=28 Monk Idealist=28 Monk Realist=40 Monkey Cage=100 Monkey Monkey Monkey=28 -Monomania=32 -Mons's Goblin Raiders=30 +Monomania=26 +Mons's Goblin Raiders=23 Mons's Goblin Waiters=40 Monsoon=25 Monstrify=25 -Monstrous Carabid=25 -Monstrous Growth=48 -Monstrous Hound=208 -Moon Heron=25 -Moon Sprite=38 +Monstrous Carabid=35 +Monstrous Growth=46 +Monstrous Hound=148 +Moon Heron=34 +Moon Sprite=31 Moonbow Illusionist=25 Moonglove Changeling=114 Moonglove Extract=25 -Moonglove Winnower=40 +Moonglove Winnower=38 Moonhold=25 -Moonlace=25 +Moonlace=62 Moonlight Bargain=30 Moonlit Strider=25 Moonlit Wake=25 -Moonmist=38 +Moonmist=58 Moonring Island=70 Moonring Mirror=50 +Moonsilver Spear=104 +Moonveil Dragon=101 Moonwing Moth=25 Moor Fiend=25 -Moorish Cavalry=85 -Moorland Haunt=136 +Moorish Cavalry=193 +Moorland Haunt=90 Morale=15 Morality Shift=47 Moratorium Stone=54 Morbid Bloom=25 Morbid Hunger=28 -Morbid Plunder=25 -Mordant Dragon=21 +Morbid Plunder=36 +Mordant Dragon=34 Morgue Theft=25 Morgue Thrull=25 Morgue Toad=25 -Morinfen=100 +Morinfen=10 Moriok Reaver=25 Moriok Replica=25 Moriok Rigger=79 Moriok Scavenger=25 Morkrut Banshee=25 -Moroii=25 -Morphling=494 -Morsel Theft=25 +Moroii=36 +Morphling=525 +Morsel Theft=40 Morselhoarder=25 -Mortal Combat=75 +Mortal Combat=66 Mortal Wound=11 -Mortarpod=55 -Mortician Beetle=42 +Mortarpod=112 +Mortician Beetle=44 Mortify=66 Mortipede=25 Mortiphobia=25 -Mortis Dogs=15 -Mortivore=59 -Mortuary=23 -Mosquito Guard=25 +Mortis Dogs=28 +Mortivore=76 +Mortuary=49 +Mosquito Guard=33 Moss Diamond=21 Moss Kami=25 Moss Monster=27 -Mossbridge Troll=148 +Mossbridge Troll=25 Mossdog=25 Mossfire Egg=40 -Mossfire Valley=125 +Mossfire Valley=149 Mosstodon=245 -Mosswort Bridge=152 -Mothdust Changeling=40 +Mosswort Bridge=218 +Mothdust Changeling=25 Mother of Goons=25 -Mother of Runes=381 +Mother of Runes=338 Mothrider Samurai=25 Mountain=5 -Mountain Bandit=157 +Mountain Bandit=274 Mountain Goat=27 Mountain Stronghold=500 Mountain Titan=100 -Mountain Valley=78 +Mountain Valley=25 Mountain Yeti=39 Mounted Archers=25 Mourner's Shield=25 @@ -6685,15 +6839,15 @@ Mournful Zombie=25 Mourning=28 Mourning Thrull=40 Mournwhelk=25 -Mouth of Ronom=76 +Mouth of Ronom=40 Mouth to Mouth=25 -Mox Diamond=2598 -Mox Emerald=34888 -Mox Jet=43892 -Mox Opal=1710 -Mox Pearl=31894 -Mox Ruby=37222 -Mox Sapphire=49675 +Mox Diamond=2547 +Mox Emerald=38866 +Mox Jet=39457 +Mox Opal=1431 +Mox Pearl=31977 +Mox Ruby=32495 +Mox Sapphire=43798 Mtenda Griffin=40 Mtenda Herder=29 Mtenda Lion=25 @@ -6701,109 +6855,110 @@ Muck Drubb=25 Muck Rats=23 Mudbrawler Cohort=25 Mudbrawler Raiders=25 -Mudbutton Clanger=13 +Mudbutton Clanger=25 Mudbutton Torchrunner=40 -Muddle the Mixture=15 +Muddle the Mixture=74 Mudhole=25 Mudslide=100 -Mul Daya Channelers=85 -Mulch=20 -Mulldrifter=39 +Mul Daya Channelers=67 +Mulch=36 +Mulldrifter=72 Multani's Acolyte=46 -Multani's Decree=25 +Multani's Decree=100 Multani's Harmony=10 Multani's Presence=49 -Multani, Maro-Sorcerer=96 -Mundungu=58 +Multani, Maro-Sorcerer=174 +Mundungu=38 Mungha Wurm=62 -Muraganda Petroglyphs=85 +Muraganda Petroglyphs=87 Murasa Pyromancer=42 Murder of Crows=50 -Murderous Betrayal=28 -Murderous Redcap=103 +Murderous Betrayal=37 +Murderous Redcap=33 Murderous Spoils=25 Murk Dwellers=7 -Murkfiend Liege=371 -Murmuring Bosk=282 +Murkfiend Liege=437 +Murmuring Bosk=263 Murmurs from Beyond=25 Muscle Burst=50 -Muscle Sliver=47 +Muscle Sliver=90 Muse Vessel=62 Musician=99 Mutagenic Growth=34 -Mutavault=2702 -Mutilate=186 +Mutavault=2391 +Mutilate=173 Muzzle=25 -Mwonvuli Acid-Moss=36 +Mwonvuli Acid-Moss=25 Mwonvuli Ooze=7 My First Tome=40 -Mycoid Shepherd=109 +Mycoid Shepherd=104 Mycologist=50 -Mycoloth=252 -Mycosynth Fiend=25 -Mycosynth Golem=941 -Mycosynth Lattice=408 -Mycosynth Wellspring=16 -Myojin of Cleansing Fire=150 -Myojin of Infinite Rage=26 -Myojin of Life's Web=280 -Myojin of Night's Reach=62 -Myojin of Seeing Winds=56 +Mycoloth=311 +Mycosynth Fiend=32 +Mycosynth Golem=807 +Mycosynth Lattice=396 +Mycosynth Wellspring=22 +Myojin of Cleansing Fire=77 +Myojin of Infinite Rage=90 +Myojin of Life's Web=247 +Myojin of Night's Reach=139 +Myojin of Seeing Winds=69 Myr Adapter=15 -Myr Battlesphere=80 -Myr Enforcer=58 -Myr Galvanizer=54 -Myr Incubator=83 +Myr Battlesphere=45 +Myr Enforcer=38 +Myr Galvanizer=74 +Myr Incubator=46 Myr Landshaper=25 -Myr Matrix=227 +Myr Matrix=319 Myr Mindservant=37 Myr Moonvessel=25 -Myr Propagator=38 +Myr Propagator=44 Myr Prototype=36 Myr Quadropod=25 -Myr Reservoir=44 -Myr Retriever=101 -Myr Servitor=24 +Myr Reservoir=32 +Myr Retriever=105 +Myr Servitor=25 Myr Sire=25 -Myr Superion=147 -Myr Token=88 -Myr Turbine=46 -Myr Welder=30 -Myrsmith=25 +Myr Superion=133 +Myr Token=27 +Myr Turbine=68 +Myr Welder=32 +Myrsmith=38 Mysteries of the Deep=25 -Mystic Compass=30 -Mystic Crusader=52 +Mystic Compass=27 +Mystic Crusader=37 Mystic Decree=157 -Mystic Denial=37 -Mystic Enforcer=77 +Mystic Denial=34 +Mystic Enforcer=88 Mystic Familiar=30 -Mystic Gate=494 -Mystic Melting=40 +Mystic Gate=561 +Mystic Melting=39 Mystic Might=73 Mystic Penitent=44 Mystic Remora=50 Mystic Restraints=49 -Mystic Snake=101 +Mystic Retrieval=28 +Mystic Snake=119 Mystic Speculation=35 Mystic Veil=27 Mystic Visionary=28 Mystic Zealot=28 Mystical Teachings=40 -Mystical Tutor=377 -Mystifying Maze=101 -Mythic Proportions=79 +Mystical Tutor=373 +Mystifying Maze=81 +Mythic Proportions=44 Nacatl Hunt-Pride=408 Nacatl Outlander=46 Nacatl Savage=102 Nacatl War-Pride=25 Nacre Talisman=25 -Nafs Asp=32 +Nafs Asp=31 Nagao, Bound by Honor=79 Nakaya Shade=25 Naked Singularity=45 -Nalathni Dragon=114 +Nalathni Dragon=160 Name Dropping=40 -Nameless Inversion=71 +Nameless Inversion=49 Nameless One=25 Nameless Race=56 Nantuko Blightcutter=56 @@ -6813,154 +6968,159 @@ Nantuko Disciple=37 Nantuko Elder=49 Nantuko Husk=24 Nantuko Mentor=100 -Nantuko Monastery=49 -Nantuko Shade=58 +Nantuko Monastery=45 +Nantuko Shade=57 Nantuko Shaman=25 Nantuko Shrine=112 Nantuko Tracer=25 -Nantuko Vigilante=40 +Nantuko Vigilante=100 Narcissism=25 Narcolepsy=25 -Narcomoeba=165 +Narcomoeba=148 Narrow Escape=25 Narwhal=81 Nath of the Gilt-Leaf=147 Nath's Buffoon=40 Nath's Elite=25 -Natural Affinity=27 -Natural Balance=69 +Natural Affinity=40 +Natural Balance=112 Natural Emergence=36 -Natural Order=2438 -Natural Selection=1103 +Natural Order=2236 +Natural Selection=1032 Natural Spring=8 Naturalize=22 -Nature's Blessing=12 -Nature's Chosen=25 +Nature's Blessing=55 +Nature's Chosen=19 Nature's Claim=25 -Nature's Cloak=146 +Nature's Cloak=121 Nature's Kiss=28 -Nature's Lore=46 +Nature's Lore=31 Nature's Resurgence=74 Nature's Revolt=47 -Nature's Ruin=396 -Nature's Spiral=36 -Nature's Will=62 +Nature's Ruin=348 +Nature's Spiral=48 +Nature's Will=36 Nature's Wrath=100 -Nausea=28 +Nausea=27 Naya Battlemage=25 -Naya Charm=49 +Naya Charm=25 Naya Hushblade=25 Naya Panorama=31 Naya Sojourners=25 -Near-Death Experience=58 -Nebuchadnezzar=113 +Near-Death Experience=41 +Nearheath Pilgrim=38 +Nearheath Stalker=125 +Nebuchadnezzar=112 Neck Snap=29 Necra Disciple=28 Necra Sanctuary=40 Necratog=25 -Necravolver=99 +Necravolver=25 Necrite=26 Necro-Impotence=100 Necrogen Censer=47 -Necrogen Mists=25 -Necrogen Scudder=38 -Necrogen Spellbomb=36 +Necrogen Mists=100 +Necrogen Scudder=50 +Necrogen Spellbomb=25 Necrogenesis=25 -Necrologia=22 -Necromancer's Covenant=121 +Necrologia=33 +Necromancer's Covenant=170 Necromancer's Magemark=31 -Necromancy=120 +Necromancy=136 Necromantic Thirst=25 -Necropede=29 -Necroplasm=83 +Necropede=56 +Necroplasm=175 Necropolis=50 -Necropotence=241 -Necropouncer=35 -Necrosavant=45 -Necroskitter=353 -Necrotic Ooze=74 +Necropotence=403 +Necropouncer=34 +Necrosavant=44 +Necroskitter=437 +Necrotic Ooze=72 Necrotic Plague=25 -Necrotic Sliver=99 +Necrotic Sliver=90 Nectar Faerie=25 Need for Speed=29 Needle Drop=25 -Needle Specter=107 -Needle Storm=25 +Needle Specter=137 +Needle Storm=28 Needlebite Trap=40 Needlebug=31 Needlepeak Spider=27 Needleshot Gourna=16 Nefarious Lich=25 Nefashu=25 -Negate=30 -Neko-Te=104 -Nekrataal=31 +Negate=27 +Neko-Te=64 +Nekrataal=32 Nema Siltlurker=25 -Nemata, Grove Guardian=102 +Nemata, Grove Guardian=110 Nemesis Mask=63 Nemesis Trap=100 -Nemesis of Reason=314 +Nemesis of Reason=379 Nephalia Drownyard=40 Nessian Courser=50 -Nest Invader=50 -Nested Ghoul=30 +Nest Invader=25 +Nested Ghoul=34 Nesting Wurm=25 Nether Horror=25 -Nether Shadow=547 -Nether Spirit=255 -Nether Traitor=275 -Nether Void=7986 +Nether Shadow=572 +Nether Spirit=347 +Nether Traitor=251 +Nether Void=8268 Netherborn Phalanx=25 Netter en-Dal=28 -Nettle Sentinel=44 +Nettle Sentinel=65 Nettletooth Djinn=100 -Nettlevine Blight=74 -Nettling Curse=33 -Nettling Imp=84 +Nettlevine Blight=60 +Nettling Curse=25 +Nettling Imp=140 Neurok Commando=37 Neurok Familiar=25 Neurok Hoversail=27 -Neurok Invisimancer=35 +Neurok Invisimancer=31 Neurok Prodigy=25 Neurok Replica=29 Neurok Spy=25 Neurok Stealthsuit=32 Neurok Transmuter=25 -Neverending Torment=200 +Neverending Torment=74 Nevermaker=40 -Nevermore=33 -Nevinyrral's Disk=788 -New Benalia=25 -New Frontiers=155 +Nevermore=32 +Nevinyrral's Disk=656 +New Benalia=38 +New Frontiers=81 Nezumi Bone-Reader=25 -Nezumi Cutthroat=35 -Nezumi Graverobber=36 +Nezumi Cutthroat=25 +Nezumi Graverobber=88 Nezumi Ronin=25 Nezumi Shadow-Watcher=25 -Nezumi Shortfang=250 +Nezumi Shortfang=271 Niall Silvain=175 -Nicol Bolas=470 +Niblis of the Breath=25 +Niblis of the Urn=28 +Nicol Bolas=170 Nicol Bolas, Planeswalker=182 -Night Dealings=40 +Night Dealings=100 Night Revelers=16 Night Soil=25 -Night Terrors=33 -Night of Souls' Betrayal=48 -Night's Whisper=94 +Night Terrors=32 +Night of Souls' Betrayal=87 +Night's Whisper=80 Night/Day=15 -Nightbird's Clutches=25 -Nightcreep=57 +Nightbird's Clutches=32 +Nightcreep=100 Nightguard Patrol=25 Nighthaze=25 -Nightmare=290 -Nightmare Incursion=70 -Nightmare Lash=25 +Nightmare=766 +Nightmare Incursion=38 +Nightmare Lash=73 Nightmare Void=45 Nightscape Apprentice=16 Nightscape Battlemage=25 -Nightscape Familiar=49 +Nightscape Familiar=38 Nightscape Master=79 Nightshade Assassin=31 +Nightshade Peddler=65 Nightshade Schemers=25 Nightshade Seer=25 Nightshade Stinger=25 @@ -6969,145 +7129,145 @@ Nightsoil Kami=25 Nightstalker Engine=165 Nightwind Glider=25 Nightwing Shade=45 -Nihil Spellbomb=36 +Nihil Spellbomb=44 Nihilistic Glee=25 -Nihilith=25 +Nihilith=99 Nikko-Onna=25 Nim Abomination=25 -Nim Deathmantle=52 -Nim Devourer=25 +Nim Deathmantle=44 +Nim Devourer=100 Nim Grotesque=25 Nim Lasher=25 Nim Replica=25 Nim Shambler=34 Nim Shrieker=25 Nimana Sell-Sword=100 -Nimble Mongoose=134 -Nimbus Maze=167 +Nimble Mongoose=178 +Nimbus Maze=184 Nimbus Wings=25 Nine-Ringed Bo=25 -Ninja of the Deep Hours=49 -Nip Gwyllion=40 -Nirkana Cutthroat=52 -Nirkana Revenant=506 -Nissa Revane=479 -Nissa's Chosen=62 -Niv-Mizzet, the Firemind=1007 +Ninja of the Deep Hours=28 +Nip Gwyllion=34 +Nirkana Cutthroat=25 +Nirkana Revenant=644 +Nissa Revane=664 +Nissa's Chosen=123 +Niv-Mizzet, the Firemind=880 Niveous Wisps=49 Nivix, Aerie of the Firemind=25 -Nix=44 -No Mercy=405 +Nix=33 +No Mercy=215 No Quarter=26 No Rest for the Wicked=46 No-Dachi=25 -Nobilis of War=112 -Noble Benefactor=100 -Noble Elephant=40 -Noble Hierarch=1594 +Nobilis of War=131 +Noble Benefactor=99 +Noble Elephant=25 +Noble Hierarch=1786 Noble Panther=25 -Noble Purpose=79 +Noble Purpose=38 Noble Stand=11 Noble Steeds=28 Noble Templar=26 Noble Vestige=25 Nocturnal Raid=25 -Noetic Scales=58 +Noetic Scales=195 Noggin Whack=25 Noggle Bandit=25 Noggle Bridgebreaker=25 Noggle Hedge-Mage=40 Noggle Ransacker=25 Nomad Decoy=41 -Nomad Mythmaker=27 +Nomad Mythmaker=24 Nomad Stadium=41 Nomadic Elf=25 -Nomads en-Kor=37 +Nomads en-Kor=25 Nomads' Assembly=25 -Norin the Wary=56 -Norn's Annex=79 +Norin the Wary=50 +Norn's Annex=74 Norritt=195 -North Star=284 -Northern Paladin=105 +North Star=322 +Northern Paladin=292 Norwood Archers=50 -Norwood Priestess=975 +Norwood Priestess=1302 Norwood Ranger=25 Norwood Riders=29 Norwood Warrior=28 -Nostalgic Dreams=61 +Nostalgic Dreams=48 Nosy Goblin=28 -Not of This World=25 +Not of This World=50 Notorious Assassin=30 Notorious Throng=25 Nourish=25 Nourishing Shoal=25 -Nova Chaser=171 -Nova Cleric=16 -Nova Pentacle=475 -Novablast Wurm=116 +Nova Chaser=146 +Nova Cleric=39 +Nova Pentacle=341 +Novablast Wurm=114 Novijen Sages=38 -Novijen, Heart of Progress=44 +Novijen, Heart of Progress=115 Now I Know My ABC's=100 -Noxious Field=25 -Noxious Ghoul=50 +Noxious Field=42 +Noxious Ghoul=58 Noxious Hatchling=25 -Noxious Revival=32 +Noxious Revival=111 Noxious Toad=100 Noxious Vapors=25 Nucklavee=25 Nuisance Engine=37 -Null Brooch=37 +Null Brooch=56 Null Chamber=29 Null Champion=25 -Null Profusion=44 -Null Rod=525 -Nullmage Advocate=40 -Nullmage Shepherd=36 +Null Profusion=25 +Null Rod=778 +Nullmage Advocate=12 +Nullmage Shepherd=35 Nullstone Gargoyle=25 -Nulltread Gargantuan=25 +Nulltread Gargantuan=43 Numai Outcast=25 Number Crunch=28 Numbing Dose=38 -Numot, the Devastator=97 +Numot, the Devastator=96 Nurturer Initiate=29 -Nurturing Licid=25 -Nut Collector=334 -Nyxathid=157 +Nurturing Licid=35 +Nut Collector=275 +Nyxathid=220 O-Naginata=25 Oaken Brawler=25 Oakenform=25 Oakgnarl Warrior=25 -Oasis=160 -Oath of Druids=509 +Oasis=145 +Oath of Druids=621 Oath of Ghouls=37 -Oath of Lieges=85 +Oath of Lieges=25 Oath of Lim-Dul=62 -Oath of Mages=31 -Oath of Scholars=25 +Oath of Mages=33 +Oath of Scholars=100 Oathkeeper, Takeno's Daisho=100 Oathsworn Giant=16 Ob Nixilis, the Fallen=100 -Obelisk of Alara=56 +Obelisk of Alara=112 Obelisk of Bant=25 -Obelisk of Esper=100 +Obelisk of Esper=33 Obelisk of Grixis=25 Obelisk of Jund=25 Obelisk of Naya=25 -Obelisk of Undoing=56 -Oblation=95 -Obliterate=138 +Obelisk of Undoing=48 +Oblation=43 +Obliterate=50 Oblivion Crown=41 -Oblivion Ring=93 -Oblivion Stone=153 +Oblivion Ring=83 +Oblivion Stone=129 Oboro Breezecaller=29 Oboro Envoy=25 -Oboro, Palace in the Clouds=160 +Oboro, Palace in the Clouds=182 Obsessive Search=25 -Obsianus Golem=45 -Obsidian Acolyte=40 -Obsidian Battle-Axe=12 -Obsidian Fireheart=45 +Obsianus Golem=63 +Obsidian Acolyte=100 +Obsidian Battle-Axe=25 +Obsidian Fireheart=101 Obsidian Giant=29 -Obstinate Baloth=72 +Obstinate Baloth=46 Obstinate Familiar=37 Ocular Halo=40 Oculus=35 @@ -7117,118 +7277,118 @@ Odylic Wraith=25 Off Balance=25 Offalsnout=74 Offering to Asha=45 -Ogre Arsonist=523 +Ogre Arsonist=500 Ogre Berserker=46 Ogre Enforcer=25 Ogre Gatecrasher=25 Ogre Geargrabber=99 Ogre Leadfoot=25 -Ogre Marauder=25 +Ogre Marauder=38 Ogre Menial=125 Ogre Recluse=25 Ogre Resister=11 Ogre Savant=25 Ogre Sentry=25 -Ogre Shaman=179 +Ogre Shaman=67 Ogre Taskmaster=26 Ogre Warrior=75 Ogre's Cleaver=25 -Ohran Viper=234 +Ohran Viper=256 Ohran Yeti=25 -Okiba-Gang Shinobi=40 +Okiba-Gang Shinobi=38 Okina Nightwatch=25 -Okina, Temple to the Grandfathers=86 +Okina, Temple to the Grandfathers=99 Okk=23 -Old Fogey=103 +Old Fogey=114 Old Ghastbark=40 -Old Man of the Sea=3012 -Olivia Voldaren=588 +Old Man of the Sea=2481 +Olivia Voldaren=344 Omega Myr=31 -Omen=110 -Omen Machine=28 +Omen=102 +Omen Machine=37 Omen of Fire=100 -Omnath, Locus of Mana=250 -Omnibian=25 +Omnath, Locus of Mana=289 +Omnibian=43 Once More with Feeling=100 -Ondu Cleric=32 -Ondu Giant=25 -One Dozen Eyes=38 -One with Nature=25 -One with Nothing=51 -One-Eyed Scarecrow=30 +Ondu Cleric=25 +Ondu Giant=16 +One Dozen Eyes=25 +One with Nature=52 +One with Nothing=169 +One-Eyed Scarecrow=34 Oni Possession=25 Oni of Wild Places=44 Onulet=46 -Onyx Goblet=31 +Onyx Goblet=36 Onyx Mage=25 Onyx Talisman=29 -Oona's Blackguard=60 +Oona's Blackguard=25 Oona's Gatewarden=25 Oona's Grace=25 -Oona's Prowler=25 -Oona, Queen of the Fae=318 -Ooze Garden=96 -Opal Acrolith=42 -Opal Archangel=114 -Opal Avenger=25 +Oona's Prowler=86 +Oona, Queen of the Fae=417 +Ooze Garden=1491 +Opal Acrolith=25 +Opal Archangel=48 +Opal Avenger=45 Opal Caryatid=16 Opal Champion=27 Opal Gargoyle=16 -Opal Guardian=25 -Opal Titan=99 -Opal-Eye, Konda's Yojimbo=175 -Opalescence=121 +Opal Guardian=38 +Opal Titan=34 +Opal-Eye, Konda's Yojimbo=190 +Opalescence=100 Opaline Bracers=25 -Opaline Sliver=25 -Open the Vaults=70 -Ophidian=40 +Opaline Sliver=39 +Open the Vaults=66 +Ophidian=38 Ophidian Eye=25 Opportunist=15 -Opportunity=50 -Opposition=92 -Oppression=10 +Opportunity=122 +Opposition=204 +Oppression=34 Oppressive Will=25 Opt=31 -Oracle en-Vec=52 -Oracle of Mul Daya=122 -Oracle of Nectars=193 -Oracle's Attendants=13 +Oracle en-Vec=83 +Oracle of Mul Daya=154 +Oracle of Nectars=211 +Oracle's Attendants=30 Oran-Rief Recluse=25 -Oran-Rief Survivalist=28 -Oran-Rief, the Vastwood=102 +Oran-Rief Survivalist=40 +Oran-Rief, the Vastwood=98 Oraxid=44 Orb of Dreams=49 Orbweaver Kumo=25 Orc General=50 Orchard Spirit=33 -Orchard Warden=28 -Orcish Artillery=69 +Orchard Warden=37 +Orcish Artillery=66 Orcish Bloodpainter=25 Orcish Cannonade=25 Orcish Cannoneers=38 Orcish Captain=24 -Orcish Conscripts=26 -Orcish Farmer=15 +Orcish Conscripts=29 +Orcish Farmer=20 Orcish Healer=33 -Orcish Librarian=30 +Orcish Librarian=36 Orcish Lumberjack=31 Orcish Mechanics=34 Orcish Mine=40 -Orcish Oriflamme=59 +Orcish Oriflamme=53 Orcish Paratroopers=28 Orcish Settlers=71 Orcish Spy=30 Orcish Squatters=47 -Orcish Veteran=25 +Orcish Veteran=100 Order of Leitbur=30 -Order of Whiteclay=49 +Order of Whiteclay=58 Order of Yawgmoth=49 -Order of the Ebon Hand=39 -Order of the Golden Cricket=31 +Order of the Ebon Hand=38 +Order of the Golden Cricket=25 Order of the Sacred Bell=25 -Order of the Sacred Torch=62 -Order of the Stars=48 -Order of the White Shield=38 +Order of the Sacred Torch=31 +Order of the Stars=26 +Order of the White Shield=35 Order/Chaos=25 Ordered Migration=25 Ordruun Commando=25 @@ -7237,232 +7397,233 @@ Organ Grinder=36 Organ Harvest=25 Orgg=54 Origin Spellbomb=25 -Orim's Chant=970 +Orim's Chant=1154 Orim's Cure=25 -Orim's Prayer=42 +Orim's Prayer=100 Orim's Thunder=25 Orim's Touch=28 -Oriss, Samite Guardian=25 -Ornate Kanzashi=31 -Ornithopter=26 +Oriss, Samite Guardian=90 +Ornate Kanzashi=63 +Ornithopter=52 Orochi Eggwatcher=25 -Orochi Hatchery=61 -Orochi Leafcaller=50 +Orochi Hatchery=38 +Orochi Leafcaller=38 Orochi Ranger=35 -Orochi Sustainer=49 -Oros, the Avenger=101 -Orzhov Basilica=41 +Orochi Sustainer=25 +Oros, the Avenger=110 +Orzhov Basilica=49 Orzhov Euthanist=25 Orzhov Guildmage=25 -Orzhov Pontiff=145 +Orzhov Pontiff=60 Orzhov Signet=25 -Orzhova, the Church of Deals=26 +Orzhova, the Church of Deals=40 Osai Vultures=27 Ostiary Thrull=25 Ostracize=22 Otarian Juggernaut=49 -Otherworldly Journey=31 -Oubliette=225 +Otherworld Atlas=37 +Otherworldly Journey=25 +Oubliette=172 Ouphe Vandals=25 Oust=38 -Outbreak=29 +Outbreak=40 Outmaneuver=25 -Outrage Shaman=40 +Outrage Shaman=25 Outrider en-Kor=25 Outrider of Jhess=25 +Outwit=36 Overabundance=57 -Overbeing of Myth=176 +Overbeing of Myth=204 Overblaze=25 -Overburden=104 +Overburden=185 Overeager Apprentice=40 -Overgrown Battlement=35 +Overgrown Battlement=16 Overgrown Estate=175 -Overgrown Tomb=1468 -Overgrowth=15 +Overgrown Tomb=1307 +Overgrowth=36 Overlaid Terrain=29 Overload=40 -Overmaster=174 +Overmaster=62 Override=24 -Overrule=31 -Overrun=27 -Oversold Cemetery=392 -Oversoul of Dusk=157 -Overtaker=32 +Overrule=38 +Overrun=36 +Oversold Cemetery=466 +Oversoul of Dusk=176 +Overtaker=50 Overwhelm=37 -Overwhelming Forces=11400 +Overwhelming Forces=10929 Overwhelming Instinct=25 -Overwhelming Intellect=25 -Overwhelming Stampede=83 -Ovinize=56 -Ovinomancer=12 -Ow=100 -Owl Familiar=65 +Overwhelming Intellect=61 +Overwhelming Stampede=97 +Ovinize=45 +Ovinomancer=10 +Ow=99 +Owl Familiar=66 Oxidda Golem=25 Oxidda Scrapmelter=45 -Oxidize=75 -Oyobi, Who Split the Heavens=75 -Pacifism=16 -Pact of Negation=1298 -Pact of the Titan=171 +Oxidize=83 +Oyobi, Who Split the Heavens=25 +Pacifism=15 +Pact of Negation=1384 +Pact of the Titan=144 Pain Kami=25 Pain Magnification=50 Pain's Reward=44 Pain/Suffering=25 Painbringer=15 Painful Memories=26 -Painful Quandary=58 +Painful Quandary=80 Painsmith=37 -Painter's Servant=451 +Painter's Servant=487 Painwracker Oni=25 Palace Guard=12 -Paladin en-Vec=111 +Paladin en-Vec=59 Paladin of Prahv=44 Pale Bears=54 Pale Moon=49 Pale Recluse=42 Pale Wayfarer=35 -Paleoloth=58 -Palinchron=359 -Palladia-Mors=368 -Palladium Myr=79 -Palliation Accord=50 +Paleoloth=74 +Palinchron=324 +Palladia-Mors=314 +Palladium Myr=85 +Palliation Accord=25 Pallid Mycoderm=25 Pallimud=35 Panacea=25 -Pandemonium=56 +Pandemonium=66 Pang Tong, Young Phoenix=699 -Panglacial Wurm=136 +Panglacial Wurm=104 Pangosaur=37 Panic=30 Panic Attack=13 -Panic Spellbomb=47 -Panoptic Mirror=301 +Panic Spellbomb=25 +Panoptic Mirror=304 Panther Warriors=16 Paper Tiger=62 Paperfin Rascal=25 -Paradigm Shift=72 -Paradise Mantle=164 -Paradise Plume=34 -Paradox Haze=96 +Paradigm Shift=64 +Paradise Mantle=176 +Paradise Plume=28 +Paradox Haze=75 Paragon of the Amesha=37 Parallax Dementia=40 Parallax Inhibitor=62 Parallax Nexus=58 -Parallax Tide=227 -Parallax Wave=82 +Parallax Tide=109 +Parallax Wave=150 Parallectric Feedback=44 -Parallel Evolution=280 -Parallel Lives=110 -Parallel Thoughts=99 -Paralyze=32 +Parallel Evolution=273 +Parallel Lives=105 +Parallel Thoughts=35 +Paralyze=31 Paralyzing Grasp=31 -Parapet=25 +Parapet=40 Parapet Watchers=25 -Paraselene=38 +Paraselene=32 Parasitic Bond=32 -Parasitic Implant=16 +Parasitic Implant=11 Parasitic Strix=44 Parch=37 Pardic Arsonist=25 Pardic Collaborator=25 -Pardic Dragon=50 +Pardic Dragon=31 Pardic Firecat=40 Pardic Lancer=28 Pardic Miner=100 Pardic Swordsmith=46 -Pariah=192 -Pariah's Shield=188 +Pariah=205 +Pariah's Shield=204 Paroxysm=25 Part Water=100 Part the Veil=31 -Past in Flames=191 +Past in Flames=100 Patagia Golem=24 Patagia Viper=25 Patchwork Gnomes=22 Path of Anger's Flame=25 Path of Peace=34 -Path to Exile=371 -Pathrazer of Ulamog=70 -Patriarch's Bidding=355 +Path to Exile=320 +Pathrazer of Ulamog=85 +Patriarch's Bidding=446 Patriarch's Desire=28 Patrician's Scorn=44 Patrol Hound=28 -Patrol Signaler=25 -Patron Wizard=410 -Patron of the Akki=25 -Patron of the Kitsune=88 +Patrol Signaler=33 +Patron Wizard=469 +Patron of the Akki=68 +Patron of the Kitsune=60 Patron of the Moon=58 Patron of the Nezumi=25 -Patron of the Orochi=25 +Patron of the Orochi=221 Patron of the Wild=37 -Pattern of Rebirth=258 +Pattern of Rebirth=263 Paupers' Cage=58 -Pavel Maliki=100 -Pawn of Ulamog=49 +Pavel Maliki=300 +Pawn of Ulamog=35 Pay No Heed=29 -Peace Strider=25 -Peace Talks=25 +Peace Strider=30 +Peace Talks=43 Peace and Quiet=40 Peace of Mind=22 -Peacekeeper=438 -Peach Garden Oath=75 -Pearl Dragon=59 -Pearl Medallion=402 +Peacekeeper=446 +Peach Garden Oath=200 +Pearl Dragon=124 +Pearl Medallion=643 Pearl Shard=25 Pearled Unicorn=35 Pearlspear Courier=25 -Peat Bog=28 +Peat Bog=31 Pedantic Learning=79 Peek=25 -Peel from Reality=25 -Peer Pressure=74 -Peer Through Depths=25 +Peer Pressure=32 +Peer Through Depths=56 Pegasus Charger=9 -Pegasus Refuge=22 +Pegasus Refuge=47 Pegasus Stampede=25 -Pegasus Token=49 -Pelakka Wurm=50 -Pemmin's Aura=58 +Pegasus Token=34 +Pelakka Wurm=38 +Pemmin's Aura=73 Penance=25 -Pendelhaven=149 +Pendelhaven=136 Pendelhaven Elder=40 Pendrell Drake=16 Pendrell Flux=32 -Pendrell Mists=147 -Pennon Blade=43 -Pentad Prism=28 -Pentagram of the Ages=48 -Pentarch Paladin=111 +Pendrell Mists=99 +Pennon Blade=25 +Pentad Prism=25 +Pentagram of the Ages=42 +Pentarch Paladin=160 Pentarch Ward=25 Pentavite Token=25 -Pentavus=26 +Pentavus=29 Penumbra Bobcat=40 Penumbra Kavu=29 Penumbra Spider=25 -Penumbra Wurm=103 -People of the Woods=36 +Penumbra Wurm=52 +People of the Woods=30 Peppersmoke=25 Peregrine Drake=31 Peregrine Griffin=47 -Peregrine Mask=50 -Perilous Forays=24 -Perilous Myr=38 +Peregrine Mask=25 +Perilous Forays=25 +Perilous Myr=25 Perilous Research=44 -Perimeter Captain=32 -Perish=152 +Perimeter Captain=25 +Perish=193 Perish the Thought=25 Permafrost Trap=50 -Pernicious Deed=1430 -Perplex=44 -Persecute=86 +Pernicious Deed=1263 +Perplex=48 +Persecute=79 Persecute Artist=27 -Personal Incarnation=193 -Personal Sanctuary=31 -Personal Tutor=1078 -Persuasion=49 -Pestermite=31 -Pestilence=30 -Pestilence Demon=45 +Personal Incarnation=171 +Personal Sanctuary=30 +Personal Tutor=2814 +Persuasion=47 +Pestermite=44 +Pestilence=29 +Pestilence Demon=67 Pestilence Rats=50 Pestilent Kathari=15 Pestilent Souleater=27 @@ -7472,102 +7633,102 @@ Petra Sphinx=99 Petradon=100 Petrahydrox=103 Petravark=43 -Petrified Field=221 +Petrified Field=231 Petrified Plating=25 Petrified Wood-Kin=29 Pewter Golem=49 -Phage the Untouchable=344 -Phantasmagorian=48 +Phage the Untouchable=332 +Phantasmagorian=28 Phantasmal Abomination=25 -Phantasmal Bear=112 -Phantasmal Dragon=46 -Phantasmal Fiend=28 -Phantasmal Forces=44 -Phantasmal Image=1056 +Phantasmal Bear=14 +Phantasmal Dragon=38 +Phantasmal Fiend=16 +Phantasmal Forces=39 +Phantasmal Image=1030 Phantasmal Mount=50 Phantasmal Sphere=49 Phantasmal Terrain=39 Phantatog=40 -Phantom Beast=41 -Phantom Centaur=29 +Phantom Beast=25 +Phantom Centaur=25 Phantom Flock=25 -Phantom Monster=39 -Phantom Nantuko=56 -Phantom Nishoba=202 +Phantom Monster=31 +Phantom Nantuko=51 +Phantom Nishoba=168 Phantom Nomad=25 Phantom Tiger=99 -Phantom Warrior=23 +Phantom Warrior=22 Phantom Whelp=28 Phantom Wings=34 Phantom Wurm=25 -Phelddagrif=157 +Phelddagrif=85 Phobian Phantasm=25 -Phosphorescent Feast=26 +Phosphorescent Feast=25 Phthisis=25 Phylactery Lich=71 Phyresis=42 -Phyrexia's Core=11 -Phyrexian Altar=391 -Phyrexian Arena=248 +Phyrexia's Core=51 +Phyrexian Altar=323 +Phyrexian Arena=297 Phyrexian Battleflies=14 Phyrexian Bloodstock=25 -Phyrexian Boon=14 +Phyrexian Boon=8 Phyrexian Broodlings=39 -Phyrexian Colossus=34 -Phyrexian Crusader=365 +Phyrexian Colossus=38 +Phyrexian Crusader=244 Phyrexian Debaser=50 Phyrexian Defiler=42 Phyrexian Delver=200 Phyrexian Denouncer=11 -Phyrexian Devourer=181 +Phyrexian Devourer=175 Phyrexian Digester=25 -Phyrexian Dreadnought=1189 +Phyrexian Dreadnought=1349 Phyrexian Driver=28 -Phyrexian Etchings=79 -Phyrexian Furnace=33 +Phyrexian Etchings=99 +Phyrexian Furnace=180 Phyrexian Gargantua=25 Phyrexian Ghoul=34 Phyrexian Gremlins=44 Phyrexian Grimoire=10 Phyrexian Hulk=10 -Phyrexian Hydra=36 +Phyrexian Hydra=39 Phyrexian Infiltrator=107 -Phyrexian Ingester=41 +Phyrexian Ingester=35 Phyrexian Ironfoot=44 Phyrexian Juggernaut=41 Phyrexian Lens=100 Phyrexian Librarian=25 Phyrexian Marauder=109 -Phyrexian Metamorph=514 -Phyrexian Monitor=28 -Phyrexian Negator=159 -Phyrexian Obliterator=1500 -Phyrexian Plaguelord=115 +Phyrexian Metamorph=576 +Phyrexian Monitor=40 +Phyrexian Negator=136 +Phyrexian Obliterator=1585 +Phyrexian Plaguelord=87 Phyrexian Portal=23 -Phyrexian Processor=230 +Phyrexian Processor=210 Phyrexian Prowler=25 Phyrexian Purge=100 Phyrexian Rager=23 Phyrexian Reaper=19 -Phyrexian Rebirth=51 -Phyrexian Reclamation=96 -Phyrexian Revoker=101 -Phyrexian Scuta=66 +Phyrexian Rebirth=65 +Phyrexian Reclamation=154 +Phyrexian Revoker=82 +Phyrexian Scuta=84 Phyrexian Slayer=38 Phyrexian Snowcrusher=25 -Phyrexian Soulgorger=62 -Phyrexian Splicer=25 -Phyrexian Swarmlord=37 +Phyrexian Soulgorger=74 +Phyrexian Splicer=41 +Phyrexian Swarmlord=28 Phyrexian Totem=25 -Phyrexian Tower=728 +Phyrexian Tower=812 Phyrexian Tribute=29 Phyrexian Tyranny=149 -Phyrexian Unlife=44 -Phyrexian Vatmother=37 +Phyrexian Unlife=58 +Phyrexian Vatmother=46 Phyrexian Vault=9 -Phyrexian Walker=69 -Phyrexian War Beast=25 -Phytohydra=122 +Phyrexian Walker=90 +Phyrexian War Beast=37 +Phytohydra=133 Pianna, Nomad Captain=26 Pierce Strider=19 Piety=113 @@ -7575,14 +7736,15 @@ Piety Charm=25 Pikemen=7 Pilgrim of Justice=28 Pilgrim of Virtue=28 -Pilgrim's Eye=38 +Pilgrim's Eye=31 Pili-Pala=38 -Pillage=25 +Pillage=37 Pillaging Horde=88 Pillar Tombs of Aku=74 -Pillar of the Paruns=222 +Pillar of Flame=84 +Pillar of the Paruns=187 Pillarfield Ox=25 -Pillory of the Sleepless=19 +Pillory of the Sleepless=25 Pincer Spider=40 Pincher Beetles=25 Pine Barrens=23 @@ -7591,106 +7753,106 @@ Pinpoint Avalanche=28 Pious Kitsune=25 Pious Warrior=28 Piper's Melody=25 -Piracy=818 -Piracy Charm=32 -Piranha Marsh=25 -Pirate Ship=104 -Piston Sledge=42 -Pistus Strike=35 -Pit Imp=25 +Piracy=744 +Piracy Charm=25 +Piranha Marsh=50 +Pirate Ship=155 +Piston Sledge=34 +Pistus Strike=34 +Pit Imp=41 Pit Keeper=40 Pit Raptor=25 Pit Scorpion=22 -Pit Spawn=30 +Pit Spawn=58 Pit Trap=27 Pitchburn Devils=33 Pitchstone Wall=43 Pitfall Trap=25 -Pith Driller=13 -Pithing Needle=117 +Pith Driller=32 +Pithing Needle=225 Pixie Queen=523 -Plagiarize=61 +Plagiarize=26 Plague Beetle=11 -Plague Boiler=25 +Plague Boiler=33 Plague Dogs=15 Plague Fiend=15 -Plague Myr=57 -Plague Rats=37 -Plague Sliver=62 -Plague Spitter=54 +Plague Myr=52 +Plague Rats=39 +Plague Sliver=26 +Plague Spitter=38 Plague Spores=16 -Plague Stinger=33 -Plague Wind=122 +Plague Stinger=62 +Plague Wind=72 Plague Witch=200 Plague of Vermin=25 -Plaguebearer=50 -Plagued Rusalka=25 -Plaguemaw Beast=35 +Plaguebearer=162 +Plagued Rusalka=35 +Plaguemaw Beast=34 Plains=5 -Planar Birth=100 -Planar Cleansing=68 -Planar Collapse=102 +Planar Birth=58 +Planar Cleansing=74 +Planar Collapse=112 Planar Despair=25 -Planar Gate=623 +Planar Gate=99 Planar Guide=25 Planar Overlay=25 -Planar Portal=241 -Planar Void=62 -Planeswalker's Favor=25 -Planeswalker's Fury=37 -Planeswalker's Mirth=37 +Planar Portal=307 +Planar Void=56 +Planeswalker's Favor=45 +Planeswalker's Fury=145 +Planeswalker's Mirth=41 Planeswalker's Mischief=99 -Planeswalker's Scorn=25 +Planeswalker's Scorn=33 Plant Elemental=25 Plasma Elemental=25 -Plateau=5580 +Plateau=5911 Plated Geopede=25 Plated Pegasus=25 Plated Rootwalla=28 -Plated Seastrider=25 -Plated Slagwurm=54 -Plated Sliver=87 +Plated Seastrider=22 +Plated Slagwurm=74 +Plated Sliver=44 Plated Spider=40 Plated Wurm=28 -Platinum Angel=197 -Platinum Emperion=208 -Plaxcaster Frogling=49 -Plaxmanta=38 +Platinum Angel=324 +Platinum Emperion=171 +Plaxcaster Frogling=25 +Plaxmanta=25 Pledge of Loyalty=25 Plover Knights=25 Plow Through Reito=25 -Plow Under=204 +Plow Under=108 Plumes of Peace=25 -Plumeveil=30 +Plumeveil=31 Plummet=25 Plunder=25 -Plunge into Darkness=142 +Plunge into Darkness=99 Pointy Finger of Doom=100 -Poison Arrow=50 +Poison Arrow=99 Poison the Well=25 Poisonbelly Ogre=25 Polar Kraken=102 -Political Trickery=25 -Pollen Lullaby=50 +Political Trickery=52 +Pollen Lullaby=25 Pollen Remedy=28 Pollenbright Wings=37 -Polluted Bonds=151 -Polluted Delta=3450 +Polluted Bonds=95 +Polluted Delta=3516 Polluted Mire=25 -Polymorph=94 -Ponder=107 -Pongify=86 -Pooling Venom=25 -Porcelain Legionnaire=35 -Porphyry Nodes=60 +Polymorph=44 +Ponder=101 +Pongify=49 +Pooling Venom=57 +Porcelain Legionnaire=34 +Porphyry Nodes=61 Port Inspector=28 -Portcullis=94 -Portent=21 +Portcullis=33 +Portent=26 Possessed Aven=49 Possessed Barbarian=57 Possessed Centaur=99 Possessed Nomad=74 -Possessed Portal=25 +Possessed Portal=47 Postmortem Lunge=46 Poultice Sliver=40 Poultrygeist=25 @@ -7699,311 +7861,315 @@ Pouncing Kavu=25 Pouncing Wurm=50 Powder Keg=169 Power Armor=40 -Power Artifact=1226 +Power Artifact=1147 Power Conduit=38 -Power Leak=38 -Power Matrix=232 +Power Leak=46 +Power Matrix=102 Power Sink=21 -Power Surge=252 +Power Surge=275 Power Taint=16 Power of Fire=25 Powerleech=56 Powerstone Minefield=79 -Pox=246 +Pox=84 Pradesh Gypsies=39 -Praetor's Counsel=79 +Praetor's Counsel=81 Praetor's Grasp=72 Prahv, Spires of Order=25 -Preacher=474 +Preacher=468 Precognition=39 -Precursor Golem=44 -Predator Dragon=97 -Predator's Strike=37 -Predator, Flagship=111 -Predatory Advantage=48 -Predatory Focus=40 +Precursor Golem=39 +Predator Dragon=104 +Predator Ooze=100 +Predator's Gambit=31 +Predator's Strike=25 +Predator, Flagship=117 +Predatory Advantage=51 +Predatory Focus=25 Predatory Hunger=52 Predatory Nightstalker=41 Predatory Urge=25 -Predict=40 -Preeminent Captain=377 -Preemptive Strike=89 +Predict=43 +Preeminent Captain=414 +Preemptive Strike=99 Preferred Selection=50 -Premature Burial=25 -Preordain=34 +Premature Burial=35 +Preordain=49 Presence of Gond=25 -Presence of the Master=57 +Presence of the Master=45 Presence of the Wise=30 Pretender's Claim=25 -Prey Upon=31 +Prey Upon=32 Prey's Vengeance=25 -Price of Glory=110 -Price of Progress=348 +Price of Glory=119 +Price of Progress=371 Prickly Boggart=40 Pride Guardian=25 -Pride of Lions=98 -Pride of the Clouds=145 -Priest of Gix=38 -Priest of Titania=239 -Priest of Urabrask=210 +Pride of Lions=47 +Pride of the Clouds=99 +Priest of Gix=79 +Priest of Titania=233 +Priest of Urabrask=54 Priest of Yawgmoth=26 Priests of Norn=46 -Primal Bellow=25 -Primal Beyond=101 +Primal Bellow=34 +Primal Beyond=86 Primal Boost=56 -Primal Clay=33 +Primal Clay=34 Primal Cocoon=25 -Primal Command=196 -Primal Forcemage=40 +Primal Command=204 +Primal Forcemage=41 Primal Frenzy=40 Primal Growth=25 -Primal Order=46 +Primal Order=77 Primal Plasma=25 -Primal Rage=29 +Primal Rage=56 +Primal Surge=117 Primal Whisperer=125 -Primalcrux=325 +Primalcrux=395 Primeval Force=87 Primeval Light=79 Primeval Shambler=25 -Primeval Titan=1659 +Primeval Titan=1279 Primitive Etchings=25 Primitive Justice=25 Primoc Escapee=25 -Primordial Hydra=332 -Primordial Ooze=17 -Primordial Sage=79 -Prince of Thralls=161 -Princess Lucrezia=94 +Primordial Hydra=280 +Primordial Ooze=22 +Primordial Sage=155 +Prince of Thralls=233 +Princess Lucrezia=79 Prismatic Boon=25 Prismatic Circle=25 Prismatic Lace=10 -Prismatic Lens=26 -Prismatic Omen=345 +Prismatic Lens=37 +Prismatic Omen=390 Prismatic Strands=25 Prismatic Ward=22 Prismatic Wardrobe=25 Prismwake Merrow=25 Prison Barricade=28 -Prison Term=58 -Pristine Angel=290 -Pristine Talisman=689 +Prison Term=41 +Pristine Angel=378 +Pristine Talisman=44 Private Research=38 -Privileged Position=743 +Privileged Position=586 Prized Unicorn=25 Probe=25 -Proclamation of Rebirth=611 -Prodigal Pyromancer=25 -Prodigal Sorcerer=28 +Proclamation of Rebirth=610 +Prodigal Pyromancer=26 +Prodigal Sorcerer=43 Profane Command=134 Profane Prayers=14 -Progenitus=1128 +Progenitus=1180 Prohibit=29 -Promise of Bunrei=167 -Promise of Power=69 +Promise of Bunrei=102 +Promise of Power=62 Promised Kannushi=25 -Propaganda=187 -Proper Burial=99 -Prophetic Bolt=48 -Prophetic Prism=25 +Propaganda=148 +Proper Burial=83 +Prophetic Bolt=49 +Prophetic Prism=40 Prosperity=47 -Protean Hulk=208 -Protean Hydra=99 +Protean Hulk=219 +Protean Hydra=75 Protective Bubble=40 Protective Sphere=10 Proteus Machine=25 -Proteus Staff=246 +Proteus Staff=112 Protomatter Powder=42 -Prototype Portal=32 -Provoke=25 -Prowess of the Fair=28 +Prototype Portal=42 +Provoke=40 +Prowess of the Fair=37 Prowling Nightstalker=49 Prowling Pangolin=25 -Psionic Blast=474 +Psionic Blast=594 Psionic Entity=91 Psionic Gift=40 -Psionic Sliver=58 -Psychatog=39 +Psionic Sliver=71 +Psychatog=29 Psychic Allergy=51 -Psychic Barrier=25 +Psychic Barrier=13 Psychic Battle=15 -Psychic Drain=50 +Psychic Drain=100 Psychic Membrane=27 Psychic Miasma=25 Psychic Network=100 Psychic Overload=25 -Psychic Possession=41 +Psychic Possession=25 Psychic Puppetry=40 -Psychic Purge=40 +Psychic Purge=36 Psychic Spear=25 -Psychic Surgery=34 -Psychic Theft=25 +Psychic Surgery=31 +Psychic Theft=34 Psychic Trance=33 Psychic Transfer=66 -Psychic Venom=23 -Psychic Vortex=51 +Psychic Venom=22 +Psychic Vortex=49 Psychogenic Probe=25 -Psychosis Crawler=35 +Psychosis Crawler=49 Psychotic Episode=25 Psychotic Fury=25 Psychotic Haze=25 -Psychotrope Thallid=85 +Psychotrope Thallid=95 Pteron Ghost=25 -Puca's Mischief=34 +Puca's Mischief=56 Puffer Extract=25 Pull Under=25 -Pull from Eternity=25 -Pulling Teeth=25 -Pulmonic Sliver=89 +Pull from Eternity=27 +Pulling Teeth=40 +Pulmonic Sliver=116 Pulsating Illusion=25 Pulse Tracker=25 Pulse of Llanowar=37 Pulse of the Dross=12 -Pulse of the Fields=39 -Pulse of the Forge=100 +Pulse of the Fields=50 +Pulse of the Forge=185 Pulse of the Grid=46 -Pulse of the Tangle=76 -Pulsemage Advocate=50 -Pulverize=99 +Pulse of the Tangle=45 +Pulsemage Advocate=47 +Pulverize=51 Punctuate=28 Puncture Blast=25 Puncture Bolt=25 Puncturing Light=25 -Punish Ignorance=52 -Punishing Fire=40 +Punish Ignorance=25 +Punishing Fire=27 Puppet Conjurer=25 Puppet Master=37 -Puppet Strings=38 +Puppet Strings=129 Puppet's Verdict=58 -Puppeteer=31 -Puppeteer Clique=154 +Puppeteer=33 +Puppeteer Clique=183 Pure Intentions=25 Pure Reflection=29 -Pure/Simple=36 -Purelace=122 +Pure/Simple=25 +Purelace=124 Puresight Merrow=25 -Puresteel Paladin=166 -Purgatory=69 +Puresteel Paladin=139 +Purgatory=99 Purge=25 Purging Scythe=41 -Purify=37 -Purify the Grave=125 -Purity=69 -Purraj of Urborg=22 -Pursuit of Knowledge=65 +Purify=39 +Purify the Grave=78 +Purity=125 +Purraj of Urborg=54 +Pursuit of Knowledge=46 Pus Kami=29 Put Away=25 Putrefaction=49 -Putrefax=36 -Putrefy=105 +Putrefax=34 +Putrefy=127 Putrid Cyclops=25 -Putrid Imp=81 +Putrid Imp=39 Putrid Leech=25 Putrid Raptor=38 -Putrid Warrior=28 +Putrid Warrior=25 Pygmy Allosaurus=55 -Pygmy Giant=32 -Pygmy Hippo=70 +Pygmy Giant=25 +Pygmy Hippo=97 Pygmy Kavu=25 Pygmy Pyrosaur=28 Pygmy Razorback=25 Pygmy Troll=52 Pyknite=16 -Pyramids=937 +Pyramids=701 Pyre Charger=25 Pyre Zombie=57 +Pyreheart Wolf=25 Pyretic Ritual=28 Pyric Salamander=28 Pyrite Spellbomb=40 -Pyroblast=66 -Pyroclasm=50 +Pyroblast=222 +Pyroclasm=38 Pyroclast Consul=25 -Pyrohemia=25 -Pyrokinesis=64 -Pyromancer Ascension=119 -Pyromancer's Swath=148 -Pyromancy=62 +Pyrohemia=100 +Pyrokinesis=92 +Pyromancer Ascension=173 +Pyromancer's Swath=52 +Pyromancy=61 Pyromania=40 Pyromatics=103 -Pyrostatic Pillar=72 -Pyrotechnics=25 +Pyrostatic Pillar=85 +Pyrotechnics=26 Pyrrhic Revival=50 Python=16 -Qasali Ambusher=31 -Qasali Pridemage=286 +Qasali Ambusher=58 +Qasali Pridemage=275 Quag Sickness=25 -Quag Vampires=46 +Quag Vampires=37 Quagmire=100 Quagmire Druid=38 Quagmire Lamprey=25 -Quagnoth=75 -Quarum Trench Gnomes=208 -Quash=15 -Quenchable Fire=15 +Quagnoth=100 +Quarum Trench Gnomes=155 +Quash=17 +Quenchable Fire=35 Quest for Ancient Secrets=25 Quest for Pure Flame=25 -Quest for Renewal=28 -Quest for Ula's Temple=49 +Quest for Renewal=25 +Quest for Ula's Temple=40 Quest for the Gemblades=25 -Quest for the Goblin Lord=46 -Quest for the Gravelord=34 -Quest for the Holy Relic=66 -Quest for the Nihil Stone=39 -Questing Phelddagrif=59 +Quest for the Goblin Lord=40 +Quest for the Gravelord=47 +Quest for the Holy Relic=50 +Quest for the Nihil Stone=94 +Questing Phelddagrif=248 Question Elemental?=25 -Quick Sliver=51 +Quick Sliver=45 Quickchange=25 -Quicken=42 +Quicken=43 Quickening Licid=25 -Quicksand=42 -Quicksilver Amulet=179 +Quicksand=45 +Quicksilver Amulet=139 Quicksilver Behemoth=42 -Quicksilver Dagger=25 -Quicksilver Dragon=162 +Quicksilver Dagger=38 +Quicksilver Dragon=74 Quicksilver Elemental=99 -Quicksilver Fountain=61 -Quicksilver Gargantuan=43 +Quicksilver Fountain=25 +Quicksilver Gargantuan=42 Quicksilver Geyser=46 Quicksilver Wall=25 Quiet Disrepair=157 Quiet Purity=40 Quiet Speculation=50 -Quietus Spike=204 +Quietus Spike=200 Quill-Slinger Boggart=25 Quilled Slagwurm=35 -Quilled Sliver=68 +Quilled Sliver=38 Quillmane Baku=25 -Quillspike=90 -Quirion Druid=45 -Quirion Dryad=84 -Quirion Elves=22 +Quillspike=81 +Quirion Druid=30 +Quirion Dryad=60 +Quirion Elves=37 Quirion Explorer=38 -Quirion Ranger=75 +Quirion Ranger=68 Quirion Sentinel=27 Quirion Trailblazer=40 Qumulox=25 -Rabble-Rouser=25 +Rabble-Rouser=37 Rabid Elephant=41 Rabid Rats=38 Rabid Wolverines=28 -Rabid Wombat=61 -Rack and Ruin=69 -Rackling=42 -Radha, Heir to Keld=117 +Rabid Wombat=57 +Rack and Ruin=39 +Rackling=50 +Radha, Heir to Keld=127 Radiant Essence=25 Radiant Kavu=38 -Radiant's Dragoons=32 -Radiant's Judgment=38 -Radiant, Archangel=282 -Radiate=127 +Radiant's Dragoons=40 +Radiant's Judgment=64 +Radiant, Archangel=287 +Radiate=38 Radjan Spirit=41 -Rafiq of the Many=346 +Rafiq of the Many=404 Rag Dealer=49 -Rag Man=41 +Rag Man=49 Ragamuffyn=25 Rage Extractor=25 Rage Forger=50 -Rage Nimbus=29 -Rage Reflection=172 +Rage Nimbus=25 +Rage Reflection=125 Rage Thrower=25 Rage Weaver=10 Ragged Veins=40 @@ -8011,83 +8177,83 @@ Raging Bull=22 Raging Cougar=67 Raging Goblin=27 Raging Gorilla=71 -Raging Kavu=50 +Raging Kavu=105 Raging Minotaur=39 -Raging Ravine=128 -Raging River=1057 +Raging Ravine=153 +Raging River=1100 Raging Spirit=28 -Ragnar=595 +Ragnar=257 Raid Bombardment=25 Raiding Nightstalker=45 Raiding Party=25 Rain of Blades=24 -Rain of Daggers=509 +Rain of Daggers=138 Rain of Embers=25 Rain of Filth=600 -Rain of Gore=25 +Rain of Gore=200 Rain of Rust=25 -Rain of Salt=10 -Rain of Tears=22 +Rain of Salt=25 +Rain of Tears=20 Rainbow Crow=25 -Rainbow Efreet=38 -Rainbow Vale=99 +Rainbow Efreet=101 +Rainbow Vale=162 Raise Dead=38 Raise the Alarm=38 Raka Disciple=599 Raka Sanctuary=40 Rakalite=99 Rakavolver=25 -Rakdos Augermage=25 -Rakdos Carnarium=135 +Rakdos Augermage=57 +Rakdos Carnarium=31 Rakdos Guildmage=25 Rakdos Ickspitter=28 -Rakdos Pit Dragon=223 -Rakdos Riteknife=48 -Rakdos Signet=27 -Rakdos the Defiler=138 +Rakdos Pit Dragon=144 +Rakdos Riteknife=25 +Rakdos Signet=100 +Rakdos the Defiler=162 Rakeclaw Gargantuan=25 -Raking Canopy=35 -Rakish Heir=38 -Rakka Mar=46 -Raksha Golden Cub=208 -Rally=14 +Raking Canopy=55 +Rakish Heir=58 +Rakka Mar=94 +Raksha Golden Cub=225 +Rally=129 Rally the Forces=25 Rally the Horde=64 -Rally the Peasants=33 -Rally the Righteous=25 -Rally the Troops=50 -Ramirez DePietro=157 -Ramosian Captain=29 -Ramosian Commander=27 +Rally the Peasants=30 +Rally the Righteous=30 +Rally the Troops=249 +Ramirez DePietro=99 +Ramosian Captain=46 +Ramosian Commander=46 Ramosian Lieutenant=28 Ramosian Rally=25 -Ramosian Revivalist=50 +Ramosian Revivalist=25 Ramosian Sergeant=100 -Ramosian Sky Marshal=25 -Rampaging Baloths=99 +Ramosian Sky Marshal=135 +Rampaging Baloths=182 Rampant Elephant=27 -Rampant Growth=19 +Rampant Growth=13 Rampart Crawler=29 -Ramses Overdark=800 -Rancid Earth=111 -Rancor=156 -Ranger en-Vec=40 -Ranger of Eos=305 -Ranger's Guile=37 +Ramses Overdark=301 +Rancid Earth=25 +Rancor=152 +Ranger en-Vec=45 +Ranger of Eos=296 +Ranger's Guile=30 Rank and File=25 Ransack=57 Rapacious One=30 Rapid Decay=41 -Rapid Fire=90 +Rapid Fire=149 Rappelling Scouts=74 Rashida Scalebane=23 Rashka the Slayer=99 -Rasputin Dreamweaver=999 -Ratcatcher=97 -Ratchet Bomb=605 +Rasputin Dreamweaver=791 +Ratcatcher=194 +Ratchet Bomb=467 Rath's Edge=99 -Rathi Assassin=60 -Rathi Dragon=130 +Rathi Assassin=76 +Rathi Dragon=124 Rathi Fiend=25 Rathi Intimidator=28 Rathi Trapper=39 @@ -8095,16 +8261,17 @@ Rats of Rath=39 Rats' Feast=41 Rattleblaze Scarecrow=49 Ravaged Highlands=25 -Ravages of War=15250 -Ravaging Horde=1644 +Ravages of War=16390 +Ravaging Horde=1399 Ravaging Riftwurm=25 Raven Familiar=31 Raven Guild Initiate=28 -Raven Guild Master=268 -Raven's Crime=25 +Raven Guild Master=243 +Raven's Crime=36 Raven's Run Dragoon=25 -Ravenous Baboons=190 -Ravenous Baloth=78 +Ravenous Baboons=78 +Ravenous Baloth=55 +Ravenous Demon=30 Ravenous Rats=30 Ravenous Skirge=28 Ravenous Trap=25 @@ -8113,11 +8280,11 @@ Raving Oni-Slave=25 Ray of Command=28 Ray of Distortion=25 Ray of Erasure=40 -Ray of Revelation=50 -Rayne, Academy Chancellor=88 +Ray of Revelation=27 +Rayne, Academy Chancellor=154 Raze=26 -Razia's Purification=34 -Razia, Boros Archangel=137 +Razia's Purification=25 +Razia, Boros Archangel=164 Razing Snidd=25 Razor Barrier=25 Razor Boomerang=42 @@ -8129,143 +8296,146 @@ Razorclaw Bear=792 Razorfield Rhino=35 Razorfield Thresher=16 Razorfin Abolisher=40 -Razorfin Hunter=25 +Razorfin Hunter=19 Razorfoot Griffin=25 Razorgrass Screen=25 Razorjaw Oni=24 -Razormane Masticore=66 +Razormane Masticore=49 Razortooth Rats=26 -Razorverge Thicket=498 +Razorverge Thicket=528 Reach Through Mists=50 Reach of Branches=75 -Read the Runes=41 +Read the Runes=25 Reality Acid=40 Reality Anchor=28 -Reality Ripple=25 +Reality Ripple=32 Reality Spasm=25 -Reality Strobe=61 +Reality Strobe=25 Reality Twist=45 -Realm Razer=100 -Realms Uncharted=31 -Reanimate=300 -Reap=25 -Reap and Sow=25 -Reaper King=300 -Reaper from the Abyss=63 +Realm Razer=25 +Realms Uncharted=28 +Reanimate=239 +Reap=7 +Reap and Sow=47 +Reaper King=285 +Reaper from the Abyss=52 Reaper of Sheoldred=25 Reaping the Graves=25 Reaping the Rewards=52 -Reassembling Skeleton=38 +Reassembling Skeleton=22 Rebel Informer=100 Rebellion of the Flamekin=35 Rebirth=25 Reborn Hero=36 Reborn Hope=37 Rebound=50 -Rebuff the Wicked=100 -Rebuild=71 -Rebuke=25 +Rebuff the Wicked=146 +Rebuild=43 +Rebuke=44 Rebuking Ceremony=62 -Recall=128 +Recall=122 Recantation=79 -Reciprocate=45 -Reckless Abandon=25 +Reciprocate=39 +Reckless Abandon=39 Reckless Assault=100 -Reckless Charge=50 +Reckless Charge=124 Reckless Embermage=49 Reckless Ogre=28 Reckless One=37 Reckless Scholar=42 Reckless Spite=27 -Reckless Waif=30 -Reckless Wurm=28 -Reclaim=27 +Reckless Waif=102 +Reckless Wurm=58 +Reclaim=24 Reclamation=61 Reclusive Wight=50 -Recoil=28 -Recollect=25 -Reconnaissance=102 -Reconstruction=26 +Recoil=38 +Recollect=23 +Reconnaissance=38 +Reconstruction=32 Recoup=40 Recover=26 Recross the Paths=25 Recumbent Bliss=38 Recuperate=16 -Recurring Insight=46 -Recurring Nightmare=729 -Recycle=111 -Red Cliffs Armada=50 -Red Elemental Blast=109 -Red Mana Battery=75 +Recurring Insight=25 +Recurring Nightmare=966 +Recycle=122 +Red Cliffs Armada=199 +Red Elemental Blast=130 +Red Mana Battery=62 Red Scarab=25 -Red Sun's Zenith=82 +Red Sun's Zenith=100 Red Ward=43 Red-Hot Hottie=25 Redeem=28 Redeem the Lost=25 -Redirect=47 +Redirect=38 Reduce to Dreams=25 Redwood Treefolk=30 Reef Pirates=33 Reef Shaman=40 -Reflect Damage=51 +Reflect Damage=99 Reflecting Mirror=34 -Reflecting Pool=676 -Reflex Sliver=28 +Reflecting Pool=626 +Reflex Sliver=37 Reflexes=10 +Reforge the Soul=238 Refraction Trap=25 Refresh=37 Refreshing Rain=41 -Regal Force=537 +Regal Force=498 Regal Unicorn=22 Regenerate=25 Regeneration=38 Regress=26 -Regrowth=332 +Regrowth=217 Reign of Chaos=25 Reign of Terror=25 -Reincarnation=183 +Reincarnation=150 Reinforced Bulwark=15 Reinforcements=25 -Reins of Power=54 -Reins of the Vinesteed=25 -Reiterate=63 +Reins of Power=41 +Reins of the Vinesteed=40 +Reiterate=134 Reito Lantern=8 -Reiver Demon=70 +Reiver Demon=87 Rejuvenate=16 Rejuvenation Chamber=43 -Reki, the History of Kamigawa=25 -Rekindled Flame=99 +Reki, the History of Kamigawa=89 +Rekindled Flame=25 Reknit=25 -Relearn=31 +Relearn=28 Release the Ants=25 -Relentless Assault=152 -Relentless Rats=128 +Relentless Assault=69 +Relentless Rats=116 +Relentless Skaabs=25 Relic Bane=25 Relic Barrier=45 -Relic Bind=28 +Relic Bind=11 Relic Crush=25 -Relic Putrescence=37 -Relic Ward=37 -Relic of Progenitus=115 +Relic Putrescence=25 +Relic Ward=46 +Relic of Progenitus=173 Reliquary Monk=29 -Reliquary Tower=277 -Remand=381 +Reliquary Tower=370 +Remand=331 Remedy=26 -Remembrance=92 -Reminisce=25 +Remembrance=128 +Reminisce=24 Remodel=28 -Remote Farm=8 +Remote Farm=25 Remote Isle=15 Remove=100 Remove Enchantments=40 -Remove Soul=43 +Remove Soul=31 Rend Flesh=25 Rend Spirit=25 Rendclaw Trow=31 Rending Vines=25 -Renegade Doppelganger=73 -Renegade Troops=154 +Renegade Demon=25 +Renegade Doppelganger=35 +Renegade Troops=258 Renegade Warlord=12 Renewal=28 Renewed Faith=31 @@ -8273,27 +8443,28 @@ Renewing Dawn=39 Renewing Touch=122 Renounce=44 Reparations=122 -Repay in Kind=75 -Repeal=34 +Repay in Kind=62 +Repeal=36 Repel=99 -Repel Intruders=25 +Repel Intruders=38 Repel the Darkness=25 Repentance=33 -Repentant Blacksmith=51 -Repentant Vampire=190 -Repercussion=208 -Replenish=722 +Repentant Blacksmith=55 +Repentant Vampire=62 +Repercussion=175 +Replenish=721 Repopulate=40 -Reprisal=34 -Reprocess=26 -Repulse=25 -Reroute=25 +Reprisal=28 +Reprocess=25 +Repulse=33 +Requiem Angel=35 +Reroute=37 Rescind=16 Rescue=20 Research the Deep=25 -Research/Development=121 -Reset=1275 -Reshape=135 +Research/Development=108 +Reset=1109 +Reshape=67 Resilient Wanderer=25 Resistance Fighter=39 Resize=41 @@ -8304,116 +8475,119 @@ Resounding Thunder=25 Resounding Wave=25 Respite=29 Resplendent Mentor=40 -Rest for the Weary=31 +Rest for the Weary=25 Restless Apparition=25 Restless Bones=25 Restless Dead=26 Restless Dreams=40 -Restock=157 -Restore Balance=204 +Restock=103 +Restoration Angel=489 +Restore Balance=25 Restrain=28 -Resurrection=53 +Resurrection=114 Resuscitate=52 -Retaliate=42 +Retaliate=49 Retaliation=29 -Retaliator Griffin=78 +Retaliator Griffin=127 Retether=75 -Rethink=8 -Retraced Image=75 +Rethink=40 +Retraced Image=145 Retract=25 Retribution=360 -Retribution of the Meek=119 +Retribution of the Meek=229 Retromancer=25 Return of the Nightstalkers=50 -Return to Battle=50 -Return to Dust=77 -Reveillark=344 +Return to Battle=99 +Return to Dust=52 +Reveillark=308 Reveille Squad=40 -Reveka, Wizard Savant=100 -Revelation=174 +Reveka, Wizard Savant=165 +Revelation=149 Revelsong Horn=25 -Revenant=18 +Revenant=241 Revenant Patriarch=25 -Reverberate=40 -Reverberation=99 +Revenge of the Hunted=86 +Reverberate=36 +Reverberation=288 Revered Dead=25 Revered Elder=28 Revered Unicorn=40 -Reverence=99 -Reverent Mantra=151 +Reverence=100 +Reverent Mantra=214 Reverent Silence=56 Reversal of Fortune=25 -Reverse Damage=181 +Reverse Damage=147 Reverse Polarity=14 Reverse the Sands=49 Revive=14 Reviving Dose=34 Reviving Vapors=102 -Revoke Existence=31 +Revoke Existence=73 Reward the Faithful=46 Rewards of Diversity=25 Reweave=25 -Rewind=30 -Reya Dawnbringer=262 -Rhox=56 -Rhox Bodyguard=25 +Rewind=26 +Reya Dawnbringer=204 +Rhox=57 +Rhox Bodyguard=34 Rhox Brute=25 Rhox Charger=25 Rhox Meditant=25 Rhox Pikemaster=24 -Rhox War Monk=42 -Rhys the Exiled=116 -Rhys the Redeemed=725 -Rhystic Cave=25 +Rhox War Monk=25 +Rhys the Exiled=100 +Rhys the Redeemed=715 +Rhystic Cave=43 Rhystic Circle=16 -Rhystic Deluge=38 +Rhystic Deluge=44 Rhystic Lightning=40 Rhystic Scrying=25 Rhystic Shield=16 -Rhystic Study=146 +Rhystic Study=127 Rhystic Syphon=9 -Rhystic Tutor=100 +Rhystic Tutor=88 Rib Cage Spider=75 -Ribbon Snake=16 +Ribbon Snake=44 Ribbons of Night=25 Ribbons of the Reikai=25 Ricochet=31 Ricochet Trap=25 Riddle of Lightning=25 Riddlesmith=25 +Riders of Gavony=77 Ridge Rannet=28 Ridged Kusite=28 Ridgeline Rager=28 Ridgetop Raptor=25 -Riding Red Hare=208 -Riding the Dilu Horse=3200 -Rift Bolt=135 -Rift Elemental=40 +Riding Red Hare=81 +Riding the Dilu Horse=2300 +Rift Bolt=95 +Rift Elemental=37 Riftmarked Knight=48 -Riftstone Portal=49 -Riftsweeper=25 -Riftwing Cloudskate=33 +Riftstone Portal=105 +Riftsweeper=40 +Riftwing Cloudskate=37 Righteous Aura=25 -Righteous Avengers=40 +Righteous Avengers=38 Righteous Cause=25 Righteous Charge=37 -Righteous Fury=468 +Righteous Fury=550 Righteous Indignation=25 -Righteous War=72 -Righteousness=110 +Righteous War=105 +Righteousness=166 Rime Dryad=25 Rime Transfusion=25 Rimebound Dead=25 Rimefeather Owl=8 Rimehorn Aurochs=25 -Rimescale Dragon=160 +Rimescale Dragon=151 Rimewind Cryomancer=25 Rimewind Taskmage=37 -Ring of Gix=52 -Ring of Immortals=404 -Ring of Ma'ruf=1577 -Ring of Renewal=56 -Rings of Brighthearth=181 +Ring of Gix=108 +Ring of Immortals=303 +Ring of Ma'ruf=1540 +Ring of Renewal=35 +Rings of Brighthearth=313 Ringskipper=25 Riot Devils=13 Riot Spikes=25 @@ -8422,94 +8596,95 @@ Riptide=799 Riptide Biologist=16 Riptide Chronologist=25 Riptide Crab=29 -Riptide Director=74 -Riptide Entrancer=52 -Riptide Laboratory=767 -Riptide Mangler=100 +Riptide Director=87 +Riptide Entrancer=58 +Riptide Laboratory=653 +Riptide Mangler=46 Riptide Pilferer=25 -Riptide Replicator=54 +Riptide Replicator=41 Riptide Shapeshifter=58 Riptide Survivor=25 -Rise from the Grave=17 -Rise of the Hobgoblins=179 -Rise/Fall=112 +Rise from the Grave=22 +Rise of the Hobgoblins=124 +Rise/Fall=200 Rishadan Airship=25 Rishadan Brigand=100 Rishadan Cutpurse=40 Rishadan Footpad=79 Rishadan Pawnshop=79 -Rishadan Port=2195 -Rising Waters=109 +Rishadan Port=2278 +Rising Waters=48 Risky Move=50 Rite of Consumption=25 -Rite of Flame=214 -Rite of Passage=130 -Rite of Replication=77 -Rites of Flourishing=31 +Rite of Flame=174 +Rite of Passage=25 +Rite of Replication=146 +Rite of Ruin=30 +Rites of Flourishing=40 Rites of Initiation=25 Rites of Refusal=31 Rites of Spring=25 Rith's Attendant=25 -Rith's Charm=31 -Rith's Grove=50 -Rith, the Awakener=414 +Rith's Charm=100 +Rith's Grove=69 +Rith, the Awakener=242 Ritual of Restoration=27 Ritual of Steel=28 -Ritual of Subdual=38 -Ritual of the Machine=163 +Ritual of Subdual=25 +Ritual of the Machine=127 Rivalry=50 Rivals' Duel=25 -Riven Turnbull=93 +Riven Turnbull=150 River Bear=44 -River Boa=25 +River Boa=51 River Delta=35 River Kaijin=49 -River Kelpie=50 +River Kelpie=25 River Merfolk=31 -River of Tears=187 +River of Tears=204 River's Grasp=25 Riverfall Mimic=41 Rix Maadi, Dungeon Palace=40 Roar of Jukai=25 -Roar of Reclamation=51 +Roar of Reclamation=25 Roar of the Crowd=25 Roar of the Kha=25 -Roar of the Wurm=68 +Roar of the Wurm=52 Roaring Slagwurm=25 Robber Fly=50 Robe of Mirrors=25 Roc Egg=52 Roc Hatchling=25 -Roc of Kher Ridges=114 +Roc of Kher Ridges=124 Rock Badger=26 Rock Basilisk=74 -Rock Hydra=199 +Rock Hydra=277 Rock Jockey=25 -Rock Lobster=115 +Rock Lobster=127 Rock Slide=25 Rockcaster Platoon=25 -Rocket Launcher=76 +Rocket Launcher=38 Rocket-Powered Turbo Slug=100 Rockshard Elemental=30 -Rockslide Ambush=50 +Rockslide Ambush=175 Rockslide Elemental=40 -Rocky Tar Pit=25 +Rocky Tar Pit=124 Rod of Ruin=43 -Rod of Spanking=65 -Rofellos's Gift=25 -Rofellos, Llanowar Emissary=1032 -Rogue Elephant=17 +Rod of Spanking=25 +Rofellos's Gift=40 +Rofellos, Llanowar Emissary=1012 +Rogue Elephant=46 Rogue Kavu=12 Rogue Skycaptain=54 -Rohgahh of Kher Keep=625 -Roil Elemental=33 -Roiling Horror=99 +Rohgahh of Kher Keep=309 +Roil Elemental=44 +Roiling Horror=25 Roiling Terrain=25 Rolling Earthquake=9999 Rolling Spoil=25 -Rolling Stones=45 -Rolling Temblor=25 -Rolling Thunder=28 +Rolling Stones=35 +Rolling Temblor=32 +Rolling Thunder=115 Ronin Cavekeeper=25 Ronin Cliffrider=54 Ronin Houndmaster=40 @@ -8518,17 +8693,17 @@ Ronom Hulk=25 Ronom Serpent=25 Ronom Unicorn=37 Roofstalker Wight=36 -Rooftop Storm=40 +Rooftop Storm=46 Root Cage=25 -Root Elemental=31 +Root Elemental=25 Root Greevil=27 -Root Maze=35 -Root Sliver=92 +Root Maze=27 +Root Sliver=104 Root Spider=99 Root-Kin Ally=29 -Rootbound Crag=278 -Rootbreaker Wurm=23 -Rootgrapple=16 +Rootbound Crag=284 +Rootbreaker Wurm=22 +Rootgrapple=41 Rooting Kavu=25 Rootrunner=25 Roots=11 @@ -8536,53 +8711,54 @@ Roots of Life=49 Rootwalla=16 Rootwater Alligator=28 Rootwater Commando=26 -Rootwater Depths=46 +Rootwater Depths=44 Rootwater Diver=25 Rootwater Hunter=62 -Rootwater Matriarch=52 +Rootwater Matriarch=40 Rootwater Mystic=28 Rootwater Shaman=23 -Rootwater Thief=153 -Rorix Bladewing=152 -Rosheen Meanderer=43 -Rot Wolf=27 +Rootwater Thief=147 +Rorix Bladewing=109 +Rosheen Meanderer=35 +Rot Wolf=32 +Rotcrown Ghoul=25 Roterothopter=30 -Rotlung Reanimator=178 +Rotlung Reanimator=160 Rotted Hystrix=16 -Rotting Fensnake=99 +Rotting Fensnake=13 Rotting Giant=25 Rotting Legion=25 Rotting Rats=44 Rough/Tumble=29 Roughshod Mentor=35 Rouse=41 -Rout=272 +Rout=329 Rowan Treefolk=36 -Rowen=55 -Royal Assassin=107 +Rowen=44 +Royal Assassin=359 Royal Decree=48 Royal Falcon=26 Royal Herbalist=40 Royal Trooper=202 -Rubinia Soulsinger=286 +Rubinia Soulsinger=103 Ruby Leech=49 -Ruby Medallion=406 -Rude Awakening=99 -Rugged Prairie=395 +Ruby Medallion=351 +Rude Awakening=54 +Rugged Prairie=463 Ruham Djinn=25 -Ruin Ghost=25 -Ruination=195 +Ruin Ghost=37 +Ruination=100 Ruinous Minotaur=102 Ruins of Trokair=23 -Rukh Egg=136 +Rukh Egg=88 Rukh Token=49 -Rule of Law=62 +Rule of Law=37 Rumbling Aftershocks=45 Rumbling Crescendo=99 -Rumbling Slum=103 +Rumbling Slum=81 Rummaging Wizard=25 Run Wild=25 -Rune Snag=95 +Rune Snag=104 Rune of Protection: Artifacts=25 Rune of Protection: Black=40 Rune of Protection: Blue=40 @@ -8591,26 +8767,26 @@ Rune of Protection: Lands=39 Rune of Protection: Red=56 Rune of Protection: White=16 Rune-Cervin Rider=25 -Rune-Scarred Demon=111 +Rune-Scarred Demon=81 Rune-Tail, Kitsune Ascendant=265 Runeboggle=35 -Runechanter's Pike=61 -Runeclaw Bear=22 +Runechanter's Pike=67 +Runeclaw Bear=37 Runed Arch=50 -Runed Halo=142 +Runed Halo=170 Runed Servitor=25 Runed Stalactite=25 Runeflare Trap=29 -Runes of the Deus=52 -Runesword=42 +Runes of the Deus=100 +Runesword=51 Runic Repetition=25 Rupture=25 -Rupture Spire=38 -Rush of Knowledge=38 +Rupture Spire=63 +Rush of Knowledge=37 Rushing River=38 Rushing-Tide Zubera=25 Rushwood Dryad=52 -Rushwood Elemental=128 +Rushwood Elemental=98 Rushwood Grove=44 Rushwood Herbalist=28 Rushwood Legate=16 @@ -8620,84 +8796,84 @@ Rust Tick=34 Rusted Relic=38 Rusted Sentinel=35 Rusted Slasher=27 -Rustic Clachan=37 -Rusting Golem=25 +Rustic Clachan=25 +Rusting Golem=42 Rustmouth Ogre=25 Rustrazor Butcher=25 Rustspore Ram=56 -Ruthless Cullblade=25 +Ruthless Cullblade=30 Ruthless Invasion=16 Rysorian Badger=50 -Ryusei, the Falling Star=200 +Ryusei, the Falling Star=182 S.N.O.T.=26 Saber Ants=56 Saberclaw Golem=12 -Sabertooth Alley Cat=25 +Sabertooth Alley Cat=32 Sabertooth Cobra=25 -Sabertooth Nishoba=149 +Sabertooth Nishoba=104 Sabretooth Tiger=27 Sacellum Archers=36 -Sacellum Godspeaker=56 +Sacellum Godspeaker=78 Sachi, Daughter of Seshiro=25 Sacred Boon=25 -Sacred Foundry=1262 -Sacred Ground=75 +Sacred Foundry=1179 +Sacred Ground=41 Sacred Guide=50 Sacred Knight=100 -Sacred Mesa=68 +Sacred Mesa=108 Sacred Nectar=26 Sacred Prey=25 Sacred Rites=28 Sacred Wolf=29 -Sacrifice=44 +Sacrifice=45 Sadistic Augermage=25 -Sadistic Glee=25 -Sadistic Hypnotist=148 -Sadistic Sacrament=40 -Safe Haven=34 -Safe Passage=9 +Sadistic Glee=79 +Sadistic Hypnotist=25 +Sadistic Sacrament=56 +Safe Haven=47 +Safe Passage=13 Safeguard=100 Safehold Duo=25 -Safehold Elite=32 +Safehold Elite=45 Safehold Sentry=25 -Safewright Quest=25 -Saffi Eriksdotter=145 +Safewright Quest=27 +Saffi Eriksdotter=135 Sage Aven=28 -Sage Owl=25 -Sage of Epityr=25 -Sage of Fables=25 +Sage Owl=234 +Sage of Epityr=43 +Sage of Fables=32 Sage of Lat-Nam=34 Sage's Dousing=25 -Sage's Knowledge=295 -Sages of the Anima=57 +Sage's Knowledge=99 +Sages of the Anima=88 Sailmonger=25 -Sakashima the Impostor=380 +Sakashima the Impostor=357 Sakiko, Mother of Summer=25 -Sakura-Tribe Elder=31 -Sakura-Tribe Scout=24 +Sakura-Tribe Elder=35 +Sakura-Tribe Scout=47 Sakura-Tribe Springcaller=20 -Salt Flats=49 -Salt Marsh=39 -Saltblast=32 -Saltcrusted Steppe=44 +Salt Flats=97 +Salt Marsh=71 +Saltblast=25 +Saltcrusted Steppe=58 Saltfield Recluse=25 Saltskitter=25 Salvage=50 -Salvage Scout=25 +Salvage Scout=34 Salvage Slasher=44 Salvage Titan=25 -Salvaging Station=88 +Salvaging Station=32 Samite Alchemist=28 Samite Archer=25 Samite Blessing=36 Samite Censer-Bearer=25 Samite Elder=25 -Samite Healer=41 +Samite Healer=39 Samite Ministration=25 Samite Pilgrim=28 Samite Sanctuary=49 Samurai Enforcers=79 -Samurai of the Pale Curtain=56 +Samurai of the Pale Curtain=25 Sanctimony=25 Sanctum Custodian=25 Sanctum Gargoyle=45 @@ -8706,11 +8882,11 @@ Sanctum Plowbeast=25 Sand Golem=29 Sand Silos=76 Sand Squid=51 -Sandals of Abdallah=189 +Sandals of Abdallah=125 Sandbar Crocodile=28 Sandbar Merfolk=16 Sandbar Serpent=32 -Sands of Time=25 +Sands of Time=102 Sandskin=35 Sandsower=25 Sandstone Deadfall=25 @@ -8720,476 +8896,483 @@ Sandstorm=25 Sandstorm Eidolon=25 Sangrite Backlash=25 Sangrite Surge=42 -Sangromancer=77 +Sangromancer=79 Sangrophage=25 -Sanguine Bond=410 +Sanguine Bond=467 Sanguine Guard=25 Sanguine Praetor=25 -Sanity Gnawers=25 -Sanity Grinding=251 -Sapling of Colfenor=167 +Sanity Gnawers=37 +Sanity Grinding=198 +Sapling of Colfenor=90 Sapphire Charm=25 Sapphire Leech=100 -Sapphire Medallion=508 -Saprazzan Bailiff=54 +Sapphire Medallion=526 +Saprazzan Bailiff=25 Saprazzan Breaker=25 Saprazzan Cove=29 -Saprazzan Heir=157 +Saprazzan Heir=77 Saprazzan Legate=25 Saprazzan Outrigger=28 Saprazzan Raider=28 Saprazzan Skerry=25 -Saproling Burst=187 -Saproling Cluster=41 +Saproling Burst=44 +Saproling Cluster=25 Saproling Infestation=599 -Saproling Symbiosis=322 -Saproling Token=10 -Sapseep Forest=25 +Saproling Symbiosis=259 +Saproling Token=17 +Sapseep Forest=52 Sarcatog=28 -Sarcomancy=209 +Sarcomancy=280 Sarcomite Myr=25 -Sarkhan Vol=968 -Sarkhan the Mad=478 -Sarpadian Empires, Vol. VII=81 -Sasaya, Orochi Ascendant=26 +Sarkhan Vol=1160 +Sarkhan the Mad=433 +Sarpadian Empires, Vol. VII=25 +Sasaya, Orochi Ascendant=100 Saute=28 Savaen Elves=31 -Savage Beating=135 +Savage Beating=48 Savage Conception=25 Savage Firecat=50 Savage Gorilla=599 Savage Hunger=25 -Savage Lands=113 +Savage Lands=154 Savage Offensive=25 Savage Silhouette=11 -Savage Thallid=25 +Savage Thallid=37 Savage Twister=25 -Savannah=8382 -Savannah Lions=313 +Savannah=7569 +Savannah Lions=446 Save Life=25 -Savor the Moment=160 -Savra, Queen of the Golgari=100 +Saving Grasp=25 +Savor the Moment=61 +Savra, Queen of the Golgari=83 Sawback Manticore=100 Sawtooth Loon=12 Sawtooth Ogre=28 Sawtooth Thresher=19 -Scab-Clan Mauler=40 +Scab-Clan Mauler=31 Scabland=23 Scald=12 Scalding Salamander=40 -Scalding Tarn=1170 +Scalding Tarn=1204 Scalding Tongs=50 Scale of Chiss-Goria=25 Scalebane's Elite=38 Scaled Hulk=25 Scaled Wurm=23 -Scalpelexis=50 +Scalpelexis=36 Scandalmonger=25 Scapegoat=50 -Scapeshift=203 -Scar=75 +Scapeshift=81 +Scar=25 Scarab of the Unseen=18 Scarblade Elite=25 Scare Tactics=52 -Scarecrone=203 +Scarecrone=193 Scarecrow=31 Scarland Thrinax=25 Scarred Puma=28 Scarred Vinebreeder=25 -Scars of the Veteran=31 +Scars of the Veteran=25 Scarscale Ritual=49 Scarwood Bandits=147 Scarwood Goblins=25 -Scarwood Hag=32 +Scarwood Hag=30 Scarwood Treefolk=25 Scathe Zombies=33 Scatter the Seeds=99 Scattering Stroke=25 Scattershot=129 -Scattershot Archer=47 +Scattershot Archer=42 Scavenged Weaponry=28 -Scavenger Drake=31 +Scavenger Drake=37 Scavenger Folk=27 -Scavenging Ghoul=61 +Scavenging Ghoul=66 Scavenging Scarab=25 Scent of Brine=38 -Scent of Cinder=549 -Scent of Ivy=40 -Scent of Jasmine=38 +Scent of Cinder=45 +Scent of Ivy=99 +Scent of Jasmine=40 Scent of Nightshade=39 -Scepter of Dominance=28 -Scepter of Empires=40 -Scepter of Fugue=50 -Scepter of Insight=100 +Scepter of Dominance=51 +Scepter of Empires=85 +Scepter of Fugue=76 +Scepter of Insight=86 Schismotivate=25 School of Piranha=28 School of the Unseen=25 -Scion of Darkness=179 -Scion of Oona=330 -Scion of the Ur-Dragon=184 -Scion of the Wild=25 +Scion of Darkness=245 +Scion of Oona=346 +Scion of the Ur-Dragon=171 +Scion of the Wild=48 Scissors Lizard=62 Scorched Earth=25 -Scorched Ruins=227 -Scorched Rusalka=25 +Scorched Ruins=207 +Scorched Rusalka=30 Scorching Lava=28 Scorching Missile=28 Scorching Spear=13 Scorching Winds=56 Scoria Cat=25 Scoria Elemental=25 -Scoria Wurm=65 +Scoria Wurm=53 +Scorned Villager=57 Scornful AEther-Lich=25 Scornful Egotist=102 -Scour=38 -Scourge Devil=25 +Scour=30 +Scourge Devil=31 Scourge Servant=25 -Scourge of Geier Reach=21 -Scourge of Kher Ridges=249 +Scourge of Geier Reach=33 +Scourge of Kher Ridges=105 Scourge of Numai=25 -Scourge of the Nobilis=32 -Scourglass=95 -Scout's Warning=99 -Scouting Trek=12 +Scourge of the Nobilis=36 +Scourglass=122 +Scout's Warning=25 +Scouting Trek=25 Scrabbling Claws=25 -Scragnoth=43 +Scragnoth=54 Scrambleverse=25 -Scrap=40 +Scrap=71 Scrapbasket=25 Scrapdiver Serpent=25 -Scrapheap=62 +Scrapheap=43 Scrapyard Salvo=25 Screaming Fury=25 Screaming Seahawk=28 Screams from Within=31 Screams of the Damned=25 -Screeching Bat=37 +Screeching Bat=32 Screeching Buzzard=35 Screeching Drake=27 Screeching Griffin=25 Screeching Harpy=25 -Screeching Silcaw=25 -Screeching Sliver=29 +Screeching Silcaw=28 +Screeching Skaab=29 +Screeching Sliver=25 Scrib Nibblers=43 Scrivener=25 -Scroll Rack=839 +Scroll Rack=1125 Scroll Thief=25 -Scroll of Origins=31 +Scroll of Origins=100 Scrounge=25 -Scrubland=6738 -Scryb Ranger=45 -Scryb Sprites=41 +Scrubland=6466 +Scryb Ranger=67 +Scryb Sprites=40 Scrying Glass=29 -Scrying Sheets=245 -Sculpting Steel=212 -Scute Mob=55 -Scuttlemutt=58 +Scrying Sheets=139 +Sculpting Steel=151 +Scute Mob=86 +Scuttlemutt=105 Scuttling Death=25 -Scuzzback Marauders=40 +Scuzzback Marauders=38 Scuzzback Scrapper=40 Scythe Tiger=47 Scythe of the Wretched=25 -Sea Drake=1274 +Sea Drake=1141 Sea Eagle=41 -Sea Gate Loremaster=22 +Sea Gate Loremaster=38 Sea Gate Oracle=25 Sea Kings' Blessing=100 Sea Monster=27 -Sea Scryer=36 -Sea Serpent=26 +Sea Scryer=31 +Sea Serpent=22 Sea Snidd=28 Sea Spirit=14 Sea Sprite=24 Sea Troll=25 Sea's Claim=26 -Seachrome Coast=1364 -Seafarer's Quay=100 +Seachrome Coast=1070 +Seafarer's Quay=150 Seafloor Debris=25 -Seahunter=81 +Seahunter=41 Seal of Cleansing=40 Seal of Doom=25 -Seal of Fire=30 +Seal of Fire=26 Seal of Primordium=31 Seal of Removal=25 -Seal of Strength=31 +Seal of Strength=58 Sealed Fate=25 -Search for Survivors=169 -Search for Tomorrow=15 -Searing Blaze=58 +Seance=41 +Search for Survivors=40 +Search for Tomorrow=34 +Searing Blaze=48 Searing Flesh=40 -Searing Meditation=46 +Searing Meditation=62 Searing Rays=599 Searing Spear Askari=16 Searing Touch=25 -Searing Wind=35 +Searing Wind=52 Seascape Aerialist=25 -Seashell Cameo=29 -Seaside Citadel=97 +Seashell Cameo=31 +Seaside Citadel=136 Seaside Haven=29 -Seasinger=32 -Season of the Witch=155 +Seasinger=31 +Season of the Witch=88 Seasoned Marshal=34 Seasoned Tactician=16 -Seat of the Synod=107 -Secluded Glen=92 -Secluded Steppe=31 -Second Chance=58 +Seat of the Synod=101 +Secluded Glen=126 +Secluded Steppe=36 +Second Chance=49 Second Sight=25 -Second Sunrise=152 +Second Sunrise=144 Second Thoughts=25 Second Wind=25 Secretkeeper=25 +Secrets of the Dead=30 Security Detail=100 -Sedge Sliver=300 -Sedge Troll=246 +Sedge Sliver=148 +Sedge Troll=271 Sedraxis Alchemist=15 -Sedraxis Specter=60 -Sedris, the Traitor King=135 +Sedraxis Specter=48 +Sedris, the Traitor King=157 See Beyond=35 -Seed Spark=31 +Seed Spark=25 Seed the Land=36 -Seedborn Muse=314 +Seedborn Muse=292 Seedcradle Witch=35 -Seedguide Ash=25 -Seedling Charm=38 -Seeds of Innocence=100 +Seedguide Ash=55 +Seedling Charm=36 +Seeds of Innocence=49 Seeds of Strength=99 -Seedtime=51 -Seek the Horizon=40 -Seeker=132 -Seeker of Skybreak=22 -Seer's Sundial=48 +Seedtime=37 +Seek the Horizon=52 +Seeker=194 +Seeker of Skybreak=47 +Seer's Sundial=67 Seer's Vision=50 Seething Anger=29 Seething Pathblazer=29 Seething Song=103 Segmented Wurm=27 Segovian Leviathan=55 -Seht's Tiger=11 -Seismic Assault=96 +Seht's Tiger=56 +Seismic Assault=94 Seismic Mage=100 Seismic Shudder=25 -Seismic Spike=31 +Seismic Spike=35 Seismic Strike=25 -Seizan, Perverter of Truth=131 -Seize the Day=25 +Seizan, Perverter of Truth=60 +Seize the Day=150 Seize the Initiative=35 -Seize the Soul=28 +Seize the Soul=169 Seizures=99 Sejiri Merfolk=25 -Sejiri Refuge=50 +Sejiri Refuge=41 Sejiri Steppe=25 -Sek'Kuar, Deathkeeper=88 -Sekki, Seasons' Guide=160 -Selective Memory=19 -Selenia, Dark Angel=172 -Selesnya Evangel=40 +Sek'Kuar, Deathkeeper=134 +Sekki, Seasons' Guide=144 +Selective Memory=25 +Selenia, Dark Angel=185 +Selesnya Evangel=25 Selesnya Guildmage=36 -Selesnya Sagittars=40 -Selesnya Sanctuary=25 -Selesnya Signet=25 -Selfless Cathar=25 +Selesnya Sagittars=25 +Selesnya Sanctuary=40 +Selesnya Signet=31 +Selfless Cathar=32 Selfless Exorcist=12 -Selhoff Occultist=34 +Selhoff Occultist=32 Selkie Hedge-Mage=25 Sell-Sword Brute=25 -Semblance Anvil=48 -Sen Triplets=480 -Sengir Autocrat=14 +Semblance Anvil=44 +Sen Triplets=510 +Sengir Autocrat=31 Sengir Bats=30 -Sengir Nosferatu=61 -Sengir Vampire=89 -Sensation Gorger=25 -Sensei Golden-Tail=102 -Sensei's Divining Top=1061 -Sensor Splicer=25 -Sensory Deprivation=12 +Sengir Nosferatu=25 +Sengir Vampire=47 +Sensation Gorger=99 +Sensei Golden-Tail=100 +Sensei's Divining Top=1139 +Sensor Splicer=34 +Sensory Deprivation=32 Sentinel=141 Sentinels of Glen Elendra=121 Sentry Oak=25 Septic Rats=31 -Seraph=128 -Serendib Djinn=1729 -Serendib Efreet=228 -Serendib Sorcerer=74 +Seraph=127 +Seraph Sanctuary=31 +Seraph of Dawn=26 +Serendib Djinn=895 +Serendib Efreet=260 +Serendib Sorcerer=49 Serene Heart=28 -Serene Offering=25 +Serene Offering=22 Serene Sunset=12 -Serenity=156 +Serenity=141 Serpent Assassin=99 -Serpent Generator=219 +Serpent Generator=211 Serpent Skin=40 Serpent Warrior=30 Serpent of the Endless Sea=25 Serpentine Basilisk=42 Serpentine Kavu=25 -Serra Advocate=28 -Serra Angel=53 -Serra Ascendant=302 -Serra Avatar=652 +Serra Advocate=26 +Serra Angel=256 +Serra Ascendant=265 +Serra Avatar=645 Serra Avenger=498 Serra Aviary=68 Serra Bestiary=26 Serra Inquisitors=40 Serra Paladin=30 -Serra Sphinx=38 -Serra Zealot=16 -Serra's Blessing=50 +Serra Sphinx=69 +Serra Zealot=40 +Serra's Blessing=29 Serra's Boon=25 -Serra's Embrace=26 -Serra's Hymn=42 +Serra's Embrace=27 +Serra's Hymn=50 Serra's Liturgy=50 -Serra's Sanctum=1259 +Serra's Sanctum=1244 Serrated Arrows=22 -Serrated Biskelion=38 -Serum Powder=153 +Serrated Biskelion=40 +Serum Powder=62 Serum Raker=25 Serum Tank=12 -Serum Visions=34 +Serum Visions=37 Servant of Volrath=28 -Seshiro the Anointed=112 +Seshiro the Anointed=45 Seton's Desire=28 Seton's Scout=40 -Seton, Krosan Protector=74 +Seton, Krosan Protector=50 Sever Soul=13 -Sever the Bloodline=32 +Sever the Bloodline=35 Severed Legion=25 Sewer Rats=14 Sewerdreg=25 -Sewers of Estark=150 -Sewn-Eye Drake=25 -Sex Appeal=33 -Shackles=34 +Sewers of Estark=89 +Sewn-Eye Drake=35 +Sex Appeal=41 +Shackles=282 Shade of Trokair=28 Shade's Breath=25 Shade's Form=38 Shadow Guildmage=29 -Shadow Lance=40 +Shadow Lance=25 Shadow Rider=28 -Shadow Rift=39 -Shadow Sliver=25 +Shadow Rift=54 +Shadow Sliver=37 Shadow of Doubt=125 Shadowbane=35 Shadowblood Egg=40 -Shadowblood Ridge=206 +Shadowblood Ridge=299 Shadowfeed=25 -Shadowmage Infiltrator=162 +Shadowmage Infiltrator=169 Shadowstorm=10 Shah of Naar Isle=85 -Shahrazad=5295 +Shahrazad=4066 Shaleskin Bruiser=20 Shaleskin Plower=11 -Shallow Grave=141 -Shaman en-Kor=146 +Shallow Grave=218 +Shaman en-Kor=91 Shaman's Trance=25 Shambling Remains=40 -Shambling Shell=16 +Shambling Shell=41 Shambling Strider=11 Shambling Swarm=46 -Shanodin Dryads=23 -Shape Anew=56 -Shape Stealer=25 -Shape of the Wiitigo=79 +Shanodin Dryads=29 +Shape Anew=54 +Shape Stealer=30 +Shape of the Wiitigo=66 Shaper Guildmage=40 Shaper Parasite=28 -Shapesharer=114 +Shapesharer=56 Shapeshifter=34 Shapeshifter's Marrow=99 -Shard Convergence=36 +Shard Convergence=25 Shard Phoenix=27 -Shard Volley=37 -Sharding Sphinx=65 +Shard Volley=31 +Sharding Sphinx=75 Shared Animosity=41 Shared Discovery=25 -Shared Fate=37 -Shared Triumph=98 +Shared Fate=102 +Shared Triumph=105 Sharpened Pitchfork=25 -Sharuum the Hegemon=208 +Sharuum the Hegemon=201 Shatter=17 -Shattered Angel=29 +Shattered Angel=25 Shattered Crypt=40 Shattered Dreams=25 Shattering Pulse=50 -Shattering Spree=195 +Shattering Spree=211 Shatterskull Giant=25 -Shatterstorm=31 +Shatterstorm=43 Shauku's Minion=25 -Shauku, Endbringer=79 -Sheep Token=349 +Shauku, Endbringer=199 +Sheep Token=270 Shelkin Brownie=25 Shell Skulkin=25 -Shell of the Last Kappa=50 -Shelldock Isle=56 +Shell of the Last Kappa=25 +Shelldock Isle=52 Shelter=10 -Sheltered Valley=147 +Sheltered Valley=37 Sheltering Ancient=25 Sheltering Prayers=99 -Sheoldred, Whispering One=326 -Shepherd of Rot=51 -Shepherd of the Lost=42 +Sheoldred, Whispering One=325 +Shepherd of Rot=40 +Shepherd of the Lost=50 Shield Bearer=28 Shield Dancer=40 Shield Mate=52 -Shield Sphere=70 -Shield Wall=25 +Shield Sphere=74 +Shield Wall=23 Shield of Duty and Reason=25 -Shield of Kaldra=88 +Shield of Kaldra=77 Shield of the Ages=11 -Shield of the Oversoul=126 -Shield of the Righteous=50 -Shielding Plax=39 +Shield of the Oversoul=94 +Shield of the Righteous=25 +Shielding Plax=37 Shieldmage Advocate=28 Shieldmage Elder=25 Shieldmate's Blessing=102 -Shields of Velis Vel=26 +Shields of Velis Vel=25 Shifting Borders=25 -Shifting Sky=44 -Shifting Sliver=80 -Shifting Wall=29 -Shifty Doppelganger=58 -Shimatsu the Bloodcloaked=25 +Shifting Sky=43 +Shifting Sliver=68 +Shifting Wall=50 +Shifty Doppelganger=36 +Shimatsu the Bloodcloaked=100 Shimian Night Stalker=40 -Shimian Specter=125 +Shimian Specter=99 Shimmer=99 -Shimmer Myr=38 +Shimmer Myr=51 Shimmering Barrier=46 Shimmering Efreet=10 Shimmering Glasskite=49 -Shimmering Grotto=37 +Shimmering Grotto=33 Shimmering Mirage=25 Shimmering Wings=25 Shinen of Fear's Chill=25 Shinen of Flight's Wings=25 Shinen of Fury's Fire=25 -Shinen of Life's Roar=28 +Shinen of Life's Roar=25 Shinen of Stars' Light=25 -Shinewend=25 -Shining Shoal=62 +Shinewend=42 +Shining Shoal=44 Shinka Gatekeeper=25 -Shinka, the Bloodsoaked Keep=32 -Shirei, Shizo's Caretaker=134 +Shinka, the Bloodsoaked Keep=109 +Shirei, Shizo's Caretaker=105 Shisato, Whispering Hunter=25 Shiv's Embrace=31 -Shivan Dragon=553 +Shivan Dragon=511 Shivan Emissary=25 -Shivan Gorge=58 -Shivan Harvest=54 -Shivan Hellkite=65 +Shivan Gorge=74 +Shivan Harvest=58 +Shivan Hellkite=38 Shivan Meteor=38 Shivan Oasis=10 -Shivan Phoenix=55 +Shivan Phoenix=69 Shivan Raptor=27 -Shivan Reef=260 +Shivan Reef=220 Shivan Sand-Mage=25 -Shivan Wumpus=80 -Shivan Wurm=116 +Shivan Wumpus=58 +Shivan Wurm=77 Shivan Zombie=7 -Shizo, Death's Storehouse=221 +Shizo, Death's Storehouse=338 Shizuko, Caller of Autumn=16 Shoal Serpent=28 Shock=26 Shock Troops=27 -Shocker=108 +Shocker=100 Shoe Tree=28 Shore Snapper=25 Shorecrasher Mimic=39 @@ -9197,37 +9380,37 @@ Shoreline Raider=28 Shoreline Ranger=29 Shoreline Salvager=25 Shoving Match=25 -Show and Tell=3156 +Show and Tell=3291 Shower of Coals=40 Shower of Sparks=40 -Shrapnel Blast=96 -Shred Memory=25 +Shrapnel Blast=69 +Shred Memory=35 Shrewd Hatchling=48 Shriek Raptor=16 Shriek of Dread=28 Shriekhorn=11 Shrieking Drake=25 Shrieking Grotesque=25 -Shrieking Mogg=43 -Shrieking Specter=149 -Shriekmaw=57 -Shrine of Boundless Growth=46 -Shrine of Burning Rage=141 -Shrine of Limitless Power=40 -Shrine of Loyal Legions=39 +Shrieking Mogg=99 +Shrieking Specter=127 +Shriekmaw=128 +Shrine of Boundless Growth=38 +Shrine of Burning Rage=166 +Shrine of Limitless Power=46 +Shrine of Loyal Legions=54 Shrine of Piercing Vision=46 Shrink=30 Shrivel=25 Shriveling Rot=52 Shrouded Lore=25 -Shrouded Serpent=99 -Shu Cavalry=50 -Shu Defender=50 -Shu Elite Companions=99 +Shrouded Serpent=46 +Shu Cavalry=44 +Shu Defender=49 +Shu Elite Companions=44 Shu Elite Infantry=50 -Shu Farmer=50 -Shu General=50 -Shu Grain Caravan=25 +Shu Farmer=58 +Shu General=44 +Shu Grain Caravan=58 Shu Soldier-Farmers=386 Shuko=25 Shunt=25 @@ -9237,230 +9420,235 @@ Sibilant Spirit=119 Sick and Tired=28 Sicken=111 Sickening Dreams=25 -Sickening Shoal=35 +Sickening Shoal=90 Sickle Ripper=25 Sickleslicer=37 -Sidar Jabari=100 +Sidar Jabari=49 Side to Side=25 Sideswipe=25 -Sidewinder Sliver=47 +Sidewinder Sliver=25 Siege Mastodon=8 Siege Wurm=36 Siege of Towers=25 -Siege-Gang Commander=112 +Siege-Gang Commander=113 Sift=32 -Sift Through Sands=40 +Sift Through Sands=25 +Sigarda, Host of Herons=1188 Sighted-Caste Sorcerer=25 Sigil Blessing=25 -Sigil Captain=29 +Sigil Captain=27 Sigil Tracer=70 -Sigil of Distinction=110 -Sigil of Sleep=38 -Sigil of the Empty Throne=154 +Sigil of Distinction=35 +Sigil of Sleep=69 +Sigil of the Empty Throne=165 Sigil of the Nayan Gods=25 -Sigil of the New Dawn=69 +Sigil of the New Dawn=54 Sigiled Behemoth=50 -Sigiled Paladin=33 -Sign in Blood=32 -Signal Pest=65 -Silence=68 -Silent Arbiter=206 -Silent Assassin=12 +Sigiled Paladin=42 +Sign in Blood=42 +Signal Pest=61 +Silence=90 +Silent Arbiter=251 +Silent Assassin=51 Silent Attendant=25 -Silent Departure=25 -Silent Specter=90 -Silent-Chant Zubera=25 -Silhana Ledgewalker=27 +Silent Departure=30 +Silent Specter=98 +Silent-Chant Zubera=37 +Silhana Ledgewalker=25 Silhana Starfletcher=25 -Silhouette=100 +Silhouette=89 Silk Net=28 Silkbind Faerie=41 Silkenfist Fighter=28 Silkenfist Order=25 -Silklash Spider=113 +Silklash Spider=86 Silkwing Scout=25 Silt Crawler=28 Silver Drake=38 Silver Erne=25 -Silver Knight=40 +Silver Knight=36 Silver Myr=28 -Silver Seraph=58 -Silver-Inlaid Dagger=57 +Silver Seraph=116 +Silver-Inlaid Dagger=37 Silverback Ape=109 +Silverblade Paladin=400 Silverchase Fox=25 -Silvercoat Lion=7 -Silvergill Adept=80 -Silvergill Douser=25 +Silvercoat Lion=16 +Silvergill Adept=130 +Silvergill Douser=45 Silverglade Elemental=27 Silverglade Pathfinder=157 -Silverskin Armor=38 -Silverstorm Samurai=40 -Silvos, Rogue Elemental=188 +Silverskin Armor=32 +Silverstorm Samurai=38 +Silvos, Rogue Elemental=181 Sima Yi, Wei Field Marshal=599 Simian Brawler=25 Simian Grunts=39 -Simian Spirit Guide=63 +Simian Spirit Guide=45 Simic Basilisk=25 -Simic Growth Chamber=37 -Simic Guildmage=31 +Simic Growth Chamber=73 +Simic Guildmage=25 Simic Initiate=25 Simic Ragworm=58 -Simic Signet=31 -Simic Sky Swallower=151 +Simic Signet=36 +Simic Sky Swallower=155 Simoon=25 Simplify=25 -Simulacrum=179 -Sindbad=73 -Sinew Sliver=96 +Simulacrum=183 +Sindbad=63 +Sinew Sliver=43 Singe=28 Singe-Mind Ogre=50 -Singing Tree=787 +Singing Tree=680 Sinister Strength=25 Sink into Takenuma=25 -Sinkhole=2940 +Sinkhole=2209 Sinking Feeling=25 -Sins of the Past=43 +Sins of the Past=37 Sinstriker's Will=25 Sir Shandlar of Eberyn=100 Sire of the Storm=40 -Siren's Call=43 +Siren's Call=39 Sirocco=180 Sisay's Ingenuity=25 Sisay's Ring=25 -Sisters of Stone Death=327 +Sisters of Stone Death=108 Sisters of the Flame=35 -Sivitri Scarzam=89 +Sivitri Scarzam=108 Sivvi's Ruse=25 Sivvi's Valor=110 Six-y Beast=25 -Sizzle=27 -Skaab Goliath=9 -Skaab Ruinator=152 -Skarrg, the Rage Pits=25 -Skarrgan Firebird=49 -Skarrgan Pit-Skulk=25 +Sizzle=25 +Skaab Goliath=44 +Skaab Ruinator=96 +Skarrg, the Rage Pits=35 +Skarrgan Firebird=30 +Skarrgan Pit-Skulk=39 Skarrgan Skybreaker=25 Skeletal Changeling=40 Skeletal Crocodile=43 Skeletal Grimace=16 Skeletal Kathari=25 -Skeletal Scrying=64 +Skeletal Scrying=34 Skeletal Snake=115 -Skeletal Vampire=129 -Skeletal Wurm=33 +Skeletal Vampire=114 +Skeletal Wurm=25 Skeleton Scavengers=25 Skeleton Shard=25 -Skeleton Ship=158 +Skeleton Ship=160 Skeletonize=47 -Skill Borrower=38 -Skinrender=31 -Skinshifter=94 +Skill Borrower=62 +Skinrender=110 +Skinshifter=61 Skinthinner=25 -Skinwing=25 -Skirge Familiar=46 +Skinwing=34 +Skirge Familiar=74 Skirk Alarmist=79 Skirk Commando=28 Skirk Drill Sergeant=25 Skirk Fire Marshal=99 Skirk Marauder=26 Skirk Outrider=20 -Skirk Prospector=25 -Skirk Ridge Exhumer=32 +Skirk Prospector=17 +Skirk Ridge Exhumer=50 Skirk Shaman=15 Skirk Volcanist=25 Skirsdag Cultist=16 -Skirsdag High Priest=73 -Skithiryx, the Blight Dragon=530 +Skirsdag Flayer=25 +Skirsdag High Priest=47 +Skithiryx, the Blight Dragon=363 Skitter of Lizards=50 Skittering Horror=25 -Skittering Invasion=31 +Skittering Invasion=25 Skittering Monstrosity=25 Skittering Skirge=29 Skittish Kavu=25 Skittish Valesk=25 -Skizzik=142 +Skizzik=87 Skizzik Surger=25 Skred=31 Skulking Fugitive=25 Skulking Ghost=40 Skulking Knight=25 -Skull Catapult=72 +Skull Catapult=13 Skull Collector=36 Skull Fracture=25 -Skull of Orm=84 -Skull of Ramos=32 +Skull of Orm=31 +Skull of Ramos=38 Skullcage=25 -Skullclamp=181 +Skullclamp=175 Skullmane Baku=25 -Skullmead Cauldron=31 -Skullmulcher=25 -Skullscorch=50 -Skullsnatcher=40 +Skullmead Cauldron=25 +Skullmulcher=52 +Skullscorch=85 +Skullsnatcher=38 Skulltap=25 Sky Diamond=14 Sky Hussar=25 Sky Ruin Drake=45 -Sky Spirit=25 -Sky Swallower=95 +Sky Spirit=38 +Sky Swallower=25 Sky Weaver=25 Sky-Eel School=25 Skyclaw Thrash=25 Skycloud Egg=40 -Skycloud Expanse=167 -Skyfire Kirin=62 +Skycloud Expanse=232 +Skyfire Kirin=100 Skyhunter Cub=25 Skyhunter Patrol=25 Skyhunter Prowler=25 Skyhunter Skirmisher=12 -Skyknight Legionnaire=28 +Skyknight Legionnaire=35 Skyreach Manta=25 Skyrider Trainee=25 Skyscribing=40 Skyshaper=52 -Skyship Weatherlight=52 +Skyship Weatherlight=91 Skyshooter=25 Skyshroud Archer=25 Skyshroud Behemoth=47 Skyshroud Blessing=25 -Skyshroud Claim=46 +Skyshroud Claim=44 Skyshroud Condor=25 Skyshroud Cutter=47 -Skyshroud Elf=24 -Skyshroud Elite=75 -Skyshroud Falcon=26 +Skyshroud Elf=41 +Skyshroud Elite=31 +Skyshroud Falcon=37 Skyshroud Forest=125 -Skyshroud Poacher=126 -Skyshroud Ranger=22 +Skyshroud Poacher=69 +Skyshroud Ranger=40 Skyshroud Ridgeback=25 Skyshroud Sentinel=25 -Skyshroud Troll=28 +Skyshroud Troll=40 Skyshroud Troopers=25 -Skyshroud Vampire=40 +Skyshroud Vampire=38 Skyshroud War Beast=99 Skyward Eye Prophets=25 Skywatcher Adept=52 +Skywinder Drake=25 Skywing Aven=25 -Slag Fiend=35 -Slagstorm=431 +Slag Fiend=26 +Slagstorm=309 Slagwurm Armor=25 Slash Panther=16 Slashing Tiger=704 -Slate of Ancestry=119 +Slate of Ancestry=108 Slaughter=73 Slaughter Cry=15 -Slaughter Pact=246 +Slaughter Pact=231 Slaughterhouse Bouncer=25 -Slave of Bolas=40 -Slavering Nulls=37 -Slay=28 +Slave of Bolas=33 +Slavering Nulls=25 +Slay=38 Slayer of the Wicked=13 +Slayers' Stronghold=177 Sleep=25 -Sleeper Agent=24 +Sleeper Agent=56 Sleeper's Guile=25 -Sleeper's Robe=34 +Sleeper's Robe=29 Sleeping Potion=28 -Sleight of Hand=69 -Sleight of Mind=114 +Sleight of Hand=98 +Sleight of Mind=92 Slice and Dice=50 Slice in Twain=25 Slimy Kavu=102 @@ -9473,57 +9661,57 @@ Slippery Bogle=40 Slippery Karst=16 Slipstream Eel=25 Slipstream Serpent=25 -Sliptide Serpent=99 +Sliptide Serpent=45 Slith Ascendant=40 Slith Bloodletter=25 -Slith Firewalker=40 +Slith Firewalker=36 Slith Predator=37 Slith Strider=25 Slithering Shade=25 -Slithermuse=41 +Slithermuse=28 Slithery Stalker=14 -Sliver Legion=1263 +Sliver Legion=1459 Sliver Overlord=421 -Sliver Queen=2131 -Sliver Token=1349 +Sliver Queen=2378 +Sliver Token=683 Sliversmith=37 -Slobad, Goblin Tinkerer=61 -Slow Motion=31 -Sludge Strider=25 +Slobad, Goblin Tinkerer=31 +Slow Motion=40 +Sludge Strider=31 Sluggishness=25 Slumbering Tora=25 -Smallpox=37 +Smallpox=32 Smart Ass=25 Smash=26 -Smash to Smithereens=64 -Smite=13 +Smash to Smithereens=58 +Smite=903 Smite the Monstrous=25 -Smogsteed Rider=25 -Smoke=283 -Smokebraider=69 +Smogsteed Rider=30 +Smoke=175 +Smokebraider=58 Smokespew Invoker=16 -Smokestack=672 +Smokestack=591 Smolder Initiate=39 Smoldering Butcher=45 Smoldering Crater=16 Smoldering Spires=25 -Smoldering Tar=31 -Smother=28 +Smoldering Tar=12 +Smother=23 Snag=11 -Snake Basket=96 +Snake Basket=78 Snake Cult Initiation=47 Snake Pit=41 -Snake Umbra=25 -Snakeform=39 -Snap=43 +Snake Umbra=32 +Snakeform=28 +Snap=81 Snapback=25 -Snapcaster Mage=2158 +Snapcaster Mage=1924 Snapping Creeper=40 Snapping Drake=39 Snapping Thragg=25 Snapsail Glider=25 Snarling Undorak=55 -Sneak Attack=2130 +Sneak Attack=2334 Sneaky Homunculus=26 Snorting Gahr=28 Snow Devil=38 @@ -9535,7 +9723,7 @@ Snow-Covered Mountain=10 Snow-Covered Plains=10 Snow-Covered Swamp=10 Snowblind=50 -Snuff Out=25 +Snuff Out=199 Soar=87 Soaring Hope=25 Soaring Seacliff=47 @@ -9543,60 +9731,62 @@ Soilshaper=30 Sokenzan Bruiser=25 Sokenzan Renegade=25 Sokenzan Spellblade=40 -Sol Grail=25 -Sol Ring=1433 -Sol'kanar the Swamp King=171 +Sol Grail=35 +Sol Ring=1422 +Sol'kanar the Swamp King=68 Solar Blast=28 Solar Tide=25 -Solarion=23 +Solarion=31 Soldevi Adnate=31 -Soldevi Digger=94 -Soldevi Excavations=121 +Soldevi Digger=29 +Soldevi Excavations=54 Soldevi Golem=50 Soldevi Heretic=28 Soldevi Machinist=25 -Soldevi Sage=25 +Soldevi Sage=11 Soldevi Sentry=25 Soldevi Simulacrum=100 -Soldevi Steam Beast=41 +Soldevi Steam Beast=37 Soldier Replica=25 -Soldier Token=110 -Soldier of Fortune=38 -Solemn Offering=22 -Solemn Simulacrum=614 +Soldier Token=91 +Soldier of Fortune=19 +Solemn Offering=31 +Solemn Simulacrum=461 Solfatara=25 Solidarity=27 -Solitary Confinement=299 +Solitary Confinement=413 Soliton=47 -Soltari Champion=49 -Soltari Crusader=39 -Soltari Emissary=75 -Soltari Foot Soldier=25 +Soltari Champion=73 +Soltari Crusader=40 +Soltari Emissary=12 +Soltari Foot Soldier=35 Soltari Guerrillas=23 Soltari Lancer=43 -Soltari Monk=47 -Soltari Priest=30 +Soltari Monk=52 +Soltari Priest=27 Soltari Trooper=15 -Soltari Visionary=40 +Soltari Visionary=38 Somber Hoverguard=25 +Somberwald Dryad=32 +Somberwald Sage=164 Somberwald Spider=30 Somnomancer=25 -Somnophore=49 +Somnophore=25 Song of Blood=11 Song of Serenity=99 -Songs of the Damned=25 +Songs of the Damned=47 Songstitcher=29 Sonic Burst=52 Sonic Seizure=27 Soot Imp=25 Sootfeather Flock=16 Soothing Balm=25 -Soothsaying=93 +Soothsaying=38 Sootstoke Kindler=47 Sootwalkers=25 Sophic Centaur=25 Soramaro, First to Dream=25 -Soratami Cloud Chariot=157 +Soratami Cloud Chariot=25 Soratami Cloudskater=32 Soratami Mindsweeper=25 Soratami Mirror-Guard=25 @@ -9606,80 +9796,83 @@ Soratami Savant=25 Soratami Seer=25 Soraya the Falconer=100 Sorcerer's Strongbox=25 -Sorceress Queen=113 -Sorcerous Sight=44 -Sorin Markov=458 -Sorin's Thirst=199 -Sorin's Vengeance=50 +Sorceress Queen=90 +Sorcerous Sight=99 +Sorin Markov=441 +Sorin's Thirst=23 +Sorin's Vengeance=38 +Sorin, Lord of Innistrad=1879 Sorrow's Path=211 Sorry=31 -Sosuke's Summons=41 -Sosuke, Son of Seshiro=79 +Sosuke's Summons=40 +Sosuke, Son of Seshiro=40 Soul Barrier=27 Soul Bleed=25 Soul Burn=17 Soul Channeling=7 Soul Charmer=650 -Soul Collector=101 -Soul Conduit=25 +Soul Collector=60 +Soul Conduit=33 Soul Echo=99 -Soul Exchange=54 +Soul Exchange=49 Soul Feast=16 -Soul Foundry=195 +Soul Foundry=176 Soul Kiss=25 -Soul Link=40 +Soul Link=19 Soul Manipulation=25 Soul Net=22 Soul Nova=25 Soul Parry=25 -Soul Reap=40 +Soul Reap=31 Soul Rend=25 Soul Scourge=41 -Soul Sculptor=65 +Soul Sculptor=40 +Soul Seizer=25 Soul Shepherd=25 Soul Shred=38 -Soul Snuffers=31 -Soul Spike=25 +Soul Snuffers=25 +Soul Spike=57 Soul Stair Expedition=25 Soul Strings=25 -Soul Warden=24 +Soul Warden=30 Soul of Magma=25 -Soul's Attendant=28 -Soul's Fire=26 +Soul of the Harvest=63 +Soul's Attendant=31 +Soul's Fire=25 Soul's Grace=45 -Soul's Majesty=48 +Soul's Majesty=55 Soul's Might=42 -Soulblast=31 +Soulblast=41 Soulbound Guardians=25 Soulbright Flamekin=25 -Soulcatcher=108 -Soulcatchers' Aerie=100 +Soulcatcher=38 +Soulcatchers' Aerie=10 Souldrinker=25 Soulgorger Orgg=40 -Soulless One=169 +Soulless One=162 Soulless Revival=25 -Soulquake=48 -Souls of the Faultless=128 -Soulscour=195 -Soulshriek=25 +Soulquake=58 +Souls of the Faultless=68 +Soulscour=50 +Soulshriek=36 Soulsurge Elemental=25 Soulsworn Jury=20 Soultether Golem=25 Sound the Call=25 -Southern Elephant=43 -Southern Paladin=153 -Sovereigns of Lost Alara=88 -Sower of Temptation=625 -Sowing Salt=32 +Southern Elephant=45 +Southern Paladin=49 +Sovereigns of Lost Alara=131 +Sower of Temptation=512 +Sowing Salt=42 Spare from Evil=30 -Spark Elemental=25 -Spark Fiend=100 +Spark Elemental=32 +Spark Fiend=150 Spark Mage=25 Spark Spray=40 Sparkcaster=25 Sparkmage Apprentice=25 Sparksmith=47 -Sparkspitter=28 +Sparkspitter=38 Sparring Collar=49 Sparring Golem=29 Spatial Binding=29 @@ -9687,45 +9880,45 @@ Spatula of the Ages=31 Spawnbroker=25 Spawning Breath=30 Spawning Pit=25 -Spawning Pool=22 -Spawnsire of Ulamog=115 -Spawnwrithe=52 -Spearbreaker Behemoth=62 -Specter's Shroud=26 +Spawning Pool=40 +Spawnsire of Ulamog=104 +Spawnwrithe=48 +Spearbreaker Behemoth=130 +Specter's Shroud=25 Specter's Wail=38 Spectral Bears=25 Spectral Cloak=143 -Spectral Flight=34 -Spectral Force=122 -Spectral Guardian=52 -Spectral Lynx=32 -Spectral Procession=172 -Spectral Rider=34 -Spectral Searchlight=37 +Spectral Flight=33 +Spectral Force=40 +Spectral Guardian=150 +Spectral Lynx=87 +Spectral Procession=284 +Spectral Rider=28 +Spectral Searchlight=105 Spectral Shield=100 -Spectral Shift=25 +Spectral Shift=100 Spectral Sliver=25 -Spell Blast=23 -Spell Burst=43 +Spell Blast=34 +Spell Burst=58 Spell Contortion=25 Spell Counter=40 -Spell Pierce=54 -Spell Snare=837 +Spell Pierce=57 +Spell Snare=773 Spell Snip=25 Spell Syphon=25 Spellbane Centaur=25 -Spellbinder=74 -Spellbook=26 -Spellbound Dragon=121 -Spellbreaker Behemoth=89 +Spellbinder=38 +Spellbook=21 +Spellbound Dragon=88 +Spellbreaker Behemoth=147 Spellgorger Barbarian=28 -Spelljack=155 +Spelljack=158 Spellshift=25 Spellshock=8 -Spellskite=473 -Spellstutter Sprite=214 -Spelltithe Enforcer=43 -Spellweaver Helix=42 +Spellskite=319 +Spellstutter Sprite=208 +Spelltithe Enforcer=37 +Spellweaver Helix=81 Spellweaver Volute=56 Spellwild Ouphe=25 Sphere of Duty=25 @@ -9733,192 +9926,194 @@ Sphere of Grace=44 Sphere of Law=29 Sphere of Purity=25 Sphere of Reason=25 -Sphere of Resistance=543 +Sphere of Resistance=434 Sphere of Truth=25 -Sphere of the Suns=51 -Sphinx Ambassador=104 -Sphinx Sovereign=130 -Sphinx Summoner=97 -Sphinx of Jwar Isle=27 -Sphinx of Lost Truths=25 -Sphinx of Magosi=72 -Sphinx of Uthuun=101 -Sphinx of the Steel Wind=455 +Sphere of the Suns=66 +Sphinx Ambassador=150 +Sphinx Sovereign=158 +Sphinx Summoner=16 +Sphinx of Jwar Isle=29 +Sphinx of Lost Truths=31 +Sphinx of Magosi=58 +Sphinx of Uthuun=31 +Sphinx of the Steel Wind=228 Sphinx's Herald=25 -Sphinx-Bone Wand=25 +Sphinx-Bone Wand=33 Spider Climb=40 -Spider Spawning=48 +Spider Spawning=31 Spider Umbra=33 -Spidersilk Armor=52 +Spidersilk Armor=54 Spidersilk Net=45 Spiderwig Boggart=16 -Spidery Grasp=47 +Spidery Grasp=78 Spike Breeder=37 -Spike Cannibal=55 +Spike Cannibal=52 Spike Colony=49 Spike Drone=25 -Spike Feeder=35 +Spike Feeder=28 Spike Hatcher=25 -Spike Rogue=40 +Spike Rogue=38 Spike Soldier=44 Spike Tiller=25 -Spike Weaver=181 +Spike Weaver=121 Spike Worker=16 -Spikeshot Elder=85 -Spikeshot Goblin=25 -Spiketail Drake=36 +Spikeshot Elder=56 +Spikeshot Goblin=47 +Spiketail Drake=100 Spiketail Drakeling=25 -Spiketail Hatchling=28 +Spiketail Hatchling=27 Spin Engine=27 -Spin into Myth=76 -Spinal Embrace=78 +Spin into Myth=93 +Spinal Embrace=74 Spinal Graft=28 Spinal Parasite=25 -Spinal Villain=825 +Spinal Villain=426 Spincrusher=25 Spindrift Drake=16 -Spine of Ish Sah=32 +Spine of Ish Sah=46 Spinebiter=25 Spined Basher=15 Spined Fluke=41 -Spined Sliver=25 -Spined Thopter=16 +Spined Sliver=22 +Spined Thopter=25 Spined Wurm=17 Spineless Thug=26 -Spinerock Knoll=144 -Spinneret Sliver=44 -Spinning Darkness=50 +Spinerock Knoll=87 +Spinneret Sliver=45 +Spinning Darkness=46 Spiny Starfish=40 -Spiraling Duelist=25 +Spiraling Duelist=34 Spiraling Embers=25 Spire Barrage=25 Spire Golem=25 Spire Monitor=12 Spire Owl=16 Spire Serpent=47 -Spirit Cairn=200 +Spirit Away=33 +Spirit Cairn=138 Spirit Flare=28 -Spirit Link=81 +Spirit Link=29 Spirit Loop=37 -Spirit Mantle=43 -Spirit Mirror=54 +Spirit Mantle=44 +Spirit Mirror=99 Spirit Shackle=25 Spirit Shield=48 -Spirit Token=85 +Spirit Token=33 Spirit Weaver=25 Spirit en-Dal=8 Spirit en-Kor=44 -Spirit of Resistance=100 -Spirit of the Hearth=94 -Spirit of the Night=400 -Spiritmonger=308 -Spiritual Asylum=56 +Spirit of Resistance=92 +Spirit of the Hearth=127 +Spirit of the Night=246 +Spiritmonger=342 +Spiritual Asylum=26 Spiritual Focus=36 -Spiritual Guardian=144 -Spiritual Sanctuary=200 +Spiritual Guardian=99 +Spiritual Sanctuary=182 Spiritual Visit=25 Spiritualize=25 Spite/Malice=100 -Spitebellows=16 +Spitebellows=8 Spiteflame Witch=25 Spiteful Bully=28 -Spiteful Visions=50 +Spiteful Shadows=17 +Spiteful Visions=92 Spitemare=41 Spitfire Handler=25 Spitting Drake=32 Spitting Earth=30 Spitting Gourna=25 Spitting Hydra=79 -Spitting Image=103 +Spitting Image=163 Spitting Sliver=25 -Spitting Slug=50 -Spitting Spider=519 -Splinter=35 -Splinter Twin=300 -Splinterfright=40 +Spitting Slug=28 +Spitting Spider=40 +Splinter=173 +Splinter Twin=258 +Splinterfright=36 Splintering Wind=40 Split-Tail Miko=25 Splitting Headache=25 -Spoils of Evil=41 -Spoils of Victory=526 +Spoils of Evil=107 +Spoils of Victory=338 Spoils of War=10 -Spoils of the Vault=58 -Spontaneous Combustion=50 -Spontaneous Generation=99 -Spore Burst=25 +Spoils of the Vault=52 +Spontaneous Combustion=25 +Spontaneous Generation=35 +Spore Burst=37 Spore Cloud=111 -Spore Flower=50 -Spore Frog=31 +Spore Flower=175 +Spore Frog=63 Sporeback Troll=25 Sporecap Spider=40 -Sporesower Thallid=25 -Sporogenesis=23 -Sporoloth Ancient=26 -Spotted Griffin=38 -Spread the Sickness=42 +Sporesower Thallid=104 +Sporogenesis=149 +Sporoloth Ancient=25 +Spotted Griffin=25 +Spread the Sickness=34 Spreading Algae=64 Spreading Plague=50 -Spreading Seas=33 +Spreading Seas=45 Spring Cleaning=40 -Spring of Eternal Peace=86 +Spring of Eternal Peace=99 Springing Tiger=37 Springjack Knight=25 -Springjack Pasture=88 +Springjack Pasture=141 Springjack Shepherd=25 -Springleaf Drum=75 -Sprite Noble=86 +Springleaf Drum=78 +Sprite Noble=25 Sprout=25 Sprout Swarm=45 -Sprouting Phytohydra=94 -Sprouting Thrinax=25 -Sprouting Vines=40 +Sprouting Phytohydra=93 +Sprouting Thrinax=35 +Sprouting Vines=37 Spur Grappler=56 Spurnmage Advocate=38 Spurred Wolverine=25 -Spy Network=79 -Squadron Hawk=114 +Spy Network=38 +Squadron Hawk=54 Squall=454 Squall Drifter=25 Squall Line=64 Squallmonger=25 -Squandered Resources=56 +Squandered Resources=140 Squeaking Pie Grubfellows=25 Squeaking Pie Sneak=25 Squealing Devil=25 Squee's Embrace=25 Squee's Revenge=40 -Squee's Toy=25 -Squee, Goblin Nabob=289 +Squee's Toy=40 +Squee, Goblin Nabob=307 Squeeze=30 Squelch=12 Squire=16 Squirming Mass=25 -Squirrel Farm=187 -Squirrel Mob=563 -Squirrel Nest=272 -Squirrel Token=367 -Squirrel Wrangler=183 -Stabbing Pain=25 -Stabilizer=99 -Staff of Domination=374 +Squirrel Farm=157 +Squirrel Mob=529 +Squirrel Nest=323 +Squirrel Token=791 +Squirrel Wrangler=178 +Stabbing Pain=99 +Stabilizer=25 +Staff of Domination=444 Staff of Zegon=25 Staff of the Ages=8 Stag Beetle=99 -Staggershock=158 +Staggershock=185 Stalker Hag=31 -Stalking Assassin=56 -Stalking Bloodsucker=25 -Stalking Stones=43 +Stalking Assassin=25 +Stalking Bloodsucker=45 +Stalking Stones=50 Stalking Tiger=42 -Stalking Vengeance=99 +Stalking Vengeance=125 Stalking Yeti=12 Stalwart Shield-Bearers=25 Stamina=25 Stampede=100 -Stampede Driver=38 +Stampede Driver=28 Stampeding Rhino=99 -Stampeding Serow=40 -Stampeding Wildebeests=45 +Stampeding Serow=25 +Stampeding Wildebeests=34 Stand Firm=28 Stand Together=31 Stand or Fall=25 @@ -9928,126 +10123,129 @@ Standardize=71 Standing Army=28 Standing Stones=32 Standing Troops=28 -Standstill=473 -Stangg=38 +Standstill=423 +Stangg=56 Star Compass=22 -Starke of Rath=42 +Starke of Rath=112 Starlight=26 -Starlight Invoker=15 -Starlit Angel=99 -Starlit Sanctum=36 -Starstorm=109 -Starved Rusalka=25 -Stasis=554 +Starlight Invoker=10 +Starlit Angel=104 +Starlit Sanctum=45 +Starstorm=115 +Starved Rusalka=30 +Stasis=409 Stasis Cell=25 Stasis Cocoon=41 Statecraft=79 -Static Orb=85 -Staunch Defenders=27 +Static Orb=94 +Staunch Defenders=24 Stave Off=38 -Staying Power=130 +Staying Power=100 Steadfast Guard=26 Steadfastness=33 -Steady Progress=31 -Steal Artifact=25 -Steal Enchantment=10 +Steady Progress=36 +Steal Artifact=24 +Steal Enchantment=104 Steal Strength=38 Steam Blast=44 Steam Catapult=400 Steam Frigate=41 Steam Spitter=25 -Steam Vents=2068 +Steam Vents=1924 Steam Vines=25 Steamclaw=25 Steamcore Weird=25 Steamflogger Boss=23 -Steel Golem=37 -Steel Hellkite=77 +Steel Golem=45 +Steel Hellkite=58 Steel Leaf Paladin=16 -Steel Overseer=274 -Steel Sabotage=36 +Steel Overseer=241 +Steel Sabotage=25 Steel Wall=40 -Steel of the Godhead=35 +Steel of the Godhead=31 Steelclad Serpent=25 Steeling Stance=25 Steelshaper Apprentice=25 -Steelshaper's Gift=340 -Steely Resolve=191 +Steelshaper's Gift=336 +Steely Resolve=152 Stench of Decay=25 -Stench of Evil=19 +Stench of Evil=44 Stenchskipper=15 -Stensia Bloodhall=28 -Steppe Lynx=31 -Sterling Grove=336 -Stern Marshal=150 +Stensia Bloodhall=32 +Steppe Lynx=25 +Sterling Grove=349 +Stern Marshal=99 +Stern Mentor=25 Stern Proctor=17 -Steward of Valeron=50 -Stifle=1291 -Stigma Lasher=248 +Steward of Valeron=25 +Stifle=1603 +Stigma Lasher=103 Still Life=39 -Stillmoon Cavalier=517 +Stillmoon Cavalier=388 Stingerfling Spider=25 Stinging Barrier=13 Stinging Licid=70 Stingmoggie=25 Stingscourger=25 -Stinkdrinker Bandit=25 -Stinkweed Imp=46 -Stir the Grave=24 +Stinkdrinker Bandit=45 +Stinkweed Imp=45 +Stir the Grave=25 Stir the Pride=25 -Stirring Wildwood=116 -Stitch Together=66 -Stitch in Time=98 -Stitched Drake=11 -Stitcher's Apprentice=14 -Stoic Angel=132 +Stirring Wildwood=160 +Stitch Together=44 +Stitch in Time=159 +Stitched Drake=25 +Stitcher's Apprentice=32 +Stoic Angel=141 Stoic Champion=25 Stoic Ephemera=25 -Stoic Rebuttal=30 +Stoic Rebuttal=40 +Stolen Goods=57 Stolen Grain=50 Stomp and Howl=40 Stomper Cub=25 -Stomping Ground=1653 +Stomping Ground=1518 Stomping Slabs=25 -Stone Calendar=60 +Stone Calendar=149 Stone Catapult=556 -Stone Giant=16 +Stone Giant=15 Stone Golem=25 -Stone Idol Trap=12 +Stone Idol Trap=34 Stone Kavu=28 -Stone Rain=16 +Stone Rain=15 Stone Spirit=16 Stone-Cold Basilisk=25 Stone-Seeder Hierophant=114 -Stone-Throwing Devils=346 -Stone-Tongue Basilisk=60 -Stonebrow, Krosan Hero=99 +Stone-Throwing Devils=187 +Stone-Tongue Basilisk=48 +Stonebrow, Krosan Hero=32 Stonecloaker=25 -Stoneforge Mystic=669 -Stonehewer Giant=337 -Stonehorn Dignitary=25 +Stoneforge Mystic=699 +Stonehewer Giant=461 +Stonehorn Dignitary=99 Stoneshaker Shaman=25 -Stonewood Invocation=63 +Stonewood Invocation=67 Stonewood Invoker=16 Stonework Puma=38 +Stonewright=45 Stony Silence=32 Stonybrook Angler=38 -Stonybrook Banneret=46 -Stonybrook Schoolmaster=43 +Stonybrook Banneret=88 +Stonybrook Schoolmaster=38 Stop That=25 -Storage Matrix=24 -Storm Cauldron=54 -Storm Crow=27 -Storm Elemental=25 +Storage Matrix=33 +Storm Cauldron=28 +Storm Crow=12 +Storm Elemental=19 Storm Entity=25 Storm Front=40 -Storm Herd=77 -Storm Seeker=183 +Storm Herd=79 +Storm Seeker=181 Storm Shaman=26 Storm Spirit=25 -Storm World=104 +Storm World=244 Stormbind=24 -Stormblood Berserker=120 +Stormblood Berserker=123 Stormcaller's Boon=25 Stormcloud Djinn=25 Stormfront Pegasus=30 @@ -10055,144 +10253,147 @@ Stormfront Riders=25 Stormscale Anarch=100 Stormscape Apprentice=40 Stormscape Battlemage=25 -Stormscape Familiar=30 +Stormscape Familiar=40 Stormscape Master=25 -Stormtide Leviathan=86 +Stormtide Leviathan=43 Stormwatch Eagle=16 -Story Circle=69 -Strafe=1000 -Strands of Night=25 +Story Circle=63 +Strafe=1495 +Strands of Night=26 Strands of Undeath=25 Strandwalker=25 Strange Inversion=25 +Strangleroot Geist=176 Strangling Soot=25 -Strata Scythe=27 +Strata Scythe=28 Stratadon=32 -Strategic Planning=400 -Strategy, Schmategy=225 +Strategic Planning=5599 +Strategy, Schmategy=114 Stratozeppelid=43 Straw Golem=25 Straw Soldiers=50 Stream Hopper=25 -Stream of Acid=275 +Stream of Acid=225 Stream of Consciousness=25 -Stream of Life=49 +Stream of Life=42 Stream of Unconsciousness=25 Streambed Aquitects=37 Street Savvy=25 -Street Wraith=146 +Street Wraith=104 Streetbreaker Wurm=15 -Strength in Numbers=40 +Strength in Numbers=38 Strength of Cedars=25 Strength of Isolation=25 Strength of Lunacy=38 -Strength of Night=40 +Strength of Night=19 Strength of Unity=25 -Strength of the Tajuru=25 -Strider Harness=25 +Strength of the Tajuru=41 +Strider Harness=11 Strip Bare=39 -Strip Mine=559 -Striped Bears=39 -Stroke of Genius=326 +Strip Mine=300 +Striped Bears=40 +Stroke of Genius=508 Stromgald Cabal=57 -Stromgald Crusader=144 +Stromgald Crusader=238 Stromgald Spy=19 -Stromkirk Noble=363 +Stromkirk Captain=57 +Stromkirk Noble=280 Stromkirk Patrol=16 -Strongarm Tactics=199 +Strongarm Tactics=24 Strongarm Thug=31 -Stronghold Assassin=31 -Stronghold Biologist=29 +Stronghold Assassin=56 +Stronghold Biologist=25 Stronghold Discipline=45 -Stronghold Gambit=36 +Stronghold Gambit=33 Stronghold Machinist=25 -Stronghold Overseer=90 +Stronghold Overseer=69 Stronghold Rats=12 Stronghold Taskmaster=25 Stronghold Zeppelin=25 Struggle for Sanity=25 -Student of Elements=32 -Student of Warfare=264 -Stuffy Doll=500 +Student of Elements=25 +Student of Warfare=342 +Stuffy Doll=513 Stun=27 -Stun Sniper=33 +Stun Sniper=45 Stunted Growth=52 Stupefying Touch=599 -Stupor=26 +Stupor=39 Sturdy Hatchling=25 -Sturmgeist=27 -Su-Chi=335 +Sturmgeist=26 +Su-Chi=313 Subdue=25 -Submerge=271 +Submerge=224 Subterranean Hangar=30 Subterranean Shambler=25 Subterranean Spirit=81 -Subversion=25 -Sudden Death=37 +Subversion=92 +Sudden Death=47 +Sudden Disappearance=30 Sudden Impact=28 -Sudden Shock=30 -Sudden Spoiling=182 +Sudden Shock=70 +Sudden Spoiling=265 Sudden Strength=28 -Suffer the Past=35 -Suffocating Blast=24 +Suffer the Past=25 +Suffocating Blast=44 Suffocation=31 Suicidal Charge=25 Sulam Djinn=25 Suleiman's Legacy=79 -Sulfur Elemental=25 -Sulfur Falls=366 +Sulfur Elemental=63 +Sulfur Falls=459 Sulfur Vent=31 Sulfuric Vapors=58 -Sulfuric Vortex=205 +Sulfuric Vortex=279 Sulfurous Blast=25 -Sulfurous Springs=113 -Summer Bloom=37 +Sulfurous Springs=81 +Summer Bloom=36 Summit Apes=50 -Summon the School=48 +Summon the School=116 Summoner's Bane=25 -Summoner's Egg=66 -Summoner's Pact=552 -Summoning Station=88 -Summoning Trap=61 +Summoner's Egg=34 +Summoner's Pact=634 +Summoning Station=39 +Summoning Trap=89 Sun Clasp=25 -Sun Droplet=52 -Sun Quan, Lord of Wu=549 -Sun Titan=401 +Sun Droplet=77 +Sun Quan, Lord of Wu=833 +Sun Titan=373 Sun's Bounty=41 -Sunastian Falconer=100 +Sunastian Falconer=145 Sunbeam Spellbomb=25 -Sunblast Angel=78 +Sunblast Angel=60 Suncrusher=162 -Sunder=93 +Sunder=199 Sunder from Within=25 -Sundering Titan=127 +Sundering Titan=202 Sundering Vitae=38 -Sundial of the Infinite=36 +Sundial of the Infinite=34 Sunfire Balm=12 -Sunflare Shaman=16 -Sunforger=104 -Sunglasses of Urza=106 +Sunflare Shaman=40 +Sunforger=114 +Sunglasses of Urza=205 Sungrass Egg=15 -Sungrass Prairie=162 -Sunhome Enforcer=39 -Sunhome, Fortress of the Legion=35 +Sungrass Prairie=169 +Sunhome Enforcer=36 +Sunhome, Fortress of the Legion=52 Sunken City=18 -Sunken Field=26 -Sunken Hope=27 -Sunken Ruins=696 -Sunlance=32 -Sunpetal Grove=211 -Sunrise Sovereign=62 -Sunscape Apprentice=10 +Sunken Field=25 +Sunken Hope=25 +Sunken Ruins=682 +Sunlance=40 +Sunpetal Grove=233 +Sunrise Sovereign=45 +Sunscape Apprentice=30 Sunscape Battlemage=25 Sunscape Familiar=38 -Sunscape Master=10 -Sunscour=98 +Sunscape Master=87 +Sunscour=99 Sunseed Nurturer=25 -Sunspear Shikari=35 +Sunspear Shikari=30 Sunspring Expedition=25 Sunstone=999 -Sunstrike Legionnaire=40 +Sunstrike Legionnaire=25 Suntail Hawk=25 Suntouched Myr=31 Sunweb=25 @@ -10201,136 +10402,136 @@ Superior Numbers=25 Supersize=28 Supply/Demand=40 Suppress=29 -Suppression Field=34 -Supreme Exemplar=79 -Supreme Inquisitor=55 -Suq'Ata Assassin=114 -Suq'Ata Firewalker=58 +Suppression Field=44 +Supreme Exemplar=25 +Supreme Inquisitor=25 +Suq'Ata Assassin=41 +Suq'Ata Firewalker=38 Suq'Ata Lancer=25 -Surestrike Trident=25 -Surge Node=35 +Surestrike Trident=37 +Surge Node=25 Surge of Strength=25 Surge of Thoughtweft=25 Surge of Zeal=25 -Surgespanner=41 -Surgical Extraction=553 +Surgespanner=35 +Surgical Extraction=504 Surging AEther=25 Surging Dementia=40 Surging Flame=25 Surging Might=25 Surging Sentinels=25 Surprise Deployment=27 -Surrakar Banisher=25 +Surrakar Banisher=16 Surrakar Marauder=25 Surrakar Spellblade=25 Surreal Memoir=42 -Surveilling Sprite=25 -Survival Cache=27 -Survival of the Fittest=1729 +Surveilling Sprite=21 +Survival Cache=30 +Survival of the Fittest=1861 Survivor of the Unseen=25 -Sustainer of the Realm=34 +Sustainer of the Realm=33 Sustaining Spirit=23 Sustenance=25 -Suture Priest=25 +Suture Priest=33 Suture Spirit=24 -Sutured Ghoul=28 +Sutured Ghoul=25 Svogthos, the Restless Tomb=25 Svyelunite Priest=29 Svyelunite Temple=25 Swallowing Plague=25 Swamp=5 Swamp Mosquito=28 -Swans of Bryn Argoll=196 -Swarm of Rats=58 -Swarmyard=214 +Swans of Bryn Argoll=299 +Swarm of Rats=69 +Swarmyard=328 Swat=26 -Sway of Illusion=54 +Sway of Illusion=47 Sway of the Stars=104 Swell of Courage=25 Swelter=25 -Swerve=47 +Swerve=25 Swift Maneuver=25 -Swift Silence=151 -Swiftfoot Boots=79 +Swift Silence=25 +Swiftfoot Boots=80 Swirl the Mists=47 Swirling Sandstorm=25 Swirling Spriggan=25 Swooping Talon=25 Sword Dancer=25 -Sword of Body and Mind=995 -Sword of Feast and Famine=2547 -Sword of Fire and Ice=2832 -Sword of Kaldra=391 -Sword of Light and Shadow=2230 -Sword of Vengeance=104 -Sword of War and Peace=3334 -Sword of the Ages=799 -Sword of the Chosen=79 -Sword of the Meek=138 -Sword of the Paruns=26 -Swords to Plowshares=334 -Sworn Defender=71 -Sygg, River Cutthroat=153 -Sygg, River Guide=65 -Sylvan Basilisk=136 +Sword of Body and Mind=838 +Sword of Feast and Famine=2059 +Sword of Fire and Ice=2527 +Sword of Kaldra=423 +Sword of Light and Shadow=2188 +Sword of Vengeance=113 +Sword of War and Peace=2846 +Sword of the Ages=875 +Sword of the Chosen=109 +Sword of the Meek=142 +Sword of the Paruns=100 +Swords to Plowshares=256 +Sworn Defender=62 +Sygg, River Cutthroat=200 +Sygg, River Guide=85 +Sylvan Basilisk=162 Sylvan Bounty=49 Sylvan Echoes=25 Sylvan Hierophant=45 -Sylvan Library=986 -Sylvan Messenger=120 +Sylvan Library=1056 +Sylvan Messenger=94 Sylvan Might=25 -Sylvan Paradise=100 -Sylvan Ranger=25 -Sylvan Safekeeper=26 -Sylvan Scrying=55 -Sylvan Tutor=1573 +Sylvan Paradise=49 +Sylvan Ranger=30 +Sylvan Safekeeper=100 +Sylvan Scrying=50 +Sylvan Tutor=1623 Sylvan Yeti=175 Sylvok Explorer=49 -Sylvok Lifestaff=35 -Sylvok Replica=31 +Sylvok Lifestaff=34 +Sylvok Replica=27 Symbiosis=40 Symbiotic Beast=25 Symbiotic Deployment=74 Symbiotic Elf=15 -Symbiotic Wurm=29 +Symbiotic Wurm=25 Symbol Status=25 Symbol of Unsummoning=25 -Synapse Sliver=172 -Synchronous Sliver=81 +Synapse Sliver=125 +Synchronous Sliver=38 Syncopate=29 -Synod Artificer=25 +Synod Artificer=39 Synod Centurion=49 Synod Sanctum=25 -Syphon Life=35 -Syphon Mind=77 -Syphon Soul=26 -Szadek, Lord of Secrets=84 +Syphon Life=25 +Syphon Mind=25 +Syphon Soul=24 +Szadek, Lord of Secrets=65 Tablet of Epityr=25 Tahngarth's Glare=28 Tahngarth's Rage=25 -Tahngarth, Talruum Hero=100 -Taiga=6329 -Tainted AEther=73 -Tainted Field=115 -Tainted Isle=105 +Tahngarth, Talruum Hero=49 +Taiga=7314 +Tainted AEther=38 +Tainted Field=109 +Tainted Isle=121 Tainted Monkey=25 Tainted Pact=95 -Tainted Peak=67 -Tainted Sigil=43 +Tainted Peak=87 +Tainted Sigil=48 Tainted Specter=74 -Tainted Strike=47 +Tainted Strike=34 Tainted Well=33 -Tainted Wood=73 +Tainted Wood=97 Taj-Nar Swordsmith=25 -Tajuru Archer=25 -Tajuru Preserver=64 -Take Possession=26 +Tajuru Archer=32 +Tajuru Preserver=38 +Take Possession=62 Takeno's Cavalry=25 -Takeno, Samurai General=26 +Takeno, Samurai General=70 Takenuma Bleeder=25 Takklemaggot=53 Talara's Bane=25 -Talara's Battalion=441 +Talara's Battalion=277 Talas Air Ship=33 Talas Explorer=38 Talas Merchant=40 @@ -10338,206 +10539,211 @@ Talas Researcher=99 Talas Scout=43 Talas Warrior=99 Talisman of Dominance=23 -Talisman of Impulse=49 +Talisman of Impulse=31 Talisman of Indulgence=36 Talisman of Progress=48 Talisman of Unity=62 -Tallowisp=50 -Talon Sliver=40 +Tallowisp=100 +Talon Sliver=69 Talon Trooper=25 Talon of Pain=31 Talonrend=25 Talruum Champion=33 Talruum Minotaur=27 Talruum Piper=30 -Talus Paladin=37 -Tamanoa=88 -Tangle=93 -Tangle Angler=37 +Talus Paladin=34 +Tamanoa=145 +Tamiyo, the Moon Sage=2586 +Tandem Lookout=45 +Tangle=85 +Tangle Angler=25 Tangle Asp=25 -Tangle Golem=37 +Tangle Golem=25 Tangle Hulk=13 Tangle Kelp=50 Tangle Mantis=25 Tangle Spider=23 -Tangle Wire=248 +Tangle Wire=296 Tanglebloom=25 Tangleroot=25 -Tanglesap=25 +Tanglesap=31 Tanglewalker=25 -Taniwha=84 -Taoist Hermit=552 -Taoist Mystic=657 -Tar Fiend=125 +Taniwha=99 +Taoist Hermit=500 +Taoist Mystic=323 +Tar Fiend=66 Tar Pit Warrior=40 Tar Pitcher=25 -Tarfire=43 -Tariff=70 -Tarmogoyf=8217 -Tarnished Citadel=367 +Tarfire=25 +Tariff=98 +Tarmogoyf=9263 +Tarnished Citadel=380 Tarox Bladewing=28 -Tarpan=28 +Tarpan=13 Task Force=50 -Task Mage Assembly=49 +Task Mage Assembly=65 Taste for Mayhem=25 Taste of Blood=35 Taste of Paradise=25 -Tatsumasa, the Dragon's Fang=182 -Tattered Drake=46 +Tatsumasa, the Dragon's Fang=203 +Tattered Drake=30 Tatterkite=40 Tattermunge Duo=40 Tattermunge Maniac=25 -Tattermunge Witch=37 +Tattermunge Witch=25 Tattoo Ward=40 Taunt=120 -Taunting Challenge=613 -Taunting Elf=30 -Taurean Mauler=139 -Tawnos's Coffin=1497 +Taunting Challenge=523 +Taunting Elf=33 +Taurean Mauler=274 +Tawnos's Coffin=1251 Tawnos's Wand=30 Tawnos's Weaponry=36 Team Spirit=16 Teardrop Kami=25 Tears of Rage=25 Tectonic Break=79 -Tectonic Edge=75 +Tectonic Edge=101 Tectonic Fiend=25 -Tectonic Instability=29 +Tectonic Instability=99 Tectonic Rift=36 -Teeka's Dragon=208 +Teeka's Dragon=147 Teetering Peaks=32 Teferi's Care=25 Teferi's Curse=25 Teferi's Drake=25 Teferi's Imp=35 -Teferi's Isle=175 -Teferi's Moat=30 -Teferi's Puzzle Box=108 -Teferi's Realm=73 -Teferi's Response=51 -Teferi's Veil=40 -Teferi, Mage of Zhalfir=353 -Tek=100 +Teferi's Isle=103 +Teferi's Moat=86 +Teferi's Puzzle Box=71 +Teferi's Realm=74 +Teferi's Response=31 +Teferi's Veil=38 +Teferi, Mage of Zhalfir=399 +Tek=99 Tel-Jilad Archers=28 Tel-Jilad Chosen=25 Tel-Jilad Defiance=29 Tel-Jilad Exile=25 Tel-Jilad Fallen=25 -Tel-Jilad Justice=7 +Tel-Jilad Justice=55 Tel-Jilad Lifebreather=25 Tel-Jilad Outrider=47 -Tel-Jilad Stylus=31 +Tel-Jilad Stylus=37 Tel-Jilad Wolf=25 -Telekinesis=261 +Telekinesis=560 Telekinetic Bonds=100 -Telekinetic Sliver=60 -Telemin Performance=69 +Telekinetic Sliver=74 +Telemin Performance=103 Telepathic Spies=26 Telepathy=22 Teleport=62 Telethopter=25 Telim'Tor=49 Telim'Tor's Darts=25 -Telim'Tor's Edict=48 +Telim'Tor's Edict=15 Teller of Tales=25 -Telling Time=31 +Telling Time=24 Temp of the Damned=25 -Temper=331 -Tempered Steel=285 -Tempest Drake=25 -Tempest Efreet=57 +Temper=68 +Tempered Steel=178 +Tempest Drake=54 +Tempest Efreet=54 Tempest Owl=11 Tempest of Light=24 -Temple Acolyte=40 -Temple Bell=30 +Temple Acolyte=25 +Temple Bell=25 Temple Elder=55 -Temple Garden=1559 -Temple of the False God=110 -Temporal Adept=21 -Temporal Aperture=103 -Temporal Cascade=49 +Temple Garden=1621 +Temple of the False God=205 +Temporal Adept=36 +Temporal Aperture=148 +Temporal Cascade=33 Temporal Distortion=57 Temporal Eddy=25 -Temporal Extortion=171 -Temporal Fissure=37 +Temporal Extortion=207 +Temporal Fissure=13 Temporal Isolation=37 -Temporal Manipulation=4451 +Temporal Manipulation=2727 +Temporal Mastery=2195 Temporal Spring=25 Temporary Insanity=50 -Temporary Truce=147 +Temporary Truce=140 Tempting Licid=42 Tempting Wurm=25 -Tendo Ice Bridge=151 -Tendrils of Agony=97 +Tendo Ice Bridge=187 +Tendrils of Agony=99 Tendrils of Corruption=28 Tendrils of Despair=40 -Teneb, the Harvester=205 +Teneb, the Harvester=92 Tenza, Godo's Maul=42 -Tephraderm=70 +Tephraderm=50 Terashi's Cry=25 Terashi's Grasp=54 Terashi's Verdict=29 -Terastodon=85 -Teremko Griffin=28 +Terastodon=56 +Teremko Griffin=100 Terminal Moraine=25 -Terminate=86 +Terminate=51 +Terminus=373 Teroh's Faithful=599 Teroh's Vanguard=28 -Terra Eternal=30 -Terra Stomper=39 +Terra Eternal=34 +Terra Stomper=47 Terraformer=25 -Terrain Generator=44 -Terramorphic Expanse=13 +Terrain Generator=112 +Terramorphic Expanse=22 Terrarion=299 -Terravore=1010 +Terravore=835 Territorial Baloth=42 Territorial Dispute=49 Terror=30 -Test of Endurance=400 +Test of Endurance=267 Test of Faith=25 Testament of Faith=40 -Tethered Griffin=100 +Tethered Griffin=74 Tethered Skirge=25 -Tetravus=164 -Tetsuo Umezawa=927 -Teysa, Orzhov Scion=147 -Tezzeret the Seeker=536 -Tezzeret's Gambit=116 -Tezzeret, Agent of Bolas=1082 -Thada Adel, Acquisitor=67 +Tetravus=185 +Tetsuo Umezawa=1309 +Teysa, Orzhov Scion=272 +Tezzeret the Seeker=530 +Tezzeret's Gambit=109 +Tezzeret, Agent of Bolas=832 +Thada Adel, Acquisitor=55 Thalakos Deceiver=79 Thalakos Dreamsower=40 Thalakos Drifters=49 Thalakos Lowlands=40 Thalakos Mistfolk=25 Thalakos Scout=16 -Thalakos Seer=40 -Thalakos Sentry=25 -Thallid=88 -Thallid Devourer=50 +Thalakos Seer=37 +Thalakos Sentry=37 +Thalia, Guardian of Thraben=322 +Thallid=25 +Thallid Devourer=25 Thallid Germinator=29 -Thallid Shell-Dweller=25 -That Which Was Taken=296 +Thallid Shell-Dweller=37 +That Which Was Taken=254 Thaumatog=40 -Thawing Glaciers=547 -The Abyss=8248 +Thawing Glaciers=507 +The Abyss=9416 The Brute=14 -The Cheese Stands Alone=171 -The Fallen=50 +The Cheese Stands Alone=157 +The Fallen=37 The Fallen Apart=25 -The Hive=216 -The Lady of the Mountain=58 -The Rack=86 -The Tabernacle at Pendrell Vale=22615 -The Ultimate Nightmare of Wizards of the Coast Customer Service=88 -The Unspeakable=38 -The Wretched=331 +The Hive=195 +The Lady of the Mountain=103 +The Rack=83 +The Tabernacle at Pendrell Vale=23636 +The Ultimate Nightmare of Wizards of the Coast Customer Service=74 +The Unspeakable=52 +The Wretched=165 Theft of Dreams=33 -Thelon of Havenwood=116 -Thelon's Chant=29 +Thelon of Havenwood=49 +Thelon's Chant=50 Thelon's Curse=33 Thelonite Druid=50 -Thelonite Hermit=133 +Thelonite Hermit=67 Thelonite Monk=49 Thermal Blast=28 Thermal Flux=25 @@ -10545,127 +10751,132 @@ Thermal Glider=28 Thermal Navigator=25 Thermokarst=48 Thermopod=25 -Thick-Skinned Goblin=16 -Thicket Basilisk=68 +Thick-Skinned Goblin=25 +Thicket Basilisk=69 Thicket Elemental=50 Thief of Hope=40 -Thieves' Auction=56 +Thieves' Auction=99 Thieves' Fortune=50 Thieving Magpie=25 Thieving Sprite=121 Thing from the Deep=99 Think Tank=25 -Think Twice=30 -Thirst=295 -Thirst for Knowledge=57 +Think Twice=191 +Thirst=38 +Thirst for Knowledge=46 Thistledown Duo=25 -Thistledown Liege=133 -Thopter Assembly=32 -Thopter Foundry=73 -Thopter Squadron=79 -Thorn Elemental=28 +Thistledown Liege=164 +Thopter Assembly=38 +Thopter Foundry=81 +Thopter Squadron=62 +Thorn Elemental=41 Thorn Thallid=25 -Thorn of Amethyst=138 +Thorn of Amethyst=145 Thorn-Thrash Viashino=47 -Thornbite Staff=63 -Thornling=137 +Thornbite Staff=62 +Thornling=171 Thornscape Apprentice=38 -Thornscape Battlemage=28 +Thornscape Battlemage=30 Thornscape Familiar=52 Thornscape Master=81 -Thorntooth Witch=40 +Thorntooth Witch=25 Thornwatch Scarecrow=40 -Thornweald Archer=79 +Thornweald Archer=25 Thornwind Faeries=25 Thought Courier=25 Thought Devourer=25 -Thought Dissector=25 +Thought Dissector=33 Thought Eater=29 -Thought Gorger=62 -Thought Hemorrhage=66 -Thought Lash=400 +Thought Gorger=25 +Thought Hemorrhage=72 +Thought Lash=295 Thought Nibbler=27 Thought Prison=25 -Thought Reflection=44 +Thought Reflection=40 +Thought Scour=39 Thoughtbind=25 Thoughtbound Primoc=25 -Thoughtcast=56 +Thoughtcast=42 Thoughtcutter Agent=47 -Thoughtlace=109 +Thoughtlace=185 Thoughtleech=21 Thoughtpicker Witch=25 -Thoughts of Ruin=25 -Thoughtseize=2661 +Thoughts of Ruin=44 +Thoughtseize=2781 Thoughtweft Gambit=25 -Thoughtweft Trio=67 -Thousand-Year Elixir=187 +Thoughtweft Trio=52 +Thousand-Year Elixir=206 Thousand-legged Kami=25 -Thraben Purebloods=16 +Thraben Doomsayer=82 +Thraben Heretic=25 +Thraben Purebloods=30 Thraben Sentry=15 -Thran Dynamo=309 +Thran Dynamo=327 Thran Forge=29 Thran Foundry=32 -Thran Golem=22 -Thran Lens=23 -Thran Quarry=256 +Thran Golem=42 +Thran Lens=25 +Thran Quarry=294 Thran Tome=208 -Thran Turbine=57 +Thran Turbine=69 Thran War Machine=56 Thran Weaponry=25 Thrashing Mudspawn=25 -Thrashing Wumpus=32 -Thraximundar=515 -Threads of Disloyalty=360 +Thrashing Wumpus=25 +Thraximundar=722 +Threads of Disloyalty=319 Threaten=31 Three Tragedies=39 -Three Visits=1321 -Three Wishes=25 +Three Visits=2098 +Three Wishes=74 Thresher Beast=25 Thrill of the Hunt=25 Thriss, Nantuko Primus=74 -Thrive=28 -Throat Slitter=26 -Throne of Bone=143 -Throne of Empires=31 -Throne of Geth=40 -Through the Breach=360 -Thrull Champion=44 +Thrive=37 +Throat Slitter=97 +Throne of Bone=142 +Throne of Empires=37 +Throne of Geth=43 +Through the Breach=371 +Thrull Champion=24 Thrull Retainer=25 Thrull Surgeon=25 Thrull Wizard=25 -Thrumming Stone=617 -Thrummingbird=38 -Thrun, the Last Troll=1262 +Thrumming Stone=436 +Thrummingbird=49 +Thrun, the Last Troll=977 Thumbscrews=35 -Thunder Dragon=782 -Thunder Spirit=875 +Thunder Dragon=709 +Thunder Spirit=1018 Thunder Strike=25 Thunder Totem=38 Thunder Wall=25 Thunder of Hooves=25 Thunder-Thrash Elder=25 Thunderblade Charge=25 -Thunderblust=72 -Thunderbolt=40 +Thunderblust=112 +Thunderbolt=38 Thunderclap=39 Thundercloud Elemental=25 -Thundercloud Shaman=25 +Thundercloud Shaman=38 Thunderheads=25 Thundering Giant=25 Thundering Tanadon=16 Thundering Wurm=222 -Thundermare=60 +Thundermare=43 +Thunderous Wrath=102 Thunderscape Apprentice=25 Thunderscape Battlemage=25 Thunderscape Familiar=25 Thunderscape Master=25 Thundersong Trumpeter=40 Thunderstaff=25 -Thwart=25 -Tibor and Lumia=99 +Thwart=81 +Tibalt, the Fiend-Blooded=1254 +Tibor and Lumia=46 Ticking Gnomes=40 Tidal Bore=50 -Tidal Control=15 +Tidal Control=29 Tidal Courier=47 Tidal Flats=201 Tidal Influence=25 @@ -10676,212 +10887,216 @@ Tidal Warrior=25 Tidal Wave=6800 Tide of War=100 Tideforce Elemental=25 -Tidehollow Sculler=55 -Tidehollow Strix=31 +Tidehollow Sculler=62 +Tidehollow Strix=65 Tideshaper Mystic=25 -Tidespout Tyrant=91 +Tidespout Tyrant=38 Tidewalker=25 -Tidewater Minion=46 -Tidings=65 +Tidewater Minion=25 +Tidings=62 Tiger Claws=25 Tigereye Cameo=29 -Tilling Treefolk=37 -Timber Protector=397 -Timber Wolves=220 +Tilling Treefolk=25 +Timber Protector=489 +Timber Wolves=280 Timberland Ruins=25 Timberline Ridge=100 -Timbermare=42 +Timbermare=49 Timbermaw Larva=25 -Timberwatch Elf=68 +Timberwatch Elf=62 Time Bomb=55 -Time Ebb=39 -Time Elemental=63 +Time Ebb=37 +Time Elemental=53 Time Machine=100 -Time Reversal=36 -Time Sieve=112 -Time Stop=101 -Time Stretch=301 -Time Vault=26349 -Time Walk=38280 -Time Warp=338 -Time and Tide=25 +Time Reversal=38 +Time Sieve=195 +Time Stop=107 +Time Stretch=230 +Time Vault=18996 +Time Walk=44259 +Time Warp=311 +Time and Tide=40 Time of Heroes=34 -Time of Need=62 +Time of Need=34 Timebender=25 Timecrafting=26 -Timely Reinforcements=134 -Timesifter=55 -Timetwister=19632 +Timely Reinforcements=117 +Timesifter=47 +Timetwister=20881 Timid Drake=22 Timmerian Fiends=40 -Timmy, Power Gamer=160 +Timmy, Power Gamer=195 Tin Street Hooligan=25 Tin-Wing Chimera=43 Tinder Farm=25 -Tinder Wall=29 +Tinder Wall=37 Tine Shrike=25 -Tinker=387 +Tinker=334 Tireless Missionaries=14 -Tireless Tribe=58 -Titan Forge=43 +Tireless Tribe=25 +Titan Forge=58 Titan's Revenge=25 Titania's Boon=31 -Titania's Chosen=140 -Titania's Song=35 +Titania's Chosen=79 +Titania's Song=15 Titanic Bulvox=27 -Titanic Growth=25 -Titanic Ultimatum=52 +Titanic Growth=22 +Titanic Ultimatum=40 Titanium Golem=25 -Tithe=295 -Tivadar of Thorn=69 -Tivadar's Crusade=75 -To Arms!=8 +Tithe=381 +Tivadar of Thorn=25 +Tivadar's Crusade=127 +To Arms!=25 Tobias Andrion=52 Togglodyte=47 Toil to Renown=29 Toils of Night and Day=25 -Tolaria=89 -Tolaria West=130 -Tolarian Academy=2393 +Tolaria=74 +Tolaria West=122 +Tolarian Academy=2351 Tolarian Drake=40 Tolarian Emissary=16 Tolarian Entrancer=97 Tolarian Sentinel=25 Tolarian Serpent=41 -Tolarian Winds=19 -Tolsimir Wolfblood=126 +Tolarian Winds=21 +Tolsimir Wolfblood=119 Tomb Hex=49 Tomb of Urami=190 Tombfire=99 -Tombstalker=678 -Tombstone Stairwell=86 -Tome Scour=24 -Tomorrow, Azami's Familiar=175 +Tombstalker=701 +Tombstone Stairwell=108 +Tome Scour=28 +Tomorrow, Azami's Familiar=25 Tonic Peddler=25 Tooth and Claw=25 -Tooth and Nail=946 +Tooth and Nail=885 Tooth of Chiss-Goria=40 -Tooth of Ramos=31 +Tooth of Ramos=45 Topan Ascetic=45 Topple=38 Topsy Turvy=100 Tor Giant=25 -Tor Wauki=37 +Tor Wauki=44 Torch Drake=25 Torch Slinger=25 Torch Song=38 -Torchling=52 +Torchling=30 Torii Watchward=25 -Tormented Angel=42 +Tormented Angel=100 Tormented Pariah=35 -Tormented Soul=25 +Tormented Soul=91 Tormentor Exarch=25 -Tormod's Crypt=88 +Tormod's Crypt=87 Tornado=87 -Tornado Elemental=148 +Tornado Elemental=95 Torpid Moloch=25 Torpor Dust=25 -Torpor Orb=62 +Torpor Orb=89 Torrent of Fire=25 Torrent of Lava=49 Torrent of Souls=50 Torrent of Stone=25 -Torsten Von Ursus=49 +Torsten Von Ursus=126 Tortoise Formation=25 Torture=38 Torture Chamber=25 Tortured Existence=37 -Toshiro Umezawa=87 +Toshiro Umezawa=123 Total War=50 Totem Speaker=40 Totem-Guide Hartebeest=45 -Touch and Go=27 +Touch and Go=39 Touch of Brilliance=40 Touch of Darkness=100 Touch of Death=26 Touch of Invisibility=28 Touch of Vitae=11 Touchstone=40 -Tourach's Chant=25 +Tourach's Chant=33 Tourach's Gate=25 Tower Above=25 Tower Drake=7 Tower Gargoyle=45 -Tower of Calamities=48 -Tower of Champions=135 +Tower Geist=25 +Tower of Calamities=37 +Tower of Champions=100 Tower of Coireall=25 -Tower of Eons=71 -Tower of Fortunes=69 +Tower of Eons=50 +Tower of Fortunes=28 Tower of Murmurs=25 -Tower of the Magistrate=745 +Tower of the Magistrate=681 Towering Baloth=47 Town Sentry=25 Toxic Iguanar=25 -Toxic Nim=35 +Toxic Nim=25 Toxic Stench=28 -Toxin Sliver=560 +Toxin Sliver=479 Toy Boat=25 Toymaker=39 -Trace of Abundance=25 -Tracker=12 +Trace of Abundance=62 +Tracker=116 +Tracker's Instincts=34 Trade Caravan=25 -Trade Routes=29 -Trade Secrets=54 -Tradewind Rider=85 +Trade Routes=34 +Trade Secrets=46 +Tradewind Rider=120 Tragic Poet=38 +Tragic Slip=26 Trailblazer=28 -Trailblazer's Boots=35 +Trailblazer's Boots=25 Train of Thought=25 Trained Armodon=30 Trained Cheetah=231 -Trained Jackal=81 +Trained Jackal=99 Trained Orgg=106 Trained Pronghorn=28 Training Drone=25 -Training Grounds=129 +Training Grounds=121 Traitor's Clutch=25 Traitor's Roar=25 -Traitorous Blood=25 +Traitorous Blood=41 Traitorous Instinct=30 -Tranquil Domain=25 +Tranquil Domain=29 Tranquil Garden=25 -Tranquil Grove=50 +Tranquil Grove=68 Tranquil Path=25 Tranquil Thicket=25 -Tranquility=12 -Transcendence=103 -Transcendent Master=342 +Tranquility=13 +Transcendence=25 +Transcendent Master=323 Transguild Courier=56 Transluminant=25 Transmogrifying Licid=52 Transmutation=33 -Transmute Artifact=1355 +Transmute Artifact=1083 Trap Digger=8 Trap Runner=43 Trapfinder's Trick=25 Trapjaw Kelpie=25 Trapmaker's Snare=25 Traproot Kami=25 -Trash for Treasure=38 +Trash for Treasure=33 Traumatic Visions=25 -Traumatize=108 -Travel Preparations=35 -Traveler's Amulet=37 +Traumatize=137 +Travel Preparations=32 +Traveler's Amulet=25 Traveler's Cloak=16 Traveling Plague=39 -Treacherous Link=25 +Treacherous Link=30 +Treacherous Pit-Dweller=62 Treacherous Urge=25 Treacherous Vampire=25 Treacherous Werewolf=25 -Treachery=777 -Treasure Hunt=289 +Treachery=648 +Treasure Hunt=206 Treasure Hunter=49 -Treasure Mage=75 +Treasure Mage=137 Treasure Trove=26 Tree Monkey=22 -Tree of Redemption=96 -Tree of Tales=52 -Treefolk Harbinger=104 +Tree of Redemption=68 +Tree of Tales=58 +Treefolk Harbinger=120 Treefolk Healer=29 Treefolk Mystic=25 Treefolk Seedlings=25 @@ -10889,219 +11104,226 @@ Treespring Lorian=28 Treetop Bracers=29 Treetop Defense=157 Treetop Rangers=16 -Treetop Scout=50 +Treetop Scout=25 Treetop Sentinel=40 -Treetop Village=31 +Treetop Village=36 Tremble=50 Tremor=7 Trench Wurm=45 Trenching Steed=29 -Trepanation Blade=28 +Trepanation Blade=45 Trespasser il-Vec=25 -Trespassing Souleater=17 -Tresserhorn Sinks=100 -Tresserhorn Skyknight=54 -Treva's Attendant=25 +Trespassing Souleater=11 +Tresserhorn Sinks=70 +Tresserhorn Skyknight=25 +Treva's Attendant=149 Treva's Charm=25 -Treva's Ruins=88 -Treva, the Renewer=288 -Triangle of War=30 +Treva's Ruins=67 +Treva, the Renewer=149 +Triangle of War=43 Triassic Egg=37 -Tribal Flames=37 -Tribal Forcemage=33 -Tribal Golem=25 -Tribal Unity=37 -Tribute to Hunger=35 -Trickbind=155 +Tribal Flames=28 +Tribal Forcemage=25 +Tribal Golem=49 +Tribal Unity=25 +Tribute to Hunger=78 +Trickbind=182 Trickery Charm=35 Trickster Mage=40 Triclopean Sight=52 Trigon of Corruption=25 Trigon of Infestation=40 Trigon of Mending=25 -Trigon of Rage=25 +Trigon of Rage=35 Trigon of Thought=25 -Trinisphere=214 -Trinket Mage=38 +Trinisphere=230 +Trinket Mage=27 Trip Noose=25 Trip Wire=75 -Triskelavus=39 -Triskelion=28 -Triumph of the Hordes=25 +Triskelavus=25 +Triskelion=37 +Triumph of Cruelty=17 +Triumph of Ferocity=23 +Triumph of the Hordes=38 Trokin High Guard=30 -Troll Ascetic=115 +Troll Ascetic=139 Troll-Horn Cameo=29 Trollhide=38 Trolls of Tel-Jilad=25 Tromp the Domains=40 Trophy Hunter=12 -Tropical Island=12498 +Tropical Island=10153 Tropical Storm=25 Troubled Healer=28 Troublesome Spirit=79 -Truce=49 -True Believer=156 -True Conviction=58 -Trumpet Blast=22 +Truce=100 +True Believer=59 +True Conviction=50 +Trumpet Blast=40 Trumpeting Armodon=70 Trusted Advisor=25 Trusty Machete=25 Truth or Tale=12 -Trygon Predator=178 -Tsabo Tavoc=117 +Trygon Predator=250 +Tsabo Tavoc=105 Tsabo's Assassin=58 -Tsabo's Decree=79 +Tsabo's Decree=97 Tsabo's Web=31 -Tsunami=42 +Tsunami=38 Tukatongue Thallid=28 -Tuknir Deathlock=199 +Tuknir Deathlock=235 Tuktuk Grunts=25 -Tuktuk Scrapper=25 -Tuktuk the Explorer=100 -Tumble Magnet=42 -Tundra=13251 +Tuktuk Scrapper=30 +Tuktuk the Explorer=88 +Tumble Magnet=32 +Tundra=18517 Tundra Kavu=25 Tundra Wolves=22 Tunnel=155 -Tunnel Ignus=43 -Tunnel Vision=83 +Tunnel Ignus=26 +Tunnel Vision=114 Tunneler Wurm=16 Turbulent Dreams=52 Turf Wound=25 -Turn Aside=27 +Turn Aside=31 Turn the Tables=99 Turn the Tide=16 Turn to Dust=25 -Turn to Frog=35 +Turn to Frog=22 Turn to Mist=25 Turn to Slag=40 -Turnabout=170 +Turnabout=181 Turntimber Basilisk=50 Turntimber Grove=22 -Turntimber Ranger=35 +Turntimber Ranger=28 Turtleshell Changeling=40 -Twiddle=33 +Twiddle=28 Twigwalker=100 -Twilight Drover=170 -Twilight Mire=743 -Twilight Shepherd=185 +Twilight Drover=45 +Twilight Mire=799 +Twilight Shepherd=211 Twilight's Call=62 -Twinblade Slasher=48 -Twincast=146 +Twinblade Slasher=56 +Twincast=180 Twinning Glass=25 Twinstrike=25 Twist Allegiance=25 Twisted Abomination=29 Twisted Experiment=27 Twisted Image=35 -Twisted Justice=25 -Twitch=27 -Two-Headed Dragon=181 -Two-Headed Giant of Foriys=1541 -Two-Headed Sliver=34 -Typhoid Rats=34 -Typhoon=99 -Tyrannize=47 +Twisted Justice=28 +Twitch=30 +Two-Headed Dragon=205 +Two-Headed Giant of Foriys=1344 +Two-Headed Sliver=51 +Typhoid Rats=32 +Typhoon=149 +Tyrannize=70 +Tyrant of Discord=45 Tyrranax=25 Uba Mask=100 Uktabi Drake=25 Uktabi Efreet=37 Uktabi Faerie=25 Uktabi Kong=100 -Uktabi Orangutan=45 +Uktabi Orangutan=34 Uktabi Wildcats=56 -Ulamog's Crusher=30 -Ulamog, the Infinite Gyre=1041 -Ulasht, the Hate Seed=87 +Ulamog's Crusher=49 +Ulamog, the Infinite Gyre=1217 +Ulasht, the Hate Seed=57 +Ulvenwald Bear=25 Ulvenwald Mystics=25 +Ulvenwald Tracker=104 Umara Raptor=42 Umbilicus=100 Umbra Mystic=25 -Umbra Stalker=25 +Umbra Stalker=57 Umbral Mantle=41 -Umezawa's Jitte=1448 -Unbender Tine=37 +Umezawa's Jitte=1526 +Unbender Tine=25 Unblinking Bleb=25 -Unbreathing Horde=49 +Unbreathing Horde=45 Unburden=12 -Unburial Rites=288 +Unburial Rites=146 Unchecked Growth=25 -Uncle Istvan=46 +Uncle Istvan=31 Uncontrollable Anger=25 Uncontrolled Infestation=40 -Undead Alchemist=38 -Undead Gladiator=135 +Undead Alchemist=36 +Undead Gladiator=162 Undead Leotau=47 Undead Slayer=39 -Undead Warchief=429 -Undercity Shade=25 -Underground River=114 -Underground Sea=13584 +Undead Warchief=411 +Undercity Shade=36 +Underground River=112 +Underground Sea=20815 Undergrowth=25 -Undermine=255 +Undermine=196 Undertaker=14 Undertow=100 -Underworld Dreams=188 -Undiscovered Paradise=498 -Undo=39 +Underworld Dreams=130 +Undiscovered Paradise=702 +Undo=10 Undying Beast=42 +Undying Evil=20 Undying Flames=28 Undying Rage=50 -Unearth=70 +Unearth=72 Unearthly Blizzard=25 Unerring Sling=25 Unforge=57 Unfulfilled Desires=36 +Unhallowed Pact=31 Unhinge=25 Unholy Citadel=100 -Unholy Grotto=387 -Unholy Strength=22 +Unholy Grotto=435 +Unholy Strength=23 Unified Strike=29 Unified Will=25 -Unifying Theory=45 +Unifying Theory=36 Unlikely Alliance=25 Unliving Psychopath=99 -Unmake=98 -Unmask=343 +Unmake=102 +Unmask=270 Unnatural Hunger=100 -Unnatural Predation=46 -Unnatural Selection=88 +Unnatural Predation=30 +Unnatural Selection=48 Unnatural Speed=25 Unnerve=26 Unnerving Assault=25 -Unquestioned Authority=39 -Unruly Mob=7 -Unscythe, Killer of Kings=116 +Unquestioned Authority=25 +Unruly Mob=27 +Unscythe, Killer of Kings=49 Unseen Walker=25 Unspeakable Symbol=11 Unstable Footing=25 -Unstable Frontier=25 -Unstable Hulk=25 -Unstable Mutation=37 -Unstable Shapeshifter=31 -Unstoppable Ash=85 -Unsummon=29 -Untaidake, the Cloud Keeper=56 -Untamed Might=40 -Untamed Wilds=36 +Unstable Frontier=30 +Unstable Hulk=20 +Unstable Mutation=36 +Unstable Shapeshifter=81 +Unstoppable Ash=100 +Unsummon=27 +Untaidake, the Cloud Keeper=100 +Untamed Might=30 +Untamed Wilds=15 Unwilling Recruit=25 -Unwinding Clock=68 +Unwinding Clock=73 Unworthy Dead=41 -Unyaro Bees=88 +Unyaro Bees=84 Unyaro Griffin=22 Updraft=7 -Upheaval=125 +Upheaval=178 Uphill Battle=41 Uproot=25 -Upwelling=31 -Ur-Drago=601 -Ur-Golem's Eye=25 -Urabrask the Hidden=250 -Urborg=943 +Upwelling=39 +Ur-Drago=146 +Ur-Golem's Eye=23 +Urabrask the Hidden=280 +Urborg=850 Urborg Drake=25 -Urborg Elf=25 +Urborg Elf=19 Urborg Emissary=25 -Urborg Justice=49 +Urborg Justice=63 Urborg Mindsucker=11 Urborg Panther=25 Urborg Phantom=25 @@ -11110,193 +11332,198 @@ Urborg Skeleton=16 Urborg Stalker=40 Urborg Syphon-Mage=25 Urborg Uprising=28 -Urborg Volcano=38 -Urborg, Tomb of Yawgmoth=1396 -Urge to Feed=57 +Urborg Volcano=14 +Urborg, Tomb of Yawgmoth=1538 +Urge to Feed=95 Urgent Exorcism=37 -Uril, the Miststalker=296 -Ursapine=25 +Uril, the Miststalker=328 +Ursapine=49 Ursine Fylgja=56 -Urza's Armor=22 -Urza's Avenger=113 -Urza's Bauble=35 -Urza's Blueprints=100 +Urza's Armor=45 +Urza's Avenger=82 +Urza's Bauble=33 +Urza's Blueprints=104 Urza's Chalice=33 Urza's Contact Lenses=31 -Urza's Engine=50 -Urza's Factory=197 +Urza's Engine=25 +Urza's Factory=31 Urza's Filter=93 Urza's Guilt=79 Urza's Hot Tub=25 -Urza's Incubator=415 -Urza's Mine=44 -Urza's Miter=199 -Urza's Power Plant=57 -Urza's Rage=123 +Urza's Incubator=555 +Urza's Mine=52 +Urza's Miter=224 +Urza's Power Plant=89 +Urza's Rage=84 Urza's Science Fair Project=31 -Urza's Tower=50 -Uthden Troll=36 -Utopia Mycon=125 -Utopia Sprawl=38 -Utopia Tree=65 -Utopia Vow=28 +Urza's Tower=33 +Uthden Troll=50 +Utopia Mycon=75 +Utopia Sprawl=35 +Utopia Tree=104 +Utopia Vow=25 Utvara Scalper=25 -Uyo, Silent Prophet=44 +Uyo, Silent Prophet=33 Vacuumelt=25 -Vaevictis Asmadi=51 +Vaevictis Asmadi=624 Vagrant Plowbeasts=50 Valakut Fireboar=25 -Valakut, the Molten Pinnacle=77 +Valakut, the Molten Pinnacle=143 Valeron Outlander=24 Valiant Guard=25 Valley Rannet=28 -Valleymaker=25 -Valor=36 +Valleymaker=32 +Valor=25 Valor Made Real=25 -Valorous Charge=29 -Vampire Aristocrat=16 -Vampire Bats=34 -Vampire Hexmage=55 +Valorous Charge=39 +Vampire Aristocrat=60 +Vampire Bats=33 +Vampire Hexmage=61 Vampire Hounds=25 Vampire Interloper=34 -Vampire Lacerator=25 +Vampire Lacerator=31 Vampire Nighthawk=147 -Vampire Nocturnus=1554 -Vampire Outcasts=34 -Vampire's Bite=56 -Vampiric Dragon=245 -Vampiric Embrace=25 +Vampire Nocturnus=1373 +Vampire Outcasts=25 +Vampire's Bite=25 +Vampiric Dragon=301 +Vampiric Embrace=38 Vampiric Feast=74 -Vampiric Fury=37 +Vampiric Fury=34 Vampiric Link=36 -Vampiric Sliver=25 +Vampiric Sliver=60 Vampiric Spirit=193 Vampiric Touch=30 -Vampiric Tutor=1577 +Vampiric Tutor=1614 Vampirism=8 -Vanish into Memory=275 -Vanishing=56 +Vanish into Memory=38 +Vanishing=76 +Vanishment=47 Vanquish=25 -Vapor Snag=45 +Vapor Snag=94 Vapor Snare=25 Vaporous Djinn=25 Varchild's Crusader=100 -Varchild's War-Riders=68 +Varchild's War-Riders=33 Vassal's Duty=10 Vastwood Animist=25 Vastwood Gorger=25 Vastwood Zendikon=25 -Vault Skirge=45 +Vault Skirge=51 Vault Skyward=25 -Vault of Whispers=88 -Vebulid=47 +Vault of Whispers=43 +Vault of the Archangel=190 +Vebulid=58 Vec Townships=50 Vectis Agents=44 Vectis Dominator=25 Vectis Silencers=25 -Vector Asp=25 -Vedalken AEthermage=32 +Vector Asp=46 +Vedalken AEthermage=25 Vedalken Anatomist=45 -Vedalken Archmage=99 +Vedalken Archmage=123 Vedalken Certarch=25 Vedalken Dismisser=25 -Vedalken Engineer=26 +Vedalken Engineer=28 Vedalken Entrancer=12 -Vedalken Ghoul=25 -Vedalken Heretic=92 -Vedalken Infuser=33 +Vedalken Ghoul=50 +Vedalken Heretic=158 +Vedalken Infuser=34 Vedalken Mastermind=21 -Vedalken Orrery=358 -Vedalken Outlander=28 +Vedalken Orrery=399 +Vedalken Outlander=25 Vedalken Plotter=13 -Vedalken Shackles=1337 +Vedalken Shackles=1355 Veil of Birds=40 -Veil of Secrecy=25 +Veil of Secrecy=36 Veiled Apparition=39 Veiled Crocodile=40 Veiled Sentry=105 Veiled Serpent=28 Veiling Oddity=40 -Veilstone Amulet=62 -Vein Drinker=116 -Veinfire Borderpost=25 +Veilstone Amulet=25 +Vein Drinker=97 +Veinfire Borderpost=35 Veldrane of Sengir=100 Veldt=35 Venarian Glimmer=25 Venarian Gold=25 Vendetta=25 -Vendilion Clique=2534 +Vendilion Clique=2412 Venerable Kumo=25 -Venerable Monk=28 -Venerated Teacher=36 +Venerable Monk=27 +Venerated Teacher=31 Vengeance=43 -Vengeful Archon=69 -Vengeful Dead=67 +Vengeful Archon=31 +Vengeful Dead=28 Vengeful Dreams=149 Vengeful Firebrand=50 -Vengeful Pharaoh=79 +Vengeful Pharaoh=45 Vengeful Rebirth=37 -Vengevine=853 -Venom=79 +Vengeful Vampire=20 +Vengevine=843 +Venom=141 Venomous Breath=14 Venomous Dragonfly=25 Venomous Fangs=39 Venomous Vines=28 Venomspout Brackus=25 Venser's Diffusion=25 -Venser's Journal=105 +Venser's Journal=100 Venser's Sliver=25 -Venser, Shaper Savant=410 -Venser, the Sojourner=765 +Venser, Shaper Savant=509 +Venser, the Sojourner=579 Vent Sentinel=35 Ventifact Bottle=10 -Verdant Catacombs=860 +Verdant Catacombs=803 Verdant Eidolon=25 -Verdant Embrace=31 +Verdant Embrace=66 Verdant Field=12 -Verdant Force=114 -Verdant Succession=61 +Verdant Force=143 +Verdant Succession=58 Verdant Touch=46 -Verdeloth the Ancient=68 +Verdeloth the Ancient=75 Verdigris=104 Verduran Emissary=399 -Verduran Enchantress=267 +Verduran Enchantress=269 Vermiculos=25 -Vernal Bloom=57 +Vernal Bloom=41 Vernal Equinox=49 Vertigo=25 -Vertigo Spawn=25 -Vesper Ghoul=25 -Vesuva=818 -Vesuvan Doppelganger=1050 -Vesuvan Shapeshifter=90 +Vertigo Spawn=30 +Vesper Ghoul=88 +Vessel of Endless Rest=60 +Vesuva=759 +Vesuvan Doppelganger=438 +Vesuvan Shapeshifter=137 Veteran Armorer=42 Veteran Armorsmith=25 -Veteran Bodyguard=314 -Veteran Brawlers=74 +Veteran Bodyguard=311 +Veteran Brawlers=44 Veteran Cavalier=39 -Veteran Explorer=89 +Veteran Explorer=155 Veteran Swordsmith=25 Veteran of the Depths=25 Veteran's Armaments=25 Veteran's Reflexes=25 Veteran's Voice=25 Vex=25 -Vexing Arcanix=32 +Vexing Arcanix=35 Vexing Beetle=37 -Vexing Shusher=220 -Vexing Sphinx=61 -Vhati il-Dal=73 +Vexing Devil=1127 +Vexing Shusher=239 +Vexing Sphinx=145 +Vhati il-Dal=75 Viashino Bey=28 Viashino Bladescout=28 -Viashino Cutthroat=31 +Viashino Cutthroat=41 Viashino Fangtail=25 Viashino Grappler=25 -Viashino Heretic=20 +Viashino Heretic=83 Viashino Outrider=16 Viashino Runner=9 Viashino Sandscout=26 -Viashino Sandstalker=33 +Viashino Sandstalker=37 Viashino Sandswimmer=45 Viashino Skeleton=25 Viashino Slasher=25 @@ -11304,73 +11531,74 @@ Viashino Slaughtermaster=25 Viashino Spearhunter=25 Viashino Warrior=26 Viashino Weaponsmith=16 -Viashivan Dragon=100 +Viashivan Dragon=138 Vibrating Sphere=50 Vicious Betrayal=25 Vicious Hunger=35 -Vicious Kavu=11 -Vicious Shadows=165 -Victim of Night=32 -Victimize=66 +Vicious Kavu=25 +Vicious Shadows=94 +Victim of Night=22 +Victimize=114 Victorious Destruction=50 -Victory's Herald=44 -Victual Sliver=37 +Victory's Herald=50 +Victual Sliver=31 View from Above=25 Vigean Graftmage=25 -Vigean Hydropon=29 +Vigean Hydropon=31 Vigean Intuition=25 Vigil for the Lost=37 -Vigilance=25 +Vigilance=31 Vigilant Drake=27 Vigilant Martyr=27 Vigilant Sentry=28 -Vigor=483 +Vigor=562 Vigor Mortis=25 Vigorous Charge=28 Vile Bile=25 -Vile Consumption=68 +Vile Consumption=79 Vile Deacon=16 Vile Requiem=25 -Village Bell-Ringer=12 -Village Cannibals=34 -Village Elder=25 +Village Bell-Ringer=27 +Village Cannibals=32 +Village Elder=29 Village Ironsmith=8 -Villagers of Estwald=63 +Village Survivors=25 +Villagers of Estwald=34 Villainous Ogre=25 -Vindicate=2140 +Vindicate=2025 Vindictive Mob=99 -Vine Dryad=200 +Vine Dryad=28 Vine Kami=25 -Vine Trellis=25 -Vinelasher Kudzu=75 -Vines of Vastwood=35 +Vine Trellis=22 +Vinelasher Kudzu=112 +Vines of Vastwood=55 Vintara Elephant=28 Vintara Snapper=25 -Violent Eruption=58 +Violent Eruption=37 Violent Outburst=25 -Violent Ultimatum=80 +Violent Ultimatum=71 Violet Pall=25 -Viral Drake=35 +Viral Drake=25 Viridescent Wisps=25 Viridian Acolyte=25 -Viridian Betrayers=12 +Viridian Betrayers=11 Viridian Claw=25 -Viridian Corrupter=34 -Viridian Emissary=113 +Viridian Corrupter=48 +Viridian Emissary=62 Viridian Harvest=20 Viridian Joiner=42 Viridian Longbow=100 Viridian Lorebearers=17 -Viridian Revel=25 +Viridian Revel=35 Viridian Scout=25 -Viridian Shaman=26 -Viridian Zealot=125 -Virtue's Ruin=770 +Viridian Shaman=37 +Viridian Zealot=170 +Virtue's Ruin=676 Virtuous Charge=50 -Virulent Sliver=39 -Virulent Swipe=25 -Virulent Wound=42 -Visara the Dreadful=324 +Virulent Sliver=25 +Virulent Swipe=26 +Virulent Wound=38 +Visara the Dreadful=351 Viscera Dragger=25 Viscera Seer=50 Viscerid Armor=25 @@ -11378,27 +11606,27 @@ Viscerid Deepwalker=25 Viscerid Drone=25 Viscid Lemures=25 Viseling=12 -Vision Charm=25 +Vision Charm=108 Vision Skeins=8 -Visions of Beyond=92 -Vital Splicer=42 +Visions of Beyond=54 +Vital Splicer=45 Vital Surge=25 Vitality Charm=38 Vitalize=25 Vitalizing Cascade=16 -Vitalizing Wind=99 -Vitaspore Thallid=25 +Vitalizing Wind=83 +Vitaspore Thallid=83 Vithian Renegades=26 Vithian Stinger=45 Vitu-Ghazi, the City-Tree=25 -Vivid Crag=37 -Vivid Creek=51 -Vivid Grove=55 -Vivid Marsh=58 -Vivid Meadow=50 +Vivid Crag=138 +Vivid Creek=99 +Vivid Grove=90 +Vivid Marsh=94 +Vivid Meadow=36 Vivify=25 Vivisection=25 -Vizzerdrix=49 +Vizzerdrix=46 Vodalian Hypnotist=12 Vodalian Illusionist=28 Vodalian Knights=76 @@ -11409,144 +11637,147 @@ Vodalian Serpent=28 Vodalian Soldiers=25 Vodalian War Machine=28 Vodalian Zombie=25 -Voice of All=57 -Voice of Duty=42 -Voice of Grace=35 -Voice of Law=39 -Voice of Reason=44 +Voice of All=52 +Voice of Duty=52 +Voice of Grace=31 +Voice of Law=107 +Voice of Reason=52 Voice of Truth=25 -Voice of the Woods=113 -Voiceless Spirit=12 +Voice of the Provinces=25 +Voice of the Woods=114 +Voiceless Spirit=32 Voices from the Void=27 -Void=89 +Void=45 Void Maw=28 -Voidmage Apprentice=36 -Voidmage Husher=37 -Voidmage Prodigy=53 -Voidslime=321 -Voidstone Gargoyle=50 +Voidmage Apprentice=25 +Voidmage Husher=25 +Voidmage Prodigy=83 +Voidslime=368 +Voidstone Gargoyle=39 Volcanic Awakening=25 -Volcanic Dragon=152 -Volcanic Eruption=213 -Volcanic Fallout=120 +Volcanic Dragon=75 +Volcanic Eruption=215 +Volcanic Fallout=113 Volcanic Geyser=28 -Volcanic Hammer=37 -Volcanic Island=11912 +Volcanic Hammer=20 +Volcanic Island=10107 Volcanic Spray=25 Volcanic Strength=28 Volcanic Submersion=25 Volcanic Wind=25 -Volcano Hellion=25 +Volcano Hellion=71 Volcano Imp=28 -Volition Reins=30 +Volition Reins=34 Volley of Boulders=25 -Volrath's Curse=25 -Volrath's Dungeon=29 -Volrath's Gardens=38 -Volrath's Laboratory=71 +Volrath's Curse=40 +Volrath's Dungeon=33 +Volrath's Gardens=22 +Volrath's Laboratory=50 Volrath's Motion Sensor=31 -Volrath's Shapeshifter=81 -Volrath's Stronghold=1450 -Volt Charge=36 +Volrath's Shapeshifter=63 +Volrath's Stronghold=1438 +Volt Charge=34 Voltaic Construct=34 -Voltaic Key=144 -Volunteer Militia=50 +Voltaic Key=59 +Volunteer Militia=58 Volunteer Reserves=25 Voodoo Doll=43 Voracious Cobra=25 -Voracious Dragon=37 -Voracious Hatchling=58 -Vorinclex, Voice of Hunger=256 -Vorosh, the Hunter=108 +Voracious Dragon=86 +Voracious Hatchling=39 +Vorapede=346 +Vorinclex, Voice of Hunger=252 +Vorosh, the Hunter=57 Vorrac Battlehorns=40 Votary of the Conclave=25 Voyager Drake=25 -Voyager Staff=41 +Voyager Staff=25 Vug Lizard=40 -Vulshok Battlegear=24 +Vulshok Battlegear=25 Vulshok Battlemaster=99 Vulshok Berserker=22 -Vulshok Gauntlets=25 +Vulshok Gauntlets=12 Vulshok Heartstoker=25 Vulshok Morningstar=22 -Vulshok Refugee=30 -Vulshok Replica=12 -Vulshok Sorcerer=40 +Vulshok Refugee=25 +Vulshok Replica=34 +Vulshok Sorcerer=39 Vulshok War Boar=25 -Vulturous Zombie=86 +Vulturous Zombie=74 Wail of the Nim=25 -Waiting in the Weeds=52 -Wake Thrasher=277 -Wake of Destruction=46 +Waiting in the Weeds=65 +Wake Thrasher=163 +Wake of Destruction=98 Wake of Vultures=14 -Wakestone Gargoyle=100 +Wakedancer=9 +Wakestone Gargoyle=46 Waking Nightmare=25 -Walk the Aeons=143 -Walker of Secret Ways=51 +Walk the Aeons=78 +Walker of Secret Ways=26 Walker of the Grove=40 Walking Archive=58 -Walking Atlas=25 -Walking Corpse=22 -Walking Dead=29 +Walking Atlas=37 +Walking Corpse=26 +Walking Dead=25 Walking Desecration=25 Walking Dream=25 Walking Sponge=16 Walking Wall=17 -Wall of Air=37 +Wall of Air=35 Wall of Blood=25 -Wall of Blossoms=111 -Wall of Bone=33 -Wall of Brambles=24 +Wall of Blossoms=124 +Wall of Bone=37 +Wall of Brambles=22 Wall of Caltrops=29 Wall of Corpses=25 Wall of Deceit=25 -Wall of Denial=115 +Wall of Denial=112 Wall of Diffusion=40 Wall of Distortion=25 Wall of Dust=37 Wall of Earth=99 -Wall of Essence=46 +Wall of Essence=56 Wall of Faith=25 Wall of Fire=23 -Wall of Frost=17 -Wall of Glare=48 -Wall of Granite=40 -Wall of Heat=23 -Wall of Hope=39 -Wall of Ice=44 +Wall of Frost=18 +Wall of Glare=78 +Wall of Granite=39 +Wall of Heat=25 +Wall of Hope=44 +Wall of Ice=47 Wall of Junk=17 Wall of Kelp=124 Wall of Lava=11 Wall of Light=33 Wall of Mulch=25 -Wall of Nets=79 -Wall of Omens=63 +Wall of Nets=64 +Wall of Omens=58 Wall of Opposition=23 Wall of Pine Needles=21 Wall of Putrid Flesh=63 Wall of Razors=50 Wall of Resistance=25 -Wall of Reverence=220 -Wall of Roots=37 -Wall of Shadows=37 +Wall of Reverence=287 +Wall of Roots=84 +Wall of Shadows=34 Wall of Shards=25 Wall of Shields=11 -Wall of Souls=71 +Wall of Souls=135 Wall of Spears=21 -Wall of Stone=39 +Wall of Stone=38 Wall of Swords=34 -Wall of Tanglecord=38 -Wall of Tears=22 +Wall of Tanglecord=25 +Wall of Tears=75 Wall of Tombstones=48 Wall of Vapor=7 Wall of Vines=15 Wall of Vipers=27 -Wall of Water=36 +Wall of Water=35 Wall of Wonder=37 -Wall of Wood=24 +Wall of Wood=23 Wallop=25 -Wand of Denial=55 -Wand of Ith=100 +Wand of Denial=53 +Wand of Ith=99 Wand of the Elements=31 Wanderbrine Rootcutters=49 Wanderer's Twig=24 @@ -11557,133 +11788,135 @@ Wandering Graybeard=45 Wandering Mage=48 Wandering Ones=11 Wandering Stream=38 -Wanderlust=70 -Wanderwine Hub=131 -Wanderwine Prophets=85 +Wandering Wolf=25 +Wanderlust=72 +Wanderwine Hub=137 +Wanderwine Prophets=64 Waning Wurm=50 War Barge=24 War Cadence=50 War Chariot=25 War Dance=38 -War Elemental=77 -War Elephant=126 +War Elemental=80 +War Elephant=86 War Mammoth=28 -War Priest of Thune=49 -War Report=12 -War Tax=52 -War's Toll=62 -War-Spike Changeling=25 -War-Torch Goblin=25 +War Priest of Thune=58 +War Report=30 +War Tax=38 +War's Toll=82 +War-Spike Changeling=40 +War-Torch Goblin=35 Warbreak Trumpeter=56 -Ward Sliver=103 -Ward of Bones=46 +Ward Sliver=95 +Ward of Bones=89 Ward of Lights=100 Ward of Piety=25 -Wargate=150 +Warden of the Wall=28 +Wargate=103 Warlord's Axe=25 Warmonger=100 -Warmonger's Chariot=37 -Warmth=61 +Warmonger's Chariot=25 +Warmth=36 Warning=680 -Warp Artifact=130 -Warp World=44 +Warp Artifact=172 +Warp World=41 Warpath=25 -Warpath Ghoul=37 -Warped Devotion=45 +Warpath Ghoul=25 +Warped Devotion=44 Warped Researcher=16 Warping Wurm=55 -Warren Instigator=205 +Warren Instigator=243 Warren Pilferers=25 -Warren Weirding=30 +Warren Weirding=25 Warren-Scourge Elf=121 -Warrior Angel=100 +Warrior Angel=78 Warrior en-Kor=50 Warrior's Charge=29 Warrior's Honor=27 -Warrior's Oath=4000 -Warrior's Stand=77 -Warstorm Surge=38 +Warrior's Oath=1932 +Warrior's Stand=56 +Warstorm Surge=26 Warthog=16 -Wash Out=95 +Wash Out=96 Wasp Lancer=37 Waste Away=26 -Wasteland=3518 +Wasteland=3575 Watchdog=25 Watcher Sliver=25 Watchwing Scarecrow=35 -Watchwolf=84 -Water Elemental=35 -Water Gun Balloon Game=102 +Watchwolf=74 +Water Elemental=36 +Water Gun Balloon Game=74 Water Servant=25 Water Wurm=31 -Waterfront Bouncer=40 +Waterfront Bouncer=100 Waterspout Djinn=14 Waterspout Elemental=99 Waterspout Weavers=29 -Waterveil Cavern=62 -Watery Grave=1744 +Waterveil Cavern=25 +Watery Grave=1522 Wave Elemental=25 Wave of Indifference=25 -Wave of Reckoning=25 +Wave of Reckoning=99 Wave of Terror=79 -Waves of Aggression=38 +Waves of Aggression=125 Waveskimmer Aven=25 Wax/Wane=32 Waxmane Baku=24 -Wayfarer's Bauble=37 +Wayfarer's Bauble=40 Wayfaring Giant=25 Waylay=52 -Wayward Angel=113 +Wayward Angel=44 Wayward Soul=28 -Weakness=41 +Weakness=33 Weakstone=24 Wear Away=42 Weathered Bodyguards=25 -Weathered Wayfarer=335 -Weatherseed Elf=31 +Weathered Wayfarer=338 +Weatherseed Elf=43 Weatherseed Faeries=44 Weatherseed Totem=34 -Weatherseed Treefolk=72 +Weatherseed Treefolk=122 Weaver of Lies=27 -Web=65 +Web=186 Web of Inertia=79 -Wee Dragonauts=26 +Wee Dragonauts=28 Weed Strangle=25 -Weed-Pruner Poplar=28 -Wei Ambush Force=50 -Wei Assassins=400 -Wei Elite Companions=258 +Weed-Pruner Poplar=38 +Wei Ambush Force=99 +Wei Assassins=399 +Wei Elite Companions=99 Wei Infantry=50 -Wei Night Raiders=712 +Wei Night Raiders=650 Wei Scout=50 -Wei Strike Force=100 +Wei Strike Force=99 Weight of Conscience=25 Weight of Spires=25 -Weird Harvest=30 +Weird Harvest=88 Weirding Shaman=25 -Welding Jar=45 +Welding Jar=25 Welkin Guide=25 Welkin Hawk=52 Welkin Tern=11 Well of Discovery=25 -Well of Knowledge=69 -Well of Life=50 -Well of Lost Dreams=174 +Well of Knowledge=177 +Well of Life=39 +Well of Lost Dreams=154 Well-Laid Plans=100 Wellgabber Apothecary=25 Wellspring=62 -Wellwisher=88 -Werebear=31 -Western Paladin=63 +Wellwisher=94 +Werebear=39 +Western Paladin=31 Wet Willie of the Damned=40 Whalebone Glider=25 -Wheel and Deal=71 -Wheel of Fate=94 -Wheel of Fortune=1501 -Wheel of Sun and Moon=247 -Wheel of Torture=25 -When Fluffy Bunnies Attack=32 -Where Ancients Tread=45 +Wheel and Deal=154 +Wheel of Fate=41 +Wheel of Fortune=1515 +Wheel of Sun and Moon=301 +Wheel of Torture=92 +When Fluffy Bunnies Attack=75 +Where Ancients Tread=50 Whetstone=49 Whetwheel=25 Whim of Volrath=62 @@ -11692,382 +11925,390 @@ Whip Sergeant=22 Whip Silk=40 Whip Vine=25 Whip-Spine Drake=25 -Whipcorder=54 -Whipflare=58 +Whipcorder=50 +Whipflare=66 Whipgrass Entangler=100 Whipkeeper=29 Whiplash Trap=25 Whippoorwill=47 Whipstitched Zombie=29 Whiptail Moloch=25 -Whiptail Wurm=50 +Whiptail Wurm=59 Whiptongue Frog=52 Whirling Catapult=31 -Whirling Dervish=12 +Whirling Dervish=69 Whirlpool Drake=25 Whirlpool Rider=28 Whirlpool Warrior=25 Whirlpool Whelm=25 -Whirlwind=69 +Whirlwind=62 Whispering Shade=25 -Whispering Specter=32 -Whispers of the Muse=27 -Whispersilk Cloak=43 -White Knight=24 -White Mana Battery=42 +Whispering Specter=28 +Whispers of the Muse=42 +Whispersilk Cloak=24 +White Knight=29 +White Mana Battery=101 White Scarab=38 -White Shield Crusader=44 -White Sun's Zenith=66 -White Ward=54 +White Shield Crusader=25 +White Sun's Zenith=64 +White Ward=34 Whitemane Lion=25 Whiteout=799 -Whitesun's Passage=35 -Who/What/When/Where/Why=113 +Whitesun's Passage=30 +Who/What/When/Where/Why=127 Wicked Akuba=40 Wicked Pact=103 Wicked Reward=38 Wicker Warcrawler=40 -Wickerbough Elder=40 -Wielding the Green Dragon=50 +Wickerbough Elder=34 +Wielding the Green Dragon=99 Wiitigo=100 Wild Aesthir=29 Wild Cantor=25 Wild Colos=25 +Wild Defiance=63 Wild Dogs=25 Wild Elephant=28 Wild Evocation=25 -Wild Griffin=43 -Wild Growth=47 +Wild Griffin=41 +Wild Growth=27 Wild Jhovall=28 Wild Leotau=25 Wild Mammoth=599 Wild Might=25 -Wild Mongrel=61 -Wild Nacatl=38 +Wild Mongrel=45 +Wild Nacatl=47 Wild Ox=38 -Wild Pair=109 +Wild Pair=125 Wild Research=37 -Wild Ricochet=45 +Wild Ricochet=97 Wild Swing=25 Wild Wurm=25 -Wilderness Elemental=25 +Wilderness Elemental=19 Wilderness Hypnotist=25 -Wildfield Borderpost=25 -Wildfire=114 +Wildfield Borderpost=28 +Wildfire=49 Wildfire Emissary=22 Wildheart Invoker=25 Wildsize=103 Wildslayer Elves=25 -Will-O'-The-Wisp=393 -Will-o'-the-Wisp=202 -Willbender=29 +Will-O'-The-Wisp=477 +Will-o'-the-Wisp=710 +Willbender=26 Willow Dryad=40 Willow Elf=35 Willow Faerie=25 Willow Priestess=70 -Willow Satyr=1265 -Wilt-Leaf Cavaliers=64 -Wilt-Leaf Liege=434 +Willow Satyr=1014 +Wilt-Leaf Cavaliers=90 +Wilt-Leaf Liege=554 Wind Dancer=25 Wind Drake=20 Wind Sail=29 Wind Shear=40 Wind Spirit=25 -Wind Zendikon=44 -Windborn Muse=49 +Wind Zendikon=28 +Windborn Muse=81 Windborne Charge=25 -Windbrisk Heights=279 +Windbrisk Heights=414 Windbrisk Raptor=35 -Windfall=44 -Winding Canyons=396 +Windfall=50 +Winding Canyons=430 Winding Wurm=16 -Windreaper Falcon=41 -Windreaver=2600 +Windreaper Falcon=15 +Windreaver=74 Windrider Eel=25 -Winds of Change=58 -Winds of Rath=155 +Winds of Change=83 +Winds of Rath=171 Windscouter=27 Windseeker Centaur=99 -Windstorm=40 -Windswept Heath=2707 +Windstorm=58 +Windswept Heath=2877 Windwright Mage=45 Wine of Blood and Iron=25 Wing Puncture=25 -Wing Shards=25 +Wing Shards=45 Wing Snare=29 -Wing Splicer=40 +Wing Splicer=41 Wing Storm=25 Wingbeat Warrior=28 -Winged Coatl=43 -Winged Sliver=92 +Wingcrafter=30 +Winged Coatl=119 +Winged Sliver=63 Wingrattle Scarecrow=35 Wings of Aesthir=31 Wings of Hope=16 Wings of Velis Vel=42 Winnow=25 Winnower Patrol=25 -Winter Blast=141 -Winter Orb=342 +Winter Blast=146 +Winter Orb=274 Winter Sky=50 Winter's Chill=103 -Winter's Grasp=59 +Winter's Grasp=35 Winter's Night=74 -Wintermoon Mesa=71 -Wipe Away=37 +Wintermoon Mesa=45 +Wipe Away=100 Wipe Clean=49 Wirecat=56 Wirefly Hive=40 -Wirewood Channeler=82 -Wirewood Elf=20 +Wirewood Channeler=39 +Wirewood Elf=10 Wirewood Guardian=29 -Wirewood Herald=32 -Wirewood Hivemaster=55 -Wirewood Lodge=140 +Wirewood Herald=42 +Wirewood Hivemaster=50 +Wirewood Lodge=183 Wirewood Pride=25 Wirewood Savage=40 -Wirewood Symbiote=140 +Wirewood Symbiote=123 Wishmonger=49 Wispmare=25 Wistful Selkie=24 -Wistful Thinking=44 +Wistful Thinking=25 Wit's End=12 Witch Engine=38 -Witch Hunter=60 -Witch's Mist=37 -Witch-Maw Nephilim=56 -Witchbane Orb=34 -Withdraw=25 -Withered Wretch=21 +Witch Hunter=34 +Witch's Mist=50 +Witch-Maw Nephilim=45 +Witchbane Orb=42 +Withdraw=46 +Withered Wretch=28 Withering Boon=40 Withering Gaze=27 Withering Hex=25 Withering Wisps=25 -Witherscale Wurm=49 +Witherscale Wurm=55 Withstand=25 -Withstand Death=25 +Withstand Death=34 Wizard Mentor=37 Wizard Replica=33 -Wizards' School=49 -Wizened Cenn=31 +Wizards' School=19 +Wizened Cenn=43 Wizened Snitches=25 -Woebearer=25 -Woebringer Demon=35 +Woebearer=28 +Woebringer Demon=100 Woeleecher=25 Wojek Apothecary=25 -Wojek Embermage=49 +Wojek Embermage=35 Wojek Siren=25 -Wolf Pack=38 -Wolf-Skull Shaman=50 -Wolfbriar Elemental=65 -Wonder=47 -Wood Elemental=249 -Wood Elves=66 +Wolf Pack=20 +Wolf-Skull Shaman=62 +Wolfbitten Captive=58 +Wolfbriar Elemental=91 +Wolfhunter's Quiver=17 +Wolfir Avenger=64 +Wolfir Silverheart=435 +Wonder=43 +Wood Elemental=307 +Wood Elves=73 Wood Sage=25 Woodcloaker=129 -Wooded Bastion=351 -Wooded Foothills=1907 -Wooden Sphere=98 +Wooded Bastion=393 +Wooded Foothills=2009 +Wooden Sphere=101 Wooden Stake=37 -Woodfall Primus=822 -Woodland Cemetery=359 +Woodfall Primus=681 +Woodland Cemetery=376 Woodland Changeling=25 Woodland Druid=28 Woodland Guidance=25 Woodland Sleuth=47 Woodlurker Mimic=34 Woodripper=41 -Woodwraith Corrupter=25 +Woodwraith Corrupter=100 Woodwraith Strangler=25 Woolly Mammoths=30 -Woolly Razorback=62 +Woolly Razorback=39 Woolly Spider=40 -Woolly Thoctar=46 +Woolly Thoctar=33 Word of Binding=13 Word of Blasting=14 -Word of Command=3781 -Word of Seizing=61 +Word of Command=3651 +Word of Seizing=25 Word of Undoing=25 -Wordmail=25 -Words of War=23 -Words of Waste=97 +Wordmail=50 +Words of War=25 +Words of Waste=74 Words of Wilding=25 Words of Wind=25 Words of Wisdom=31 -Words of Worship=66 -Workhorse=50 +Words of Worship=68 +Workhorse=49 Working Stiff=25 -World Queller=32 -World at War=50 -World-Bottling Kit=94 -Worldgorger Dragon=131 +World Queller=38 +World at War=25 +World-Bottling Kit=100 +Worldgorger Dragon=162 Worldheart Phoenix=25 Worldly Counsel=163 -Worldly Tutor=280 -Worldpurge=62 -Worldslayer=29 -Worm Harvest=68 +Worldly Tutor=346 +Worldpurge=32 +Worldslayer=42 +Worm Harvest=50 Wormfang Behemoth=32 Wormfang Crab=25 Wormfang Drake=25 Wormfang Manta=45 Wormfang Newt=28 Wormfang Turtle=25 -Worms of the Earth=40 +Worms of the Earth=111 Wormwood Dryad=25 Wormwood Treefolk=50 -Worn Powerstone=124 +Worn Powerstone=87 Worry Beads=32 -Worship=147 -Wort, Boggart Auntie=152 -Wort, the Raidmother=56 -Worthy Cause=44 -Wound Reflection=88 +Worship=180 +Wort, Boggart Auntie=102 +Wort, the Raidmother=175 +Worthy Cause=42 +Wound Reflection=99 Wrap in Flames=25 Wrap in Vigor=25 -Wrath of God=732 +Wrath of God=688 Wrath of Marit Lage=45 Wreak Havoc=25 -Wreath of Geists=48 -Wrecking Ball=26 -Wren's Run Packmaster=199 -Wren's Run Vanquisher=114 -Wrench Mind=40 +Wreath of Geists=32 +Wrecking Ball=42 +Wren's Run Packmaster=196 +Wren's Run Vanquisher=123 +Wrench Mind=32 Wretched Anurid=49 Wretched Banquet=50 -Wrexial, the Risen Deep=103 +Wrexial, the Risen Deep=66 Wring Flesh=38 Writ of Passage=25 -Wu Admiral=148 -Wu Elite Cavalry=25 +Wu Admiral=99 +Wu Elite Cavalry=44 Wu Infantry=50 -Wu Light Cavalry=50 -Wu Longbowman=155 -Wu Scout=51 -Wu Spy=450 -Wu Warship=50 -Wurm Token=193 -Wurm's Tooth=35 -Wurmcalling=45 -Wurmcoil Engine=1305 +Wu Light Cavalry=99 +Wu Longbowman=99 +Wu Scout=99 +Wu Spy=1215 +Wu Warship=99 +Wurm Token=186 +Wurm's Tooth=34 +Wurmcalling=35 +Wurmcoil Engine=1088 Wurmskin Forger=29 Wurmweaver Coil=49 -Wydwen, the Biting Gale=49 -Wyluli Wolf=64 +Wydwen, the Biting Gale=61 +Wyluli Wolf=55 Xanthic Statue=45 -Xantid Swarm=241 -Xathrid Demon=116 +Xantid Swarm=225 +Xathrid Demon=159 Xenic Poltergeist=37 -Xenograft=34 +Xenograft=30 Xiahou Dun, the One-Eyed=10528 -Xira Arien=204 -Xun Yu, Wei Advisor=376 +Xira Arien=344 +Xun Yu, Wei Advisor=799 Yamabushi's Flame=25 Yamabushi's Storm=25 Yare=99 -Yavimaya Ancients=41 -Yavimaya Ants=57 +Yavimaya Ancients=40 +Yavimaya Ants=64 Yavimaya Barbarian=16 -Yavimaya Coast=189 +Yavimaya Coast=161 Yavimaya Dryad=33 -Yavimaya Elder=38 -Yavimaya Enchantress=26 +Yavimaya Elder=35 +Yavimaya Enchantress=22 Yavimaya Gnats=11 Yavimaya Granger=25 -Yavimaya Hollow=465 -Yavimaya Kavu=40 +Yavimaya Hollow=551 +Yavimaya Kavu=25 Yavimaya Scion=25 Yavimaya Wurm=25 -Yavimaya's Embrace=20 -Yawgmoth Demon=91 +Yavimaya's Embrace=72 +Yawgmoth Demon=112 Yawgmoth's Agenda=23 -Yawgmoth's Bargain=105 +Yawgmoth's Bargain=162 Yawgmoth's Edict=22 -Yawgmoth's Will=1356 +Yawgmoth's Will=1172 Yawning Fissure=25 -Ydwen Efreet=566 +Ydwen Efreet=749 Yellow Scarves Cavalry=50 -Yellow Scarves General=230 -Yellow Scarves Troops=64 +Yellow Scarves General=498 +Yellow Scarves Troops=40 Yet Another AEther Vortex=100 -Yixlid Jailer=42 +Yixlid Jailer=25 Yoke of the Damned=102 Yoked Plowbeast=25 -Yomiji, Who Bars the Way=52 -Yore-Tiller Nephilim=100 -Yosei, the Morning Star=550 -Yotian Soldier=13 -Young Wei Recruits=50 +Yomiji, Who Bars the Way=51 +Yore-Tiller Nephilim=97 +Yosei, the Morning Star=571 +Yotian Soldier=7 +Young Wei Recruits=99 +Young Wolf=28 Youthful Knight=23 Yuan Shao's Infantry=50 Yuan Shao, the Indecisive=710 -Yuki-Onna=41 -Yukora, the Prisoner=79 +Yuki-Onna=25 +Yukora, the Prisoner=104 Zanam Djinn=25 Zap=25 Zealot il-Vec=25 Zealots en-Dal=25 +Zealous Conscripts=224 Zealous Guardian=25 Zealous Inquisitor=25 -Zealous Persecution=27 +Zealous Persecution=81 Zebra Unicorn=10 Zektar Shrine Expedition=25 Zelyon Sword=40 Zendikar Farguide=25 -Zephid=39 -Zephid's Embrace=41 +Zephid=58 +Zephid's Embrace=32 Zephyr Falcon=23 Zephyr Net=25 Zephyr Spirit=25 Zephyr Sprite=25 Zerapa Minotaur=29 -Zhalfirin Commander=8 +Zhalfirin Commander=9 Zhalfirin Crusader=99 Zhalfirin Knight=11 -Zhang Fei, Fierce Warrior=3800 -Zhang He, Wei General=1148 -Zhang Liao, Hero of Hefei=550 -Zhao Zilong, Tiger General=609 +Zhang Fei, Fierce Warrior=1550 +Zhang He, Wei General=950 +Zhang Liao, Hero of Hefei=799 +Zhao Zilong, Tiger General=1258 Zhou Yu, Chief Commander=850 -Zhuge Jin, Wu Strategist=1271 -Zirilan of the Claw=231 +Zhuge Jin, Wu Strategist=500 +Zirilan of the Claw=310 Zo-Zu the Punisher=33 -Zodiac Dog=121 -Zodiac Dragon=20499 -Zodiac Goat=104 +Zodiac Dog=109 +Zodiac Dragon=12750 +Zodiac Goat=50 Zodiac Horse=400 -Zodiac Monkey=27 +Zodiac Monkey=39 Zodiac Ox=520 Zodiac Pig=100 -Zodiac Rabbit=50 -Zodiac Rat=236 -Zodiac Rooster=300 -Zodiac Snake=80 -Zodiac Tiger=351 -Zoetic Cavern=26 +Zodiac Rabbit=101 +Zodiac Rat=69 +Zodiac Rooster=99 +Zodiac Snake=199 +Zodiac Tiger=928 +Zoetic Cavern=25 Zof Shade=25 -Zombie Assassin=26 +Zombie Apocalypse=63 +Zombie Assassin=100 Zombie Boa=25 -Zombie Brute=55 +Zombie Brute=25 Zombie Cannibal=75 Zombie Cutthroat=12 Zombie Fanboy=16 Zombie Goliath=14 -Zombie Infestation=54 -Zombie Master=582 +Zombie Infestation=31 +Zombie Master=447 Zombie Mob=25 Zombie Musher=40 -Zombie Outlander=38 +Zombie Outlander=25 Zombie Scavengers=28 -Zombie Token=137 -Zombie Trailblazer=117 -Zombify=50 -Zoologist=45 -Zuberi, Golden Feather=44 +Zombie Token=113 +Zombie Trailblazer=148 +Zombify=30 +Zoologist=125 +Zuberi, Golden Feather=42 Zulaport Enforcer=45 Zuo Ci, the Mocking Sage=559 -Zur the Enchanter=230 -Zur's Weirding=49 +Zur the Enchanter=236 +Zur's Weirding=59 Zuran Enchanter=25 -Zuran Orb=123 +Zuran Orb=99 Zuran Spellcaster=38 -Zzzyxas's Abyss=100 diff --git a/res/quest/bazaar/index.xml b/res/quest/bazaar/index.xml index 6a57d660277..99db1ff5863 100644 --- a/res/quest/bazaar/index.xml +++ b/res/quest/bazaar/index.xml @@ -98,12 +98,12 @@ Fine Print: Loses effectiveness after 15 uses. Excellent at blocking the nastiest of critters! - - - - - - + + + + + + diff --git a/res/quest/duels/Buffy 2.dck b/res/quest/duels/Buffy 2.dck index 91a196d6ff6..cef00fabfae 100644 --- a/res/quest/duels/Buffy 2.dck +++ b/res/quest/duels/Buffy 2.dck @@ -13,7 +13,7 @@ Deck Type=constructed 1 Undead Warchief|TSB 1 Cemetery Reaper|M10 1 Smokespew Invoker|LGN -23 Swamp|MBS +24 Swamp|MBS 1 Zombie Master|6ED 1 Null Champion|ROE 1 Wretched Anurid|ONS @@ -46,4 +46,6 @@ Deck Type=constructed 1 Boneknitter 1 Endless Ranks of the Dead 1 Cellar Door +1 Gravecrawler +1 Mikaeus, the Unhallowed [sideboard] diff --git a/res/quest/duels/Da Vinci 3.dck b/res/quest/duels/Da Vinci 3.dck index c0fc9f42c45..b23e31c9413 100644 --- a/res/quest/duels/Da Vinci 3.dck +++ b/res/quest/duels/Da Vinci 3.dck @@ -7,11 +7,11 @@ Description=Mono B deck with Korlash, Heir to Blackblade, Bad Moon and threat re Icon=Da Vinci.jpg Deck Type=constructed [main] -23 Swamp|NPH +23 Swamp|NPH 1 Mox Jet 4 Korlash, Heir to Blackblade 1 Ascendant Evincar -2 Bad Moon +1 Bad Moon 2 Corrosive Mentor 1 Hellfire 2 Corrupt @@ -36,4 +36,5 @@ Deck Type=constructed 1 Geth's Verdict 1 Wrench Mind 1 Dunerider Outlaw +1 Geralf's Messenger [sideboard] diff --git a/res/quest/duels/Harry Potter 1.dck b/res/quest/duels/Harry Potter 1.dck index dc4fc31495d..5dd98a28940 100644 --- a/res/quest/duels/Harry Potter 1.dck +++ b/res/quest/duels/Harry Potter 1.dck @@ -1,30 +1,34 @@ -[duel] -[metadata] -Name=Harry Potter 1 -Title=Harry Potter -Difficulty=easy -Description=Mono U Mill and counter spell deck -Icon=Harry Potter.jpg -Deck Type=constructed -[main] -4 Vedalken Entrancer -2 Remove Soul -1 Traumatize -4 Hedron Crab -2 Essence Scatter -1 Keening Stone -22 Island|M12 -3 Brain Freeze -1 Boomerang -1 Jace Beleren -2 Tome Scour -2 Vision Skeins -2 Cancel -4 Howling Mine -3 Millstone -2 Unsummon -2 Cathartic Adept -1 Ray of Erasure -1 Shriekhorn -1 Merrow Witsniper -[sideboard] +[duel] +[metadata] +Name=Harry Potter 1 +Title=Harry Potter +Difficulty=easy +Description=Mono U Mill and counter spell deck +Icon=Harry Potter.jpg +Deck Type=constructed +[main] +4 Vedalken Entrancer +2 Remove Soul +1 Traumatize +3 Hedron Crab +2 Essence Scatter +1 Keening Stone +22 Island|M12 +2 Brain Freeze +1 Boomerang +1 Jace Beleren +2 Tome Scour +2 Vision Skeins +2 Cancel +4 Howling Mine +1 Millstone +2 Unsummon +2 Cathartic Adept +1 Ray of Erasure +1 Shriekhorn +1 Merrow Witsniper +1 Drowner Initiate +1 Flint Golem +1 Rotcrown Ghoul +1 Shriekgeist +[sideboard] diff --git a/res/quest/duels/Harry Potter 2.dck b/res/quest/duels/Harry Potter 2.dck index 378cc774801..cadcda2ef42 100644 --- a/res/quest/duels/Harry Potter 2.dck +++ b/res/quest/duels/Harry Potter 2.dck @@ -7,28 +7,38 @@ Description=UB Mill and counter spell deck Icon=Harry Potter.jpg Deck Type=constructed [main] +4 Swamp|M12 +11 Island|M12 +2 Darkslick Shores +2 Drowned Catacomb +2 Jwar Isle Refuge +1 Nephalia Drownyard 1 Vedalken Entrancer -4 Underground Sea -3 Remove Soul -2 Glimpse the Unthinkable +2 Remove Soul +1 Glimpse the Unthinkable 1 Traumatize -4 Hedron Crab -7 Swamp|M12 +3 Hedron Crab 3 Mind Funeral 1 Damnation 1 Keening Stone -11 Island|M12 1 Brain Freeze 1 Jace Beleren 1 Ambassador Laquatus -4 Tome Scour +1 Tome Scour 1 Nemesis of Reason 3 Counterspell -3 Howling Mine +2 Howling Mine 1 Millstone 1 Unsummon 1 Jace's Erasure 1 Shriekhorn 1 Memory Erosion 1 Riddlekeeper +1 Curse of the Bloody Tome +1 Dreadwaters +1 Dream Twist +1 Horrifying Revelation +1 Increasing Confusion +1 Thought Scour +1 Undead Alchemist [sideboard] diff --git a/res/quest/duels/Harry Potter 3.dck b/res/quest/duels/Harry Potter 3.dck index 768e0fe6c91..7d0606a45c3 100644 --- a/res/quest/duels/Harry Potter 3.dck +++ b/res/quest/duels/Harry Potter 3.dck @@ -1,30 +1,32 @@ -[duel] -[metadata] -Name=Harry Potter 3 -Title=Harry Potter -Difficulty=hard -Description=UB Mill and counter spell deck with card draw -Icon=Harry Potter.jpg -Deck Type=constructed -[main] -4 Underground Sea -4 Polluted Delta -4 Remove Soul -4 Glimpse the Unthinkable -1 Mox Sapphire -4 Hedron Crab -3 Mind Funeral -5 Swamp|M12 -2 Damnation -9 Island|M12 -1 Ancestral Recall -1 Divination -2 Jace Beleren -3 Tome Scour -2 Nemesis of Reason -1 Time Walk -4 Howling Mine -4 Counterspell -1 Mox Jet -1 Szadek, Lord of Secrets -[sideboard] +[duel] +[metadata] +Name=Harry Potter 3 +Title=Harry Potter +Difficulty=hard +Description=UB Mill and counter spell deck with card draw +Icon=Harry Potter.jpg +Deck Type=constructed +[main] +4 Underground Sea +4 Polluted Delta +4 Remove Soul +4 Glimpse the Unthinkable +1 Mox Sapphire +4 Hedron Crab +3 Mind Funeral +4 Swamp|M12 +2 Damnation +9 Island|M12 +1 Nephalia Drownyard +1 Ancestral Recall +1 Jace Beleren +3 Tome Scour +2 Nemesis of Reason +1 Time Walk +4 Howling Mine +4 Counterspell +1 Mox Jet +1 Szadek, Lord of Secrets +1 Chancellor of the Spires +1 Jace, Memory Adept +[sideboard] diff --git a/res/quest/duels/Radiant 2.dck b/res/quest/duels/Radiant 2.dck new file mode 100644 index 00000000000..bb42a4f421f --- /dev/null +++ b/res/quest/duels/Radiant 2.dck @@ -0,0 +1,53 @@ +[duel] +[metadata] +Name=Radiant 2 +Title=Radiant +Difficulty=medium +Description=WU flying creature deck with Radiant, Archangel, Gravitational Shift and Moat +Icon=Radiant.jpg +Deck Type=constructed +[main] +4 Plains|M12 +2 Island|M12 +4 Seachrome Coast +4 Sejiri Refuge +3 Glacial Fortress +4 Flooded Strand +1 Nimbus Maze +1 Radiant, Archangel +2 Soulcatcher +1 Archon of Redemption +2 Pride of the Clouds +1 Sprite Noble +1 Serra Aviary +1 Favorable Winds +1 Moat +1 Gravitational Shift +1 Abbey Griffin +1 Araba Mothrider +1 Armored Griffin +1 Armored Pegasus +1 Assault Griffin +1 Aven Riftwatcher +1 Avian Changeling +1 Azorius First-Wing +1 Blinding Angel +1 Cloud Elemental +1 Courier Hawk +1 Esper Cormorants +1 Flying Men +1 Griffin Sentinel +1 Gryff Vanguard +1 Hazerider Drake +1 Knight of Sursi +1 Messenger Falcons +1 Mulldrifter +1 Pegasus Charger +1 Peregrine Griffin +1 Requiem Angel +1 Shepherd of the Lost +1 Sky Spirit +1 Suntail Hawk +1 Talon Trooper +1 Tempest Drake +[sideboard] diff --git a/res/quest/duels/Radiant 3.dck b/res/quest/duels/Radiant 3.dck index 07e9e3ea580..1d5ae2d7b41 100644 --- a/res/quest/duels/Radiant 3.dck +++ b/res/quest/duels/Radiant 3.dck @@ -1,44 +1,41 @@ -[duel] -[metadata] -Name=Radiant 3 -Title=Radiant -Difficulty=hard -Description=WU flying creature deck with Radiant, Archangel, Gravitational Shift and Moat -Icon=Radiant.jpg -Deck Type=constructed -[main] -2 Plains|M12 -2 Island|M12 -4 Tundra -4 Sejiri Refuge -4 Glacial Fortress -4 Flooded Strand -1 Mox Sapphire -1 Mox Pearl -2 Radiant, Archangel -2 Soulcatcher -3 Archon of Redemption -3 Pride of the Clouds -1 Angelic Curator -1 Araba Mothrider -1 Aven Riftwatcher -1 Azorius First-Wing -1 Serra Avenger -1 Cloud Elemental -1 Cloud of Faeries -1 Cloud Spirit -1 Commander Eesha -1 Courier Hawk -1 Divinity of Pride -1 Emeria Angel -1 Esper Cormorants -1 Hunted Lammasu -1 Iridescent Angel -1 Keiga, the Tide Star -1 Serendib Efreet -1 Stormscape Familiar -1 Spectral Procession -1 Serra Aviary -4 Moat -4 Gravitational Shift -[sideboard] +[duel] +[metadata] +Name=Radiant 3 +Title=Radiant +Difficulty=hard +Description=WU flying creature deck with Radiant, Archangel, Gravitational Shift and Moat +Icon=Radiant.jpg +Deck Type=constructed +[main] +2 Plains|M12 +2 Island|M12 +4 Tundra +4 Sejiri Refuge +4 Glacial Fortress +4 Flooded Strand +1 Mox Sapphire +1 Mox Pearl +2 Radiant, Archangel +3 Archon of Redemption +2 Pride of the Clouds +4 Squadron Hawk +1 Azorius First-Wing +1 Serra Avenger +1 Cloud of Faeries +1 Commander Eesha +1 Courier Hawk +1 Godhead of Awe +1 Emeria Angel +1 Guardian Seraph +1 Hunted Lammasu +1 Iridescent Angel +1 Drogskol Reaver +1 Serendib Efreet +1 Stormscape Familiar +1 Spectral Procession +1 Favorable Winds +4 Moat +4 Gravitational Shift +1 Spell Snare +1 Disenchant +[sideboard] diff --git a/res/quest/duels/Sherlock Holmes 3.dck b/res/quest/duels/Sherlock Holmes 3.dck index f49ec0db521..321f0711469 100644 --- a/res/quest/duels/Sherlock Holmes 3.dck +++ b/res/quest/duels/Sherlock Holmes 3.dck @@ -1,35 +1,35 @@ -[duel] -[metadata] -Name=Sherlock Holmes 3 -Title=Sherlock Holmes -Difficulty=hard -Description=Mono G deck with Baru, Fist of Krosa and lots of great green creatures -Icon=Sherlock Holmes.jpg -Deck Type=constructed -[main] -21 Forest|M12 -1 Mox Emerald -1 Emerald Medallion -3 Three Visits -4 Baru, Fist of Krosa -1 Crabapple Cohort -1 Drove of Elves -1 Howl of the Night Pack -1 Kaysa -3 Khalni Hydra -1 Meng Huo, Barbarian King -1 Natural Order -3 Nettle Sentinel -1 Reach of Branches -1 Roughshod Mentor -1 Jugan, the Rising Star -1 Kodama of the North Tree -4 Leatherback Baloth -1 Rushwood Elemental -1 Silvos, Rogue Elemental -1 Terra Stomper -1 Weatherseed Treefolk -4 Garruk's Companion -1 Bellowing Tanglewurm -1 Primalcrux -[sideboard] +[duel] +[metadata] +Name=Sherlock Holmes 3 +Title=Sherlock Holmes +Difficulty=hard +Description=Mono G deck with Baru, Fist of Krosa and lots of great green creatures +Icon=Sherlock Holmes.jpg +Deck Type=constructed +[main] +21 Forest|M12 +1 Mox Emerald +1 Emerald Medallion +3 Three Visits +4 Baru, Fist of Krosa +1 Crabapple Cohort +1 Drove of Elves +1 Howl of the Night Pack +1 Kaysa +3 Khalni Hydra +1 Meng Huo, Barbarian King +3 Nettle Sentinel +1 Reach of Branches +1 Roughshod Mentor +1 Jugan, the Rising Star +1 Kodama of the North Tree +4 Leatherback Baloth +1 Rushwood Elemental +1 Silvos, Rogue Elemental +1 Terra Stomper +1 Weatherseed Treefolk +4 Garruk's Companion +1 Bellowing Tanglewurm +1 Primalcrux +1 Vorapede +[sideboard] diff --git a/res/quest/duels/Wyatt Earp 3.dck b/res/quest/duels/Wyatt Earp 3.dck index b9f4b659af4..336d8fe099f 100644 --- a/res/quest/duels/Wyatt Earp 3.dck +++ b/res/quest/duels/Wyatt Earp 3.dck @@ -29,7 +29,8 @@ Deck Type=constructed 1 Silver Knight 2 Kazandu Blademaster 1 Crackdown -4 Mirran Crusader +3 Mirran Crusader 1 Spectral Procession 1 Purity +1 Angel of Jubilation [sideboard] diff --git a/res/quest/quest-pet-token-images.txt b/res/quest/quest-pet-token-images.txt index 36311591137..08e84b3987c 100644 --- a/res/quest/quest-pet-token-images.txt +++ b/res/quest/quest-pet-token-images.txt @@ -11,19 +11,17 @@ petcrocodile_lvl1.jpg http://www.cardforge.org/fpics/pets/2012p petcrocodile_lvl2.jpg http://www.cardforge.org/fpics/pets/2012pets/PetCrocodile_LVL2.jpg petcrocodile_lvl3.jpg http://www.cardforge.org/fpics/pets/2012pets/PetCrocodile_LVL3.jpg petcrocodile_lvl4.jpg http://www.cardforge.org/fpics/pets/2012pets/PetCrocodile_LVL4.jpg -pethound_lvl1.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL1.jpg -pethound_lvl2.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL2.jpg -pethound_lvl3.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL3.jpg -pethound_lvl4.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL4.jpg +pethound_lvl1.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL1.jpg +pethound_lvl2.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL2.jpg +pethound_lvl3.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL3.jpg +pethound_lvl4.jpg http://www.cardforge.org/fpics/pets/2012pets/PetHound_LVL4.jpg petwolf_lvl1.jpg http://www.cardforge.org/fpics/pets/2012pets/PetWolf_LVL1.jpg petwolf_lvl2.jpg http://www.cardforge.org/fpics/pets/2012pets/PetWolf_LVL2.jpg petwolf_lvl3.jpg http://www.cardforge.org/fpics/pets/2012pets/PetWolf_LVL3.jpg petwolf_lvl4.jpg http://www.cardforge.org/fpics/pets/2012pets/PetWolf_LVL4.jpg -g_0_1_plant_wall.jpg http://www.cardforge.org/fpics/pets/tokens/g_0_1_plant_wall.jpg -g_0_2_plant_wall.jpg http://www.cardforge.org/fpics/pets/tokens/g_0_2_plant_wall.jpg -g_0_3_plant_wall.jpg http://www.cardforge.org/fpics/pets/tokens/g_0_3_plant_wall.jpg -g_1_3_plant_wall.jpg http://www.cardforge.org/fpics/pets/tokens/g_1_3_plant_wall.jpg -g_1_3_plant_wall_deathtouch.jpg http://www.cardforge.org/fpics/pets/tokens/g_1_3_plant_wall_deathtouch.jpg -g_1_3_plant_wall_wither.jpg http://www.cardforge.org/fpics/pets/tokens/g_1_3_plant_wall_wither.jpg -g_1_4_plant_wall.jpg http://www.cardforge.org/fpics/pets/tokens/g_1_4_plant_wall.jpg -g_1_4_plant_wall_wither.jpg http://www.cardforge.org/fpics/pets/tokens/g_1_4_plant_wall_wither.jpg \ No newline at end of file +plantwall_lvl1.jpg http://www.cardforge.org/fpics/pets/2012pets/PlantWall_LVL1.jpg +plantwall_lvl2.jpg http://www.cardforge.org/fpics/pets/2012pets/PlantWall_LVL2.jpg +plantwall_lvl3.jpg http://www.cardforge.org/fpics/pets/2012pets/PlantWall_LVL3.jpg +plantwall_lvl4.jpg http://www.cardforge.org/fpics/pets/2012pets/PlantWall_LVL4.jpg +plantwall_lvl5.jpg http://www.cardforge.org/fpics/pets/2012pets/PlantWall_LVL5.jpg +plantwall_lvl6.jpg http://www.cardforge.org/fpics/pets/2012pets/PlantWall_LVL6.jpg \ No newline at end of file diff --git a/res/skins/default/grid_icons.png b/res/skins/default/grid_icons.png index 7b3285fb277..ef3592cfb8e 100644 Binary files a/res/skins/default/grid_icons.png and b/res/skins/default/grid_icons.png differ diff --git a/res/skins/default/sprite_icons.png b/res/skins/default/sprite_icons.png index 4c891fd1086..b6d1b158110 100644 Binary files a/res/skins/default/sprite_icons.png and b/res/skins/default/sprite_icons.png differ diff --git a/res/skins/firebloom/bg_match.jpg b/res/skins/firebloom/bg_match.jpg index 887fbb50efb..fa664d0c43e 100644 Binary files a/res/skins/firebloom/bg_match.jpg and b/res/skins/firebloom/bg_match.jpg differ diff --git a/res/skins/firebloom/sprite_icons.png b/res/skins/firebloom/sprite_icons.png index 37ed441b73d..03f8617c6b8 100644 Binary files a/res/skins/firebloom/sprite_icons.png and b/res/skins/firebloom/sprite_icons.png differ diff --git a/res/sound/tap.mp3 b/res/sound/tap.mp3 deleted file mode 100644 index 806612a6aa3..00000000000 Binary files a/res/sound/tap.mp3 and /dev/null differ diff --git a/res/token-images.txt b/res/token-images.txt index c7cc9669782..54f064215e0 100644 --- a/res/token-images.txt +++ b/res/token-images.txt @@ -23,6 +23,7 @@ b_3_3_angel.jpg http://www.cardforge.org/fpics/tokens/b_3 b_3_3_kavu.jpg http://www.cardforge.org/fpics/tokens/b_3_3_kavu.jpg b_4_4_horror.jpg http://www.cardforge.org/fpics/tokens/b_4_4_horror.jpg b_5_5_demon.jpg http://www.cardforge.org/fpics/tokens/b_5_5_demon.jpg +b_5_5_demon_avr.jpg http://www.cardforge.org/fpics/tokens/b_5_5_demon_avr.jpg b_5_5_urami.jpg http://www.cardforge.org/fpics/tokens/b_5_5_urami.jpg b_5_5_zombie_giant.jpg http://www.cardforge.org/fpics/tokens/b_5_5_zombie_giant.jpg b_6_6_wurm.jpg http://www.cardforge.org/fpics/tokens/b_6_6_wurm.jpg @@ -123,6 +124,7 @@ r_1_1_elemental_cat.jpg http://www.cardforge.org/fpics/tokens/r_1 r_1_1_elemental.jpg http://www.cardforge.org/fpics/tokens/r_1_1_elemental.jpg r_1_1_goblin.jpg http://www.cardforge.org/fpics/tokens/r_1_1_goblin.jpg r_1_1_goblin_scout.jpg http://www.cardforge.org/fpics/tokens/r_1_1_goblin_scout.jpg +r_1_1_human_avr.jpg http://www.cardforge.org/fpics/tokens/r_1_1_human_avr.jpg r_1_1_survivor.jpg http://www.cardforge.org/fpics/tokens/r_1_1_survivor.jpg r_2_1_goblin.jpg http://www.cardforge.org/fpics/tokens/r_2_1_goblin.jpg r_3_1_carnivore.jpg http://www.cardforge.org/fpics/tokens/r_3_1_carnivore.jpg @@ -150,6 +152,7 @@ u_1_1_faerie.jpg http://www.cardforge.org/fpics/tokens/u_1 u_1_1_illusion.jpg http://www.cardforge.org/fpics/tokens/u_1_1_illusion.jpg u_1_1_merfolk_wizard.jpg http://www.cardforge.org/fpics/tokens/u_1_1_merfolk_wizard.jpg u_1_1_thopter.jpg http://www.cardforge.org/fpics/tokens/u_1_1_thopter.jpg +u_1_1_spirit_avr.jpg http://www.cardforge.org/fpics/tokens/u_1_1_spirit_avr.jpg u_2_2_elemental_flying.jpg http://www.cardforge.org/fpics/tokens/u_2_2_elemental_flying.jpg u_2_2_homunculus.jpg http://www.cardforge.org/fpics/tokens/u_2_2_homunculus.jpg u_2_2_illusion.jpg http://www.cardforge.org/fpics/tokens/u_2_2_illusion.jpg @@ -168,12 +171,14 @@ w_1_1_bird_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1 w_1_1_citizen.jpg http://www.cardforge.org/fpics/tokens/w_1_1_citizen.jpg w_1_1_goldmeadow_harrier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_goldmeadow_harrier.jpg w_1_1_human_dka.jpg http://www.cardforge.org/fpics/tokens/w_1_1_human_dka.jpg +w_1_1_human_avr.jpg http://www.cardforge.org/fpics/tokens/w_1_1_human_avr.jpg w_1_1_kithkin_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_kithkin_soldier.jpg w_1_1_kor_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_kor_soldier.jpg w_1_1_pegasus.jpg http://www.cardforge.org/fpics/tokens/w_1_1_pegasus.jpg w_1_1_soldier.jpg http://www.cardforge.org/fpics/tokens/w_1_1_soldier.jpg w_1_1_soldier_ally.jpg http://www.cardforge.org/fpics/tokens/w_1_1_soldier_ally.jpg w_1_1_spirit.jpg http://www.cardforge.org/fpics/tokens/w_1_1_spirit.jpg +w_1_1_spirit_avr.jpg http://www.cardforge.org/fpics/tokens/w_1_1_spirit_avr.jpg w_2_2_cat.jpg http://www.cardforge.org/fpics/tokens/w_2_2_cat.jpg w_2_2_griffin.jpg http://www.cardforge.org/fpics/tokens/w_2_2_griffin.jpg w_2_2_knight.jpg http://www.cardforge.org/fpics/tokens/w_2_2_knight.jpg @@ -182,6 +187,7 @@ w_2_2_reflection.jpg http://www.cardforge.org/fpics/tokens/w_2 w_3_3_bird.jpg http://www.cardforge.org/fpics/tokens/w_3_3_bird.jpg w_3_3_spirit.jpg http://www.cardforge.org/fpics/tokens/w_3_3_spirit.jpg w_4_4_angel.jpg http://www.cardforge.org/fpics/tokens/w_4_4_angel.jpg +w_4_4_angel_avr.jpg http://www.cardforge.org/fpics/tokens/w_4_4_angel_avr.jpg w_4_4_elemental.jpg http://www.cardforge.org/fpics/tokens/w_4_4_elemental.jpg w_5_5_giant_warrior.jpg http://www.cardforge.org/fpics/tokens/w_5_5_giant_warrior.jpg w_n_n_avatar.jpg http://www.cardforge.org/fpics/tokens/w_n_n_avatar.jpg @@ -195,6 +201,7 @@ chandra_the_firebrand_effect.jpg http://www.cardforge.org/fpics/effects/ch elspeth_knight_errant_emblem.jpg http://www.cardforge.org/fpics/effects/elspeth_knight_errant_emblem.jpg koth_of_the_hammer_emblem.jpg http://www.cardforge.org/fpics/effects/koth_of_the_hammer_emblem.jpg sorin_lord_of_innistrad_emblem.jpg http://www.cardforge.org/fpics/effects/sorin_lord_of_innistrad_effect.jpg +tamiyo_the_moon_sage_emblem.jpg http://www.cardforge.org/fpics/effects/tamiyo-the-moon-sage-emblem.jpg venser_the_sojourner_emblem.jpg http://www.cardforge.org/fpics/effects/venser_the_sojourner_emblem.jpg morph.jpg http://www.cardforge.org/fpics/effects/morph.jpg diff --git a/src/main/java/forge/Card.java b/src/main/java/forge/Card.java index cd0027ae420..076ef085319 100644 --- a/src/main/java/forge/Card.java +++ b/src/main/java/forge/Card.java @@ -34,6 +34,7 @@ import java.util.TreeMap; import com.esotericsoftware.minlog.Log; import forge.card.CardCharacteristics; +import forge.card.CardManaCost; import forge.card.EditionInfo; import forge.card.abilityfactory.AbilityFactory; import forge.card.cardfactory.CardFactoryUtil; @@ -1588,7 +1589,7 @@ public class Card extends GameEntity implements Comparable { * @param s * a {@link java.lang.String} object. */ - public final void setManaCost(final String s) { + public final void setManaCost(final CardManaCost s) { this.getCharacteristics().setManaCost(s); } @@ -1599,7 +1600,7 @@ public class Card extends GameEntity implements Comparable { * * @return a {@link java.lang.String} object. */ - public final String getManaCost() { + public final CardManaCost getManaCost() { return this.getCharacteristics().getManaCost(); } @@ -1776,7 +1777,7 @@ public class Card extends GameEntity implements Comparable { * @return a int. */ public final int getCMC() { - return CardUtil.getConvertedManaCost(this.getCharacteristics().getManaCost()); + return this.getCharacteristics().getManaCost().getCMC(); } /** @@ -7079,7 +7080,7 @@ public class Card extends GameEntity implements Comparable { return false; } } else if (property.equals("CostsPhyrexianMana")) { - if (!this.getCharacteristics().getManaCost().contains("P")) { + if (!this.getCharacteristics().getManaCost().hasPhyrexian()) { return false; } } else if (property.equals("IsRemembered")) { diff --git a/src/main/java/forge/CardList.java b/src/main/java/forge/CardList.java index dba70e97d64..cbac2c85ff1 100644 --- a/src/main/java/forge/CardList.java +++ b/src/main/java/forge/CardList.java @@ -714,6 +714,20 @@ public class CardList implements Iterable { this.list.removeAll(cList); } + /** + *

+ * removeAll. + *

+ * + * @param c + * a {@link forge.Card} object. + */ + public final void removeAll(final CardList list) { + for (Card c : list) { + this.list.remove(c); + } + } + /** *

* clear. diff --git a/src/main/java/forge/CardListUtil.java b/src/main/java/forge/CardListUtil.java index 83768277ce9..0d3fe65e9bd 100644 --- a/src/main/java/forge/CardListUtil.java +++ b/src/main/java/forge/CardListUtil.java @@ -410,8 +410,8 @@ public class CardListUtil { final Comparator com = new Comparator() { @Override public int compare(final Card a, final Card b) { - final int cmcA = CardUtil.getConvertedManaCost(a.getManaCost()); - final int cmcB = CardUtil.getConvertedManaCost(b.getManaCost()); + final int cmcA = a.getManaCost().getCMC(); + final int cmcB = b.getManaCost().getCMC(); if (cmcA == cmcB) { return 0; @@ -547,7 +547,7 @@ public class CardListUtil { int cmc = 0; for (int i = 0; i < c.size(); i++) { - cmc += CardUtil.getConvertedManaCost(c.get(i).getManaCost()); + cmc += c.get(i).getManaCost().getCMC(); } // System.out.println("Total CMC: " +cmc); diff --git a/src/main/java/forge/CardReader.java b/src/main/java/forge/CardReader.java index 069a8159d40..3e03a3ec80a 100644 --- a/src/main/java/forge/CardReader.java +++ b/src/main/java/forge/CardReader.java @@ -41,9 +41,11 @@ import net.slightlymagic.braids.GeneratorFunctions; import com.google.code.jyield.Generator; import com.google.code.jyield.YieldUtils; +import forge.card.CardManaCost; import forge.card.CardRules; import forge.card.CardRulesReader; import forge.card.EditionInfo; +import forge.card.mana.ManaCostParser; import forge.card.replacement.ReplacementHandler; import forge.card.trigger.TriggerHandler; import forge.error.ErrorViewer; @@ -423,7 +425,7 @@ public class CardReader implements Runnable { final String value = line.substring(9); // System.out.println(s); if (!"no cost".equals(value)) { - card.setManaCost(value); + card.setManaCost(new CardManaCost(new ManaCostParser(value))); } } else if (line.startsWith("Types:")) { CardReader.addTypes(card, line.substring("Types:".length())); diff --git a/src/main/java/forge/CardUtil.java b/src/main/java/forge/CardUtil.java index 10ba056a550..62eab0b06cd 100644 --- a/src/main/java/forge/CardUtil.java +++ b/src/main/java/forge/CardUtil.java @@ -31,6 +31,7 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; import forge.card.CardCharacteristics; +import forge.card.CardManaCost; import forge.card.EditionInfo; import forge.card.mana.ManaCost; import forge.card.spellability.SpellAbility; @@ -254,32 +255,22 @@ public final class CardUtil { * @return a {@link java.util.ArrayList} object. */ public static ArrayList getOnlyColors(final Card c) { - final String m = c.getManaCost(); + final CardManaCost m = c.getManaCost(); + final byte color_profile = m.getColorProfile(); + final Set colors = new HashSet(); + if ((color_profile & forge.card.CardColor.WHITE) > 0 ) + colors.add(Constant.Color.WHITE); + if ((color_profile & forge.card.CardColor.BLACK) > 0 ) + colors.add(Constant.Color.BLACK); + if ((color_profile & forge.card.CardColor.BLUE) > 0 ) + colors.add(Constant.Color.BLUE); + if ((color_profile & forge.card.CardColor.RED) > 0 ) + colors.add(Constant.Color.RED); + if ((color_profile & forge.card.CardColor.GREEN) > 0 ) + colors.add(Constant.Color.GREEN); + - for (int i = 0; i < m.length(); i++) { - switch (m.charAt(i)) { - case ' ': - break; - case 'G': - colors.add(Constant.Color.GREEN); - break; - case 'W': - colors.add(Constant.Color.WHITE); - break; - case 'B': - colors.add(Constant.Color.BLACK); - break; - case 'U': - colors.add(Constant.Color.BLUE); - break; - case 'R': - colors.add(Constant.Color.RED); - break; - default: - break; - } - } for (final String kw : c.getKeyword()) { if (kw.startsWith(c.getName() + " is ") || kw.startsWith("CARDNAME is ")) { for (final String color : Constant.Color.COLORS) { @@ -344,7 +335,7 @@ public final class CardUtil { if (c.isToken() && !c.isCopiedToken()) { return 0; } - return CardUtil.getConvertedManaCost(c.getManaCost()); + return c.getManaCost().getCMC(); } /** diff --git a/src/main/java/forge/GameAction.java b/src/main/java/forge/GameAction.java index 167d72b7967..7f63ad078e3 100644 --- a/src/main/java/forge/GameAction.java +++ b/src/main/java/forge/GameAction.java @@ -34,6 +34,7 @@ import forge.card.cost.CostMana; import forge.card.cost.CostPart; import forge.card.cost.CostPayment; import forge.card.mana.ManaCost; +import forge.card.mana.ManaCostShard; import forge.card.spellability.Ability; import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityStatic; @@ -1717,10 +1718,7 @@ public class GameAction { sa.setSourceCard(Singletons.getModel().getGameAction().moveToStack(c)); } } - boolean x = false; - if (sa.getSourceCard().getManaCost().contains("X")) { - x = true; - } + boolean x = sa.getSourceCard().getManaCost().getShardCount(ManaCostShard.X) > 0; if (sa.isKickerAbility()) { final Command paid1 = new Command() { diff --git a/src/main/java/forge/GameActionUtil.java b/src/main/java/forge/GameActionUtil.java index def706ef8f1..8b3a336d748 100644 --- a/src/main/java/forge/GameActionUtil.java +++ b/src/main/java/forge/GameActionUtil.java @@ -131,8 +131,7 @@ public final class GameActionUtil { while (cascadedCard == null) { crd = topOfLibrary.get(count++); revealed.add(crd); - if ((!crd.isLand() && (CardUtil.getConvertedManaCost(crd.getManaCost()) < CardUtil - .getConvertedManaCost(cascCard.getManaCost())))) { + if ((!crd.isLand() && (crd.getManaCost().getCMC() < cascCard.getManaCost().getCMC()))) { cascadedCard = crd; } @@ -381,6 +380,14 @@ public final class GameActionUtil { } return; } + if (manaCost.equals("0")) { + if (showYesNoDialog(hostCard, "Do you want to pay 0?")) { + paid.execute(); + } else { + unpaid.execute(); + } + return; + } // temporarily disable the Resolve flag, so the user can payMana for the // resolving Ability final boolean bResolving = AllZone.getStack().getResolving(); diff --git a/src/main/java/forge/GameEntity.java b/src/main/java/forge/GameEntity.java index 45926af8e9e..ded2d27bd8d 100644 --- a/src/main/java/forge/GameEntity.java +++ b/src/main/java/forge/GameEntity.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import forge.card.spellability.SpellAbility; import forge.game.player.Player; +import forge.util.MyObservable; /** *

diff --git a/src/main/java/forge/GameLog.java b/src/main/java/forge/GameLog.java index acb8b3b7270..d986eb12c7c 100644 --- a/src/main/java/forge/GameLog.java +++ b/src/main/java/forge/GameLog.java @@ -20,6 +20,8 @@ package forge; import java.util.ArrayList; +import forge.util.MyObservable; + /** *

diff --git a/src/main/java/forge/card/CardCharacteristics.java b/src/main/java/forge/card/CardCharacteristics.java index 720555c756c..81776108a15 100644 --- a/src/main/java/forge/card/CardCharacteristics.java +++ b/src/main/java/forge/card/CardCharacteristics.java @@ -34,7 +34,7 @@ import forge.card.trigger.Trigger; public class CardCharacteristics { private String name = ""; private ArrayList type = new ArrayList(); - private String manaCost = ""; + private CardManaCost manaCost = CardManaCost.EMPTY; private ArrayList cardColor = new ArrayList(); private boolean cardColorsOverridden = false; private int baseAttack = 0; @@ -94,7 +94,7 @@ public class CardCharacteristics { * * @return the manaCost */ - public final String getManaCost() { + public final CardManaCost getManaCost() { return this.manaCost; } @@ -104,7 +104,7 @@ public class CardCharacteristics { * @param manaCost0 * the manaCost to set */ - public final void setManaCost(final String manaCost0) { + public final void setManaCost(final CardManaCost manaCost0) { this.manaCost = manaCost0; } diff --git a/src/main/java/forge/card/CardManaCost.java b/src/main/java/forge/card/CardManaCost.java index 566a128b742..df7ea2d53c7 100644 --- a/src/main/java/forge/card/CardManaCost.java +++ b/src/main/java/forge/card/CardManaCost.java @@ -137,6 +137,18 @@ public final class CardManaCost implements Comparable { public List getShards() { return this.shards; } + + public int getShardCount(ManaCostShard which) { + if ( which == ManaCostShard.COLORLESS ) + return genericCost; + + int res = 0; + for(ManaCostShard shard : shards) + { + if ( shard == which ) res++; + } + return res; + } /** * Gets the generic cost. diff --git a/src/main/java/forge/card/CardRules.java b/src/main/java/forge/card/CardRules.java index 671522b1a4a..fbeea4fa9e2 100644 --- a/src/main/java/forge/card/CardRules.java +++ b/src/main/java/forge/card/CardRules.java @@ -27,18 +27,17 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; import forge.util.closures.Predicate; -import forge.util.closures.PredicateString; import forge.util.closures.Predicate.ComparableOp; import forge.util.closures.Predicate.PredicatesOp; +import forge.util.closures.PredicateString; /** - *

- * CardOracle class. - *

+ * A collection of methods containing full + * meta and gameplay properties of a card. * * @author Forge - * @version $Id: CardOracle.java 9708 2011-08-09 19:34:12Z jendave $ + * @version $Id: CardRules.java 9708 2011-08-09 19:34:12Z jendave $ */ public final class CardRules { @@ -389,8 +388,31 @@ public final class CardRules { return new LeafNumber(LeafNumber.CardField.CMC, op, what); } - // Power - // Toughness + /** + * + * @param op + * the op + * @param what + * the what + * @return the predicate + */ + public static Predicate power(final ComparableOp op, final int what) { + return new LeafNumber(LeafNumber.CardField.POWER, op, what); + } + + /** + * + * @param op + * the op + * @param what + * the what + * @return the predicate + */ + public static Predicate toughness(final ComparableOp op, final int what) { + return new LeafNumber(LeafNumber.CardField.TOUGHNESS, op, what); + } + + // P/T /** * Rules. * @@ -462,7 +484,7 @@ public final class CardRules { * @return the predicate */ public static Predicate wasPrintedInSets(final List setCodes) { - return new PredicateExitsInSets(setCodes); + return new PredicateExistsInSets(setCodes); } /** @@ -568,7 +590,7 @@ public final class CardRules { * @return the predicate */ public static Predicate hasCntColors(final byte cntColors) { - return new LeafColor(LeafColor.ColorOperator.Equals, cntColors); + return new LeafColor(LeafColor.ColorOperator.CountColors, cntColors); } /** @@ -634,18 +656,18 @@ public final class CardRules { @Override public boolean isTrue(final CardRules subject) { switch (this.op) { - case CountColors: - return subject.getColor().countColors() == this.color; - case CountColorsGreaterOrEqual: - return subject.getColor().countColors() >= this.color; - case Equals: - return subject.getColor().isEqual(this.color); - case HasAllOf: - return subject.getColor().hasAllColors(this.color); - case HasAnyOf: - return subject.getColor().hasAnyColor(this.color); - default: - return false; + case CountColors: + return subject.getColor().countColors() == this.color; + case CountColorsGreaterOrEqual: + return subject.getColor().countColors() >= this.color; + case Equals: + return subject.getColor().isEqual(this.color); + case HasAllOf: + return subject.getColor().hasAllColors(this.color); + case HasAnyOf: + return subject.getColor().hasAnyColor(this.color); + default: + return false; } } } @@ -747,10 +769,10 @@ public final class CardRules { } } - private static class PredicateExitsInSets extends Predicate { + private static class PredicateExistsInSets extends Predicate { private final List sets; - public PredicateExitsInSets(final List wantSets) { + public PredicateExistsInSets(final List wantSets) { this.sets = wantSets; // maybe should make a copy here? } @@ -808,6 +830,9 @@ public final class CardRules { public static final Predicate IS_NON_CREATURE_SPELL = Predicate.compose(Presets.IS_CREATURE, PredicatesOp.NOR, Presets.IS_LAND); + /** + * + */ @SuppressWarnings("unchecked") public static final Predicate IS_NONCREATURE_SPELL_FOR_GENERATOR = Predicate.or(Arrays.asList( Presets.IS_SORCERY, Presets.IS_INSTANT, Presets.IS_PLANESWALKER, Presets.IS_ENCHANTMENT, diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactory.java b/src/main/java/forge/card/abilityfactory/AbilityFactory.java index f2540720431..801d50cb660 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactory.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactory.java @@ -2478,7 +2478,7 @@ public class AbilityFactory { return; } - host = af.getHostCard(); + host = sa.getSourceCard(); if (params.containsKey("ForgetOtherTargets")) { host.clearRemembered(); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java index 8dcdd94429e..bd443b8c436 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryChangeZone.java @@ -947,6 +947,9 @@ public final class AbilityFactoryChangeZone { } movedCard = Singletons.getModel().getGameAction().moveTo(c.getController().getZone(destination), c); + if (params.containsKey("Tapped")) { + movedCard.setTapped(true); + } } else if (destination.equals(ZoneType.Exile)) { movedCard = Singletons.getModel().getGameAction().exile(c); if (params.containsKey("ExileFaceDown")) { @@ -1104,7 +1107,7 @@ public final class AbilityFactoryChangeZone { Singletons.getModel().getGameAction().moveToLibrary(c, libraryPos); } else if (ZoneType.Battlefield.equals(destination)) { if (params.containsKey("Tapped")) { - c.tap(); + c.setTapped(true); } if (params.containsKey("GainControl")) { c.addController(sa.getSourceCard()); @@ -1139,6 +1142,9 @@ public final class AbilityFactoryChangeZone { } newCard = Singletons.getModel().getGameAction().moveTo(c.getController().getZone(destination), c); + if (params.containsKey("Tapped")) { + newCard.setTapped(true); + } } else if (destination.equals(ZoneType.Exile)) { newCard = Singletons.getModel().getGameAction().exile(c); if (params.containsKey("ExileFaceDown")) { @@ -2008,6 +2014,9 @@ public final class AbilityFactoryChangeZone { AllZone.getCombat().addAttacker(tgtC); AllZone.getCombat().addUnblockedAttacker(tgtC); } + if (params.containsKey("Tapped") || params.containsKey("Ninjutsu")) { + tgtC.setTapped(true); + } } else { movedCard = Singletons.getModel().getGameAction().moveTo(destination, tgtC); // If a card is Exiled from the stack, remove its spells from the stack @@ -2619,9 +2628,8 @@ public final class AbilityFactoryChangeZone { continue; } } - if (params.containsKey("Tapped")) { - c.tap(); + c.setTapped(true); } } @@ -2633,6 +2641,9 @@ public final class AbilityFactoryChangeZone { if (params.containsKey("ExileFaceDown")) { movedCard.setState(CardCharactersticName.FaceDown); } + if (params.containsKey("Tapped")) { + movedCard.setTapped(true); + } } if (remember != null) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java index 2403fc268bc..87b3e8efbb2 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryChoose.java @@ -285,7 +285,7 @@ public final class AbilityFactoryChoose { */ private static void chooseTypeResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); final String type = params.get("Type"); final ArrayList invalidTypes = new ArrayList(); if (params.containsKey("InvalidTypes")) { @@ -639,7 +639,7 @@ public final class AbilityFactoryChoose { */ private static void chooseColorResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); ArrayList tgtPlayers; @@ -914,7 +914,7 @@ public final class AbilityFactoryChoose { */ private static void chooseNumberResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); //final int min = params.containsKey("Min") ? Integer.parseInt(params.get("Min")) : 0; //final int max = params.containsKey("Max") ? Integer.parseInt(params.get("Max")) : 99; final boolean random = params.containsKey("Random"); @@ -1187,7 +1187,7 @@ public final class AbilityFactoryChoose { */ private static void choosePlayerResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); ArrayList tgtPlayers; @@ -1445,7 +1445,7 @@ public final class AbilityFactoryChoose { */ private static void nameCardResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); ArrayList tgtPlayers; @@ -1730,7 +1730,7 @@ public final class AbilityFactoryChoose { */ private static void chooseCardResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); final ArrayList chosen = new ArrayList(); ArrayList tgtPlayers; @@ -1986,7 +1986,7 @@ public final class AbilityFactoryChoose { private static void chooseGenericResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); final BiMap choices = HashBiMap.create(); for (String s : Arrays.asList(params.get("Choices").split(","))) { final HashMap theseParams = AbilityFactory.getMapParams(host.getSVar(s), host); @@ -2008,7 +2008,7 @@ public final class AbilityFactoryChoose { AbilityFactory afChoice = new AbilityFactory(); final SpellAbility chosenSA = afChoice.getAbility(host.getSVar(choices.inverse().get(choice)), host); - chosenSA.setActivatingPlayer(af.getHostCard().getController()); + chosenSA.setActivatingPlayer(sa.getSourceCard().getController()); ((AbilitySub) chosenSA).setParent(sa); AbilityFactory.resolve(chosenSA, false); } diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryClash.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryClash.java index c054bb08595..90117b2798f 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryClash.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryClash.java @@ -78,7 +78,7 @@ public final class AbilityFactoryClash { @Override public String getStackDescription() { - return af.getHostCard().getName() + " - Clash with an opponent."; + return this.getSourceCard().getName() + " - Clash with an opponent."; } @Override @@ -116,7 +116,7 @@ public final class AbilityFactoryClash { @Override public String getStackDescription() { - return af.getHostCard().getName() + " - Clash with an opponent."; + return this.getSourceCard().getName() + " - Clash with an opponent."; } @Override @@ -159,7 +159,7 @@ public final class AbilityFactoryClash { @Override public String getStackDescription() { - return af.getHostCard().getName() + " - Clash with an opponent."; + return this.getSourceCard().getName() + " - Clash with an opponent."; } @Override @@ -195,17 +195,17 @@ public final class AbilityFactoryClash { */ private static void clashResolve(final AbilityFactory af, final SpellAbility sa) { final AbilityFactory afOutcomes = new AbilityFactory(); - final boolean victory = af.getHostCard().getController().clashWithOpponent(af.getHostCard()); + final boolean victory = sa.getSourceCard().getController().clashWithOpponent(sa.getSourceCard()); // Run triggers final HashMap runParams = new HashMap(); - runParams.put("Player", af.getHostCard().getController()); + runParams.put("Player", sa.getSourceCard().getController()); if (victory) { if (af.getMapParams().containsKey("WinSubAbility")) { final SpellAbility win = afOutcomes.getAbility( - af.getHostCard().getSVar(af.getMapParams().get("WinSubAbility")), af.getHostCard()); - win.setActivatingPlayer(af.getHostCard().getController()); + sa.getSourceCard().getSVar(af.getMapParams().get("WinSubAbility")), sa.getSourceCard()); + win.setActivatingPlayer(sa.getSourceCard().getController()); ((AbilitySub) win).setParent(sa); AbilityFactory.resolve(win, false); @@ -214,8 +214,8 @@ public final class AbilityFactoryClash { } else { if (af.getMapParams().containsKey("OtherwiseSubAbility")) { final SpellAbility otherwise = afOutcomes.getAbility( - af.getHostCard().getSVar(af.getMapParams().get("OtherwiseSubAbility")), af.getHostCard()); - otherwise.setActivatingPlayer(af.getHostCard().getController()); + sa.getSourceCard().getSVar(af.getMapParams().get("OtherwiseSubAbility")), sa.getSourceCard()); + otherwise.setActivatingPlayer(sa.getSourceCard().getController()); ((AbilitySub) otherwise).setParent(sa); AbilityFactory.resolve(otherwise, false); @@ -362,7 +362,7 @@ public final class AbilityFactoryClash { */ private static String flipGetStackDescription(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); final Player player = params.containsKey("OpponentCalls") ? host.getController().getOpponent() : host .getController(); @@ -396,7 +396,7 @@ public final class AbilityFactoryClash { */ private static void flipResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); final Player player = host.getController(); final ArrayList caller = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Caller"), sa); @@ -597,7 +597,7 @@ public final class AbilityFactoryClash { private static boolean twoPilesCanPlayAI(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); ZoneType zone = null; if (params.containsKey("Zone")) { @@ -640,7 +640,7 @@ public final class AbilityFactoryClash { private static void twoPilesResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); ZoneType zone = null; boolean pile1WasChosen = true; diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java index 35f074161ea..bba85d4899d 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCombat.java @@ -423,7 +423,7 @@ public final class AbilityFactoryCombat { private static String mustAttackStackDescription(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); final StringBuilder sb = new StringBuilder(); if (sa instanceof AbilitySub) { @@ -520,7 +520,7 @@ public final class AbilityFactoryCombat { if ((tgt == null) || p.canBeTargetedBy(sa)) { Object entity; if (params.get("Defender").equals("Self")) { - entity = af.getHostCard(); + entity = sa.getSourceCard(); } else { entity = p.getOpponent(); } @@ -854,7 +854,7 @@ public final class AbilityFactoryCombat { private static String mustBlockStackDescription(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); final StringBuilder sb = new StringBuilder(); if (sa instanceof AbilitySub) { @@ -994,7 +994,7 @@ public final class AbilityFactoryCombat { private static void mustBlockResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); ArrayList tgtCards; diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCopy.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCopy.java index 157c12c1065..e69cfb2722b 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCopy.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCopy.java @@ -343,7 +343,7 @@ public final class AbilityFactoryCopy { */ private static void copyPermanentResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card hostCard = af.getHostCard(); + final Card hostCard = sa.getSourceCard(); final ArrayList keywords = new ArrayList(); if (params.containsKey("Keywords")) { keywords.addAll(Arrays.asList(params.get("Keywords").split(" & "))); @@ -647,7 +647,7 @@ public final class AbilityFactoryCopy { } int amount = 1; if (params.containsKey("Amount")) { - amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("Amount"), sa); + amount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("Amount"), sa); } if (amount > 1) { sb.append(amount).append(" times"); @@ -716,7 +716,7 @@ public final class AbilityFactoryCopy { */ private static void copySpellResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); Player controller = sa.getActivatingPlayer(); int amount = 1; diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java index 2cac866ba5a..b560f3c2944 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounterMagic.java @@ -403,7 +403,7 @@ public class AbilityFactoryCounterMagic { if (this.params.containsKey("ForgetOtherTargets")) { if (this.params.get("ForgetOtherTargets").equals("True")) { - af.getHostCard().clearRemembered(); + sa.getSourceCard().clearRemembered(); } } @@ -428,7 +428,7 @@ public class AbilityFactoryCounterMagic { if (this.params.containsKey("RememberTargets")) { if (this.params.get("RememberTargets").equals("True")) { - af.getHostCard().addRemembered(tgtSACard); + sa.getSourceCard().addRemembered(tgtSACard); } } } @@ -519,6 +519,9 @@ public class AbilityFactoryCounterMagic { Singletons.getModel().getGameAction().moveToLibrary(tgtSA.getSourceCard()); } else if (this.destination.equals("Hand")) { Singletons.getModel().getGameAction().moveToHand(tgtSA.getSourceCard()); + } else if (this.destination.equals("Battlefield")) { + Card c = Singletons.getModel().getGameAction().moveToPlay(tgtSA.getSourceCard(), srcSA.getActivatingPlayer()); + c.addController(srcSA.getActivatingPlayer()); } else if (this.destination.equals("BottomOfLibrary")) { Singletons.getModel().getGameAction().moveToBottomOfLibrary(tgtSA.getSourceCard()); } else if (this.destination.equals("ShuffleIntoLibrary")) { diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java index 39564261949..df55c61a061 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryCounters.java @@ -207,8 +207,8 @@ public class AbilityFactoryCounters { } final Counters cType = Counters.valueOf(params.get("CounterType")); - final Card card = af.getHostCard(); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + final Card card = sa.getSourceCard(); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); sb.append("Put "); if (params.containsKey("UpTo")) { @@ -328,7 +328,7 @@ public class AbilityFactoryCounters { } // TODO handle proper calculation of X values based on Cost - int amount = AbilityFactory.calculateAmount(af.getHostCard(), amountStr, sa); + int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), amountStr, sa); if (amountStr.equals("X") && source.getSVar(amountStr).equals("Count$xPaid")) { // Set PayX here to maximum value. @@ -428,7 +428,7 @@ public class AbilityFactoryCounters { Card choice = null; final String type = params.get("CounterType"); final String amountStr = params.get("CounterNum"); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), amountStr, sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), amountStr, sa); final Player player = af.isCurse() ? AllZone.getHumanPlayer() : AllZone.getComputerPlayer(); @@ -533,7 +533,7 @@ public class AbilityFactoryCounters { final Player player = af.isCurse() ? AllZone.getHumanPlayer() : AllZone.getComputerPlayer(); final String type = params.get("CounterType"); final String amountStr = params.get("CounterNum"); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), amountStr, sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), amountStr, sa); if (abTgt == null) { // No target. So must be defined @@ -689,9 +689,9 @@ public class AbilityFactoryCounters { private static void putResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); final String type = params.get("CounterType"); - int counterAmount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + int counterAmount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); final int max = params.containsKey("MaxFromEffect") ? Integer.parseInt(params.get("MaxFromEffect")) : -1; if (params.containsKey("UpTo")) { @@ -862,7 +862,7 @@ public class AbilityFactoryCounters { */ private static String removeStackDescription(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); final StringBuilder sb = new StringBuilder(); if (!(sa instanceof AbilitySub)) { @@ -873,7 +873,7 @@ public class AbilityFactoryCounters { final String counterName = params.get("CounterType"); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); sb.append("Remove "); if (params.containsKey("UpTo")) { @@ -968,7 +968,7 @@ public class AbilityFactoryCounters { } // TODO handle proper calculation of X values based on Cost - // final int amount = calculateAmount(af.getHostCard(), amountStr, sa); + // final int amount = calculateAmount(sa.getSourceCard(), amountStr, sa); // prevent run-away activations - first time will always return true boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); @@ -1023,7 +1023,7 @@ public class AbilityFactoryCounters { // AllZone.getComputerPlayer(); // TODO handle proper calculation of X values based on Cost - // final int amount = calculateAmount(af.getHostCard(), amountStr, sa); + // final int amount = calculateAmount(sa.getSourceCard(), amountStr, sa); // prevent run-away activations - first time will always return true boolean chance = true; @@ -1088,9 +1088,9 @@ public class AbilityFactoryCounters { private static void removeResolve(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); - final Card card = af.getHostCard(); + final Card card = sa.getSourceCard(); final String type = params.get("CounterType"); - int counterAmount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + int counterAmount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); ArrayList tgtCards; @@ -1420,7 +1420,7 @@ public class AbilityFactoryCounters { CardList hperms = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); CardList cperms = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - if (af.getHostCard().getController().isHuman()) { + if (sa.getSourceCard().getController().isHuman()) { cperms.addAll(hperms); final CardList unchosen = cperms; AllZone.getInputControl().setInput(new Input() { @@ -1699,7 +1699,7 @@ public class AbilityFactoryCounters { } final Counters cType = Counters.valueOf(params.get("CounterType")); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); sb.append("Put ").append(amount).append(" ").append(cType.getName()).append(" counter"); if (amount != 1) { @@ -1785,7 +1785,7 @@ public class AbilityFactoryCounters { amount = ComputerUtil.determineLeftoverMana(sa); source.setSVar("PayX", Integer.toString(amount)); } else { - amount = AbilityFactory.calculateAmount(af.getHostCard(), amountStr, sa); + amount = AbilityFactory.calculateAmount(sa.getSourceCard(), amountStr, sa); } // prevent run-away activations - first time will always return true @@ -1875,7 +1875,7 @@ public class AbilityFactoryCounters { final HashMap params = af.getMapParams(); final String type = params.get("CounterType"); - final int counterAmount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + final int counterAmount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); final String valid = params.get("ValidCards"); CardList cards = AllZoneUtil.getCardsIn(ZoneType.Battlefield); @@ -2030,7 +2030,7 @@ public class AbilityFactoryCounters { } final Counters cType = Counters.valueOf(params.get("CounterType")); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); String amountString = Integer.toString(amount); if (params.containsKey("AllCounters")) { @@ -2098,7 +2098,7 @@ public class AbilityFactoryCounters { final HashMap params = af.getMapParams(); final String type = params.get("CounterType"); - int counterAmount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + int counterAmount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); final String valid = params.get("ValidCards"); CardList cards = AllZoneUtil.getCardsIn(ZoneType.Battlefield); @@ -2243,7 +2243,7 @@ public class AbilityFactoryCounters { private static String moveCounterStackDescription(final AbilityFactory af, final SpellAbility sa) { final HashMap params = af.getMapParams(); final StringBuilder sb = new StringBuilder(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); if (sa instanceof AbilitySub) { sb.append(" "); @@ -2266,7 +2266,7 @@ public class AbilityFactoryCounters { } final Counters cType = Counters.valueOf(params.get("CounterType")); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); sb.append("Move ").append(amount).append(" ").append(cType.getName()).append(" counter"); if (amount != 1) { @@ -2305,7 +2305,7 @@ public class AbilityFactoryCounters { final String amountStr = params.get("CounterNum"); // TODO handle proper calculation of X values based on Cost - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), amountStr, sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), amountStr, sa); // don't use it if no counters to add if (amount <= 0) { @@ -2365,7 +2365,7 @@ public class AbilityFactoryCounters { private static boolean moveCounterDoTriggerAI(final AbilityFactory af, final SpellAbility sa, final boolean mandatory) { final HashMap params = af.getMapParams(); - final Card host = af.getHostCard(); + final Card host = sa.getSourceCard(); final Target abTgt = sa.getTarget(); final String type = params.get("CounterType"); final String amountStr = params.get("CounterNum"); @@ -2469,7 +2469,7 @@ public class AbilityFactoryCounters { final Card host = af.getHostCard(); final Counters cType = Counters.valueOf(params.get("CounterType")); - final int amount = AbilityFactory.calculateAmount(af.getHostCard(), params.get("CounterNum"), sa); + final int amount = AbilityFactory.calculateAmount(sa.getSourceCard(), params.get("CounterNum"), sa); final ArrayList srcCards = AbilityFactory.getDefinedCards(host, params.get("Source"), sa); Card source = null; diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java index 2a76ac77300..6661707d7ec 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryPlay.java @@ -25,6 +25,7 @@ import java.util.Random; import forge.AllZone; import forge.AllZoneUtil; import forge.Card; +import forge.CardCharactersticName; import forge.CardList; import forge.CardListFilter; import forge.GameActionUtil; @@ -326,6 +327,7 @@ public final class AbilityFactoryPlay { Player activator = sa.getActivatingPlayer(); boolean optional = params.containsKey("Optional"); boolean remember = params.containsKey("RememberPlayed"); + boolean wasFaceDown = false; int amount = 1; if (params.containsKey("Amount")) { amount = AbilityFactory.calculateAmount(source, params.get("Amount"), sa); @@ -392,13 +394,23 @@ public final class AbilityFactoryPlay { } } } + if (tgtCard.isFaceDown()) { + tgtCard.setState(CardCharactersticName.Original); + wasFaceDown = true; + } final StringBuilder sb = new StringBuilder(); sb.append("Do you want to play " + tgtCard + "?"); if (controller.isHuman() && optional && !GameActionUtil.showYesNoDialog(source, sb.toString())) { // i--; // This causes an infinite loop (ArsenalNut) + if (wasFaceDown) { + tgtCard.setState(CardCharactersticName.FaceDown); + } continue; } + if (params.containsKey("ForgetRemembered")) { + source.clearRemembered(); + } // lands will be played if (tgtCard.isLand()) { controller.playLand(tgtCard); diff --git a/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java b/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java index 713dd7f54cc..cd075e001df 100644 --- a/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java +++ b/src/main/java/forge/card/abilityfactory/AbilityFactoryReveal.java @@ -33,6 +33,7 @@ import forge.CardList; import forge.CardUtil; import forge.GameActionUtil; import forge.Singletons; +import forge.card.cardfactory.CardFactoryUtil; import forge.card.cost.Cost; import forge.card.cost.CostUtil; import forge.card.spellability.AbilityActivated; @@ -341,6 +342,8 @@ public final class AbilityFactoryReveal { int destZone1ChangeNum = 1; final boolean mitosis = params.containsKey("Mitosis"); String changeValid = params.containsKey("ChangeValid") ? params.get("ChangeValid") : ""; + //andOrValid is for cards with "creature card and/or a land card" + String andOrValid = params.containsKey("AndOrValid") ? params.get("AndOrValid") : ""; final boolean anyNumber = params.containsKey("AnyNumber"); final int libraryPosition2 = params.containsKey("LibraryPosition2") ? Integer.parseInt(params @@ -375,247 +378,249 @@ public final class AbilityFactoryReveal { params.get("Choser"), sa); if (!chosers.isEmpty()) { choser = chosers.get(0); - System.out.println("choser: " + choser); } } for (final Player p : tgtPlayers) { - if ((tgt == null) || p.canBeTargetedBy(sa)) { + if (tgt != null && !p.canBeTargetedBy(sa)) { + continue; + } + final CardList top = new CardList(); + CardList valid = new CardList(); + final CardList rest = new CardList(); + final PlayerZone library = p.getZone(ZoneType.Library); - final CardList top = new CardList(); - CardList valid = new CardList(); - final CardList rest = new CardList(); - final PlayerZone library = p.getZone(ZoneType.Library); + numToDig = Math.min(numToDig, library.size()); + for (int i = 0; i < numToDig; i++) { + top.add(library.get(i)); + } - numToDig = Math.min(numToDig, library.size()); - for (int i = 0; i < numToDig; i++) { - top.add(library.get(i)); + if (top.size() > 0) { + final Card dummy = new Card(); + dummy.setName("[No valid cards]"); + boolean cardsRevealed = false; + + if (params.containsKey("Reveal")) { + GuiUtils.chooseOne("Revealing cards from library", top.toArray()); + cardsRevealed = true; + // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray()); + // - for when it exists + } else if (params.containsKey("RevealOptional")) { + String question = "Reveal: "; + for (final Card c : top) { + question += c + " "; + } + if (p.isHuman() && GameActionUtil.showYesNoDialog(host, question)) { + GuiUtils.chooseOne(host + "Revealing cards from library", top.toArray()); + // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray()); + cardsRevealed = true; + } else if (p.isComputer() && (top.get(0).isInstant() || top.get(0).isSorcery())) { + GuiUtils.chooseOne(host + "Revealing cards from library", top.toArray()); + cardsRevealed = true; + } + } else if (params.containsKey("RevealValid")) { + final String revealValid = params.get("RevealValid"); + final CardList toReveal = top.getValidCards(revealValid, host.getController(), host); + if (!toReveal.isEmpty()) { + GuiUtils.chooseOne("Revealing cards from library", toReveal.toArray()); + if (params.containsKey("RememberRevealed")) { + for (final Card one : toReveal) { + host.addRemembered(one); + } + } + } + // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray()); + // - for when it exists + } else if (choser.isHuman()) { + // show the user the revealed cards + GuiUtils.chooseOne("Looking at cards from library", top.toArray()); + cardsRevealed = true; } - if (top.size() > 0) { - final Card dummy = new Card(); - dummy.setName("[No valid cards]"); - boolean cardsRevealed = false; + if ((params.containsKey("RememberRevealed")) && cardsRevealed) { + for (final Card one : top) { + host.addRemembered(one); + } + } - if (params.containsKey("Reveal")) { - GuiUtils.chooseOne("Revealing cards from library", top.toArray()); - cardsRevealed = true; - // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray()); - // - for when it exists - } else if (params.containsKey("RevealOptional")) { - String question = "Reveal: "; + if (!noMove) { + CardList movedCards = new CardList(); + CardList andOrCards = new CardList(); + if (mitosis) { + valid = AbilityFactoryReveal.sharesNameWithCardOnBattlefield(top); for (final Card c : top) { - question += c + " "; + rest.add(c); } - if (p.isHuman() && GameActionUtil.showYesNoDialog(host, question)) { - GuiUtils.chooseOne(host + "Revealing cards from library", top.toArray()); - // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray()); - cardsRevealed = true; - } else if (p.isComputer() && (top.get(0).isInstant() || top.get(0).isSorcery())) { - GuiUtils.chooseOne(host + "Revealing cards from library", top.toArray()); - cardsRevealed = true; + } else if (!changeValid.equals("")) { + if (changeValid.contains("ChosenType")) { + changeValid = changeValid.replace("ChosenType", host.getChosenType()); } - } else if (params.containsKey("RevealValid")) { - final String revealValid = params.get("RevealValid"); - final CardList toReveal = top.getValidCards(revealValid, host.getController(), host); - if (!toReveal.isEmpty()) { - GuiUtils.chooseOne("Revealing cards from library", toReveal.toArray()); - if (params.containsKey("RememberRevealed")) { - for (final Card one : toReveal) { - host.addRemembered(one); - } - } + valid = top.getValidCards(changeValid.split(","), host.getController(), host); + if (!andOrValid.equals("")) { + andOrCards = top.getValidCards(andOrValid.split(","), host.getController(), host); + andOrCards.removeAll(valid); + valid.addAll(andOrCards); } - // Singletons.getModel().getGameAction().revealToCopmuter(top.toArray()); - // - for when it exists - } else if (choser.isHuman()) { - // show the user the revealed cards - GuiUtils.chooseOne("Looking at cards from library", top.toArray()); - cardsRevealed = true; + for (final Card c : top) { + rest.add(c); + } + if (valid.isEmpty() && choser.isHuman()) { + valid.add(dummy); + } + } else { + valid = top; } - if ((params.containsKey("RememberRevealed")) && cardsRevealed) { - for (final Card one : top) { - host.addRemembered(one); - } - } - - if (!noMove) { - if (mitosis) { - valid = AbilityFactoryReveal.sharesNameWithCardOnBattlefield(top); - for (final Card c : top) { - if (!valid.contains(c)) { - rest.add(c); + if (changeAll) { + movedCards.addAll(valid); + } else { + int j = 0; + if (choser.isHuman()) { + while ((j < destZone1ChangeNum) || (anyNumber && (j < numToDig))) { + // let user get choice + if (valid.isEmpty()) { + break; } - } - } else if (!changeValid.equals("")) { - if (changeValid.contains("ChosenType")) { - changeValid = changeValid.replace("ChosenType", host.getChosenType()); - } - valid = top.getValidCards(changeValid.split(","), host.getController(), host); - for (final Card c : top) { - if (!valid.contains(c)) { - rest.add(c); + Card chosen = null; + String prompt = "Choose a card to put into the "; + if (destZone1.equals(ZoneType.Library) && (libraryPosition == -1)) { + prompt = "Chose a card to put on the bottom of the "; } - } - if (valid.isEmpty()) { - valid.add(dummy); - } - } else { - valid = top; - } - - if (changeAll) { - for (final Card c : valid) { - if (c.equals(dummy)) { - continue; + if (destZone1.equals(ZoneType.Library) && (libraryPosition == 0)) { + prompt = "Chose a card to put on top of the "; } - final PlayerZone zone = c.getOwner().getZone(destZone1); - if (zone.is(ZoneType.Library)) { - Singletons.getModel().getGameAction().moveToLibrary(c, libraryPosition); + if (anyNumber || optional) { + chosen = GuiUtils.chooseOneOrNone(prompt + destZone1, valid.toArray()); } else { - Singletons.getModel().getGameAction().moveTo(zone, c); - if (destZone1.equals(ZoneType.Battlefield) && params.containsKey("Tapped")) { - c.setTapped(true); + chosen = GuiUtils.chooseOne(prompt + destZone1, valid.toArray()); + } + if ((chosen == null) || chosen.getName().equals("[No valid cards]")) { + break; + } + movedCards.add(chosen); + valid.remove(chosen); + if (!andOrValid.equals("")) { + andOrCards.remove(chosen); + if (!chosen.isValid(andOrValid.split(","), host.getController(), host)) { + valid = andOrCards; + } else if (!chosen.isValid(changeValid.split(","), host.getController(), host)) { + valid.removeAll(andOrCards); } } - if (params.containsKey("ForgetOtherRemembered")) { - host.clearRemembered(); - } - if (params.containsKey("RememberChanged")) { - host.addRemembered(c); - } + // Singletons.getModel().getGameAction().revealToComputer() + // - for when this exists + j++; } - } else { - int j = 0; - if (choser.isHuman()) { - while ((j < destZone1ChangeNum) || (anyNumber && (j < numToDig))) { - // let user get choice - Card chosen = null; - String prompt = "Choose a card to put into the "; - if (destZone1.equals(ZoneType.Library) && (libraryPosition == -1)) { - prompt = "Chose a card to put on the bottom of the "; - } - if (destZone1.equals(ZoneType.Library) && (libraryPosition == 0)) { - prompt = "Chose a card to put on top of the "; - } - if (anyNumber || optional) { - chosen = GuiUtils.chooseOneOrNone(prompt + destZone1, valid.toArray()); - } else { - chosen = GuiUtils.chooseOne(prompt + destZone1, valid.toArray()); - } - if ((chosen == null) || chosen.getName().equals("[No valid cards]")) { - break; - } - valid.remove(chosen); - final PlayerZone zone = chosen.getOwner().getZone(destZone1); - if (zone.is(ZoneType.Library)) { - // System.out.println("Moving to lib position: "+libraryPosition); - Singletons.getModel().getGameAction().moveToLibrary(chosen, libraryPosition); - } else { - final Card c = Singletons.getModel().getGameAction().moveTo(zone, chosen); - if (destZone1.equals(ZoneType.Battlefield) && !keywords.isEmpty()) { - for (final String kw : keywords) { - c.addExtrinsicKeyword(kw); - } - if (params.containsKey("Tapped")) { - c.setTapped(true); - } - } - if (params.containsKey("ExileFaceDown")) { - c.setState(CardCharactersticName.FaceDown); - } - if (params.containsKey("Imprint")) { - host.addImprinted(c); - } - } - // Singletons.getModel().getGameAction().revealToComputer() - // - for when this exists - j++; - } - } // human - else { // computer (pick the first cards) - int changeNum = Math.min(destZone1ChangeNum, valid.size()); - if (anyNumber) { - changeNum = valid.size(); // always take all - } - for (j = 0; j < changeNum; j++) { - final Card chosen = valid.get(0); - if (chosen.equals(dummy)) { - break; - } - final PlayerZone zone = chosen.getOwner().getZone(destZone1); - if (zone.is(ZoneType.Library)) { - Singletons.getModel().getGameAction().moveToLibrary(chosen, libraryPosition); - } else { - final Card c = Singletons.getModel().getGameAction().moveTo(zone, chosen); - if (destZone1.equals(ZoneType.Battlefield) && !keywords.isEmpty()) { - for (final String kw : keywords) { - chosen.addExtrinsicKeyword(kw); - } - if (params.containsKey("Tapped")) { - c.setTapped(true); - } - } - } - if (changeValid.length() > 0) { - GuiUtils.chooseOne("Computer picked: ", chosen); - } - valid.remove(chosen); - } + } // human + else { // computer + int changeNum = Math.min(destZone1ChangeNum, valid.size()); + if (anyNumber) { + changeNum = valid.size(); // always take all } - } - - // dump anything not selected from valid back into the - // rest - if (!changeAll) { - rest.addAll(valid); - } - if (rest.contains(dummy)) { - rest.remove(dummy); - } - - // now, move the rest to destZone2 - if (destZone2.equals(ZoneType.Library)) { - if (choser.isHuman()) { - // put them in any order - while (rest.size() > 0) { - Card chosen; - if (rest.size() > 1) { - String prompt = "Put the rest on top of the library in any order"; - if (libraryPosition2 == -1) { - prompt = "Put the rest on the bottom of the library in any order"; - } - chosen = GuiUtils.chooseOne(prompt, rest.toArray()); - } else { - chosen = rest.get(0); - } - Singletons.getModel().getGameAction().moveToLibrary(chosen, libraryPosition2); - rest.remove(chosen); + for (j = 0; j < changeNum; j++) { + Card chosen = CardFactoryUtil.getBestAI(valid); + if (sa.getActivatingPlayer().isHuman() && p.isHuman()) { + chosen = CardFactoryUtil.getWorstAI(valid); } - } else { // Computer - for (int i = 0; i < rest.size(); i++) { - Singletons.getModel().getGameAction().moveToLibrary(rest.get(i), libraryPosition2); + if (chosen == null) { + break; } - } - } else { - // just move them randomly - for (int i = 0; i < rest.size(); i++) { - Card c = rest.get(i); - final PlayerZone toZone = c.getOwner().getZone(destZone2); - c = Singletons.getModel().getGameAction().moveTo(toZone, c); - if (destZone2.equals(ZoneType.Battlefield) && !keywords.isEmpty()) { - for (final String kw : keywords) { - c.addExtrinsicKeyword(kw); + if (changeValid.length() > 0) { + GuiUtils.chooseOne("Computer picked: ", chosen); + } + movedCards.add(chosen); + valid.remove(chosen); + if (!andOrValid.equals("")) { + andOrCards.remove(chosen); + if (!chosen.isValid(andOrValid.split(","), host.getController(), host)) { + valid = andOrCards; + } else if (!chosen.isValid(changeValid.split(","), host.getController(), host)) { + valid.removeAll(andOrCards); } } } - } } - } // end if canBeTargetedBy - } // end foreach player - } + if (params.containsKey("ForgetOtherRemembered")) { + host.clearRemembered(); + } + movedCards.reverse(); + for (Card c : movedCards) { + if (c.equals(dummy)) { + continue; + } + final PlayerZone zone = c.getOwner().getZone(destZone1); + if (zone.is(ZoneType.Library)) { + Singletons.getModel().getGameAction().moveToLibrary(c, libraryPosition); + } else { + c = Singletons.getModel().getGameAction().moveTo(zone, c); + if (destZone1.equals(ZoneType.Battlefield)) { + for (final String kw : keywords) { + c.addExtrinsicKeyword(kw); + } + if (params.containsKey("Tapped")) { + c.setTapped(true); + } + } + if (params.containsKey("ExileFaceDown")) { + c.setState(CardCharactersticName.FaceDown); + } + if (params.containsKey("Imprint")) { + host.addImprinted(c); + } + } + if (params.containsKey("ForgetOtherRemembered")) { + host.clearRemembered(); + } + if (params.containsKey("RememberChanged")) { + host.addRemembered(c); + } + rest.remove(c); + } + if (rest.contains(dummy)) { + rest.remove(dummy); + } + + // now, move the rest to destZone2 + if (destZone2.equals(ZoneType.Library)) { + if (choser.isHuman()) { + // put them in any order + while (rest.size() > 0) { + Card chosen; + if (rest.size() > 1) { + String prompt = "Put the rest on top of the library in any order"; + if (libraryPosition2 == -1) { + prompt = "Put the rest on the bottom of the library in any order"; + } + chosen = GuiUtils.chooseOne(prompt, rest.toArray()); + } else { + chosen = rest.get(0); + } + Singletons.getModel().getGameAction().moveToLibrary(chosen, libraryPosition2); + rest.remove(chosen); + } + } else { // Computer + for (int i = 0; i < rest.size(); i++) { + Singletons.getModel().getGameAction().moveToLibrary(rest.get(i), libraryPosition2); + } + } + } else { + // just move them randomly + for (int i = 0; i < rest.size(); i++) { + Card c = rest.get(i); + final PlayerZone toZone = c.getOwner().getZone(destZone2); + c = Singletons.getModel().getGameAction().moveTo(toZone, c); + if (destZone2.equals(ZoneType.Battlefield) && !keywords.isEmpty()) { + for (final String kw : keywords) { + c.addExtrinsicKeyword(kw); + } + } + } + + } + } + } + } // end foreach player } // end resolve // returns a CardList that is a subset of list with cards that share a name @@ -2278,37 +2283,4 @@ public final class AbilityFactoryReveal { return chosen; } - /* - * private static CardList getRevealedList(final Card card, final - * SpellAbility sa, final CardList valid) { final CardList revealed = new - * CardList(); if (sa.getActivatingPlayer().isComputer()) { //not really - * implemented for computer //would need - * GuiUtils.getChoice("Revealed card(s)", revealed.toArray()); } else { - * AllZone.getInputControl().setInput(new Input() { private static final - * long serialVersionUID = 3851585340769670736L; - * - * @Override public void showMessage() { //in case hand is empty, don't do - * anything if (card.getController().getCardsIn(Zone.Hand).size() == 0) - * stop(); - * - * AllZone.getDisplay().showMessage(card.getName() + - * " - Reveal a card. Revealed " + revealed.size() + - * " so far. Click OK when done."); ButtonUtil.enableOnlyOK(); } - * - * @Override public void selectCard(Card c, PlayerZone zone) { if - * (zone.is(Constant.Zone.Hand) && valid.contains(c) && - * !revealed.contains(c)) { revealed.add(c); - * - * //in case no more cards in hand to reveal if (revealed.size() == - * card.getController().getCardsIn(Zone.Hand).size()) { done(); } else { - * showMessage(); } } } - * - * @Override public void selectButtonOK() { done(); } - * - * void done() { stop(); GuiUtils.getChoice("Revealed card(s)", - * revealed.toArray()); } }); } - * - * return revealed; } - */ - } // end class AbilityFactory_Reveal diff --git a/src/main/java/forge/card/cardfactory/AbstractCardFactory.java b/src/main/java/forge/card/cardfactory/AbstractCardFactory.java index 8493a3beed2..46e08164541 100644 --- a/src/main/java/forge/card/cardfactory/AbstractCardFactory.java +++ b/src/main/java/forge/card/cardfactory/AbstractCardFactory.java @@ -406,7 +406,7 @@ public abstract class AbstractCardFactory implements CardFactoryInterface { final String cardName = card.getName(); if (!card.isCardColorsOverridden()) { - card.addColor(card.getManaCost()); + card.addColor(card.getManaCost().toString()); } // may have to change the spell diff --git a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java index 8a7413e6cb8..86a8978ca4a 100644 --- a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java +++ b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java @@ -285,8 +285,7 @@ public class CardFactorySorceries { Card biggest = exiled.get(0); for (final Card c : exiled) { - if (CardUtil.getConvertedManaCost(biggest.getManaCost()) < CardUtil.getConvertedManaCost(c - .getManaCost())) { + if (biggest.getManaCost().getCMC() < c.getManaCost().getCMC() ) { biggest = c; } } diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 00f00e31f75..f068d8f5b04 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -43,6 +43,7 @@ import forge.Singletons; import forge.card.abilityfactory.AbilityFactory; import forge.card.cost.Cost; import forge.card.mana.ManaCost; +import forge.card.mana.ManaCostShard; import forge.card.spellability.Ability; import forge.card.spellability.AbilityActivated; import forge.card.spellability.AbilityMana; @@ -197,8 +198,7 @@ public class CardFactoryUtil { cheapest = all.get(0); for (int i = 0; i < all.size(); i++) { - if (CardUtil.getConvertedManaCost(cheapest.getManaCost()) <= CardUtil.getConvertedManaCost(cheapest - .getManaCost())) { + if (cheapest.getManaCost().getCMC() <= cheapest.getManaCost().getCMC()) { cheapest = all.get(i); } } @@ -306,7 +306,7 @@ public class CardFactoryUtil { int bigCMC = 0; for (int i = 0; i < all.size(); i++) { - final int curCMC = CardUtil.getConvertedManaCost(all.get(i).getManaCost()); + final int curCMC = all.get(i).getManaCost().getCMC(); if (curCMC > bigCMC) { bigCMC = curCMC; @@ -340,7 +340,7 @@ public class CardFactoryUtil { int bigCMC = 0; for (int i = 0; i < all.size(); i++) { - final int curCMC = CardUtil.getConvertedManaCost(all.get(i).getManaCost()); + final int curCMC = all.get(i).getManaCost().getCMC(); if (curCMC > bigCMC) { bigCMC = curCMC; @@ -694,6 +694,19 @@ public class CardFactoryUtil { return biggest; } + /** + *

+ * getWorstAI. + *

+ * + * @param list + * a {@link forge.CardList} object. + * @return a {@link forge.Card} object. + */ + public static Card getWorstAI(final CardList list) { + return CardFactoryUtil.getWorstPermanentAI(list, false, false, false, true); + } + // returns null if list.size() == 0 /** *

@@ -908,17 +921,15 @@ public class CardFactoryUtil { * a {@link forge.Card} object. * @param cost * a {@link forge.card.cost.Cost} object. - * @param orgManaCost - * a {@link java.lang.String} object. * @param a * a int. * @param d * a int. * @return a {@link forge.card.spellability.AbilityActivated} object. */ - public static AbilityStatic abilityMorphUp(final Card sourceCard, final Cost cost, final String orgManaCost, - final int a, final int d) { + public static AbilityStatic abilityMorphUp(final Card sourceCard, final Cost cost, final int a, final int d) { final AbilityStatic morphUp = new AbilityStatic(sourceCard, cost, null) { + @Override public void resolve() { if (sourceCard.turnFaceUp()) { @@ -1049,8 +1060,7 @@ public class CardFactoryUtil { final CardList sameCost = new CardList(); for (int i = 0; i < cards.size(); i++) { - if (CardUtil.getConvertedManaCost(cards.get(i).getManaCost()) == CardUtil - .getConvertedManaCost(sourceCard.getManaCost())) { + if (cards.get(i).getManaCost().getCMC() == sourceCard.getManaCost().getCMC()) { sameCost.add(cards.get(i)); } } @@ -1453,8 +1463,7 @@ public class CardFactoryUtil { final CardList sameCost = new CardList(); final int cost = CardUtil.getConvertedManaCost(manacost); for (int i = 0; i < cards.size(); i++) { - if ((CardUtil.getConvertedManaCost(cards.get(i).getManaCost()) <= cost) - && cards.get(i).isType("Spirit")) { + if (cards.get(i).getManaCost().getCMC() <= cost && cards.get(i).isType("Spirit")) { sameCost.add(cards.get(i)); } } @@ -1881,7 +1890,7 @@ public class CardFactoryUtil { for (int i = 0; i < cards.size(); i++) { final Card c = cards.get(i); if (!c.isToken()) { - String manaCost = c.getManaCost(); + String manaCost = c.getManaCost().toString(); manaCost = manaCost.trim(); count += CardFactoryUtil.countOccurrences(manaCost, colorAbb); } @@ -3092,7 +3101,7 @@ public class CardFactoryUtil { int mmc = 0; int cmc = 0; for (int i = 0; i < someCards.size(); i++) { - cmc = CardUtil.getConvertedManaCost(someCards.getCard(i).getManaCost()); + cmc = someCards.getCard(i).getManaCost().getCMC(); if (cmc > mmc) { mmc = cmc; } @@ -3584,7 +3593,7 @@ public class CardFactoryUtil { final String[] tokenKeywords = new String[kal.size()]; kal.toArray(tokenKeywords); final CardList tokens = CardFactoryUtil.makeToken(thisToken.getName(), thisToken.getImageName(), - thisToken.getController(), thisToken.getManaCost(), tokenTypes, thisToken.getBaseAttack(), + thisToken.getController(), thisToken.getManaCost().toString(), tokenTypes, thisToken.getBaseAttack(), thisToken.getBaseDefense(), tokenKeywords); for (final Card token : tokens) { @@ -3896,7 +3905,7 @@ public class CardFactoryUtil { final String bbCost = card.getSVar("Buyback"); if (!bbCost.equals("")) { final SpellAbility bbSA = sa.copy(); - final String newCost = CardUtil.addManaCosts(card.getManaCost(), bbCost); + final String newCost = CardUtil.addManaCosts(card.getManaCost().toString(), bbCost); if (bbSA.getPayCosts() != null) { // create new Cost bbSA.setPayCosts(new Cost(card, newCost, false)); @@ -3952,7 +3961,7 @@ public class CardFactoryUtil { final String[] k = parse.split(":"); final String kickerCost = k[1]; - final ManaCost mc = new ManaCost(card.getManaCost()); + final ManaCost mc = new ManaCost(card.getManaCost().toString()); mc.combineManaCost(kickerCost); kickedSpell.setKickerAbility(true); @@ -4130,15 +4139,11 @@ public class CardFactoryUtil { } } // Suspend - if (card.getManaCost().contains("X")) { + int xCount = card.getManaCost().getShardCount(ManaCostShard.X); + if (xCount > 0) { final SpellAbility sa = card.getSpellAbility()[0]; sa.setIsXCost(true); - - if (card.getManaCost().startsWith("X X")) { - sa.setXManaCost("2"); - } else if (card.getManaCost().startsWith("X")) { - sa.setXManaCost("1"); - } + sa.setXManaCost(Integer.toString(xCount)); } // X int cardnameSpot = CardFactoryUtil.hasKeyword(card, "CARDNAME is "); @@ -4686,13 +4691,11 @@ public class CardFactoryUtil { final int attack = card.getBaseAttack(); final int defense = card.getBaseDefense(); - final String orgManaCost = card.getManaCost(); - card.addSpellAbility(CardFactoryUtil.abilityMorphDown(card)); card.turnFaceDown(); - card.addSpellAbility(CardFactoryUtil.abilityMorphUp(card, cost, orgManaCost, attack, defense)); + card.addSpellAbility(CardFactoryUtil.abilityMorphUp(card, cost, attack, defense)); card.turnFaceUp(); } diff --git a/src/main/java/forge/card/cost/Cost.java b/src/main/java/forge/card/cost/Cost.java index 5db2f3dfd36..3afd3a07b38 100644 --- a/src/main/java/forge/card/cost/Cost.java +++ b/src/main/java/forge/card/cost/Cost.java @@ -23,6 +23,7 @@ import java.util.regex.Pattern; import forge.Card; import forge.Counters; import forge.Singletons; +import forge.card.CardManaCost; import forge.card.mana.ManaCost; import forge.card.spellability.SpellAbility; import forge.game.zone.ZoneType; @@ -144,6 +145,11 @@ public class Cost { private static final String RETURN_STR = "Return<"; private static final String REVEAL_STR = "Reveal<"; + + public Cost(final Card card, CardManaCost cost, final boolean bAbility) { + this(card, cost.toString(), bAbility); + } + /** *

* Constructor for Cost. diff --git a/src/main/java/forge/card/spellability/SpellAbility.java b/src/main/java/forge/card/spellability/SpellAbility.java index cc17076de2e..67d48b0412c 100644 --- a/src/main/java/forge/card/spellability/SpellAbility.java +++ b/src/main/java/forge/card/spellability/SpellAbility.java @@ -25,6 +25,7 @@ import forge.CardList; import forge.Command; import forge.CommandArgs; import forge.GameEntity; +import forge.card.CardManaCost; import forge.card.abilityfactory.AbilityFactory; import forge.card.cost.Cost; import forge.card.mana.Mana; @@ -267,10 +268,14 @@ public abstract class SpellAbility { * @param cost * a {@link java.lang.String} object. */ - public void setManaCost(final String cost) { - this.manaCost = cost; + public void setManaCost(final CardManaCost cost) { + this.manaCost = cost.toString(); } + public void setManaCost(final String cost) { + this.manaCost = cost; + } + /** *

* Getter for the field additionalManaCost. diff --git a/src/main/java/forge/card/spellability/SpellAbilityRequirements.java b/src/main/java/forge/card/spellability/SpellAbilityRequirements.java index 541f30bd438..3ac6c6a828f 100644 --- a/src/main/java/forge/card/spellability/SpellAbilityRequirements.java +++ b/src/main/java/forge/card/spellability/SpellAbilityRequirements.java @@ -148,7 +148,7 @@ public class SpellAbilityRequirements { } this.select.resetTargets(); - AllZone.getStack().clearFrozen(); + AllZone.getStack().removeFromFrozenStack(this.ability); return; } else { this.needPayment(); diff --git a/src/main/java/forge/card/spellability/SpellAbilityRestriction.java b/src/main/java/forge/card/spellability/SpellAbilityRestriction.java index 61e3944f702..2d64044f490 100644 --- a/src/main/java/forge/card/spellability/SpellAbilityRestriction.java +++ b/src/main/java/forge/card/spellability/SpellAbilityRestriction.java @@ -118,7 +118,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { } if (params.containsKey("ActivationLimit")) { - this.setActivationLimit(Integer.parseInt(params.get("ActivationLimit"))); + this.setLimitToCheck(params.get("ActivationLimit")); } if (params.containsKey("ActivationNumberSacrifice")) { @@ -307,8 +307,15 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { return false; } - if ((this.getActivationLimit() != -1) && (this.getNumberTurnActivations() >= this.getActivationLimit())) { - return false; + if (this.getLimitToCheck() != null) { + String limit = this.getLimitToCheck(); + int activationLimit = limit.matches("[0-9][0-9]?") + ? Integer.parseInt(limit) : AbilityFactory.calculateAmount(c, limit, sa); + this.setActivationLimit(activationLimit); + + if ((this.getActivationLimit() != -1) && (this.getNumberTurnActivations() >= this.getActivationLimit())) { + return false; + } } if (this.getCardsInHand() != -1) { diff --git a/src/main/java/forge/card/spellability/SpellAbilityVariables.java b/src/main/java/forge/card/spellability/SpellAbilityVariables.java index d2d00dec44c..b1b98eda931 100644 --- a/src/main/java/forge/card/spellability/SpellAbilityVariables.java +++ b/src/main/java/forge/card/spellability/SpellAbilityVariables.java @@ -112,6 +112,9 @@ public class SpellAbilityVariables { /** The activation limit. */ private int activationLimit = -1; + /** The limitToCheck to check. */ + private String limitToCheck = null; + /** The number turn activations. */ private int numberTurnActivations = 0; @@ -633,6 +636,30 @@ public class SpellAbilityVariables { return this.activationLimit; } + /** + *

+ * Setter for the field limitToCheck. + *

+ * + * @param limit + * a {@link java.lang.String} object. + */ + public final void setLimitToCheck(final String limit) { + this.limitToCheck = limit; + } + + /** + *

+ * Getter for the field limitToCheck. + *

+ * + * @return the limitToCheck + * a {@link java.lang.String} object. + */ + public final String getLimitToCheck() { + return this.limitToCheck; + } + /** * Checks if is threshold. * diff --git a/src/main/java/forge/card/spellability/SpellPermanent.java b/src/main/java/forge/card/spellability/SpellPermanent.java index 928074e006c..426fb7bd48d 100644 --- a/src/main/java/forge/card/spellability/SpellPermanent.java +++ b/src/main/java/forge/card/spellability/SpellPermanent.java @@ -23,7 +23,6 @@ import forge.AllZone; import forge.AllZoneUtil; import forge.Card; import forge.CardList; -import forge.CardUtil; import forge.Command; import forge.CommandReturn; import forge.Singletons; @@ -277,63 +276,9 @@ public class SpellPermanent extends Spell { card.setSVar("PayX", Integer.toString(xPay)); } // Wait for Main2 if possible - if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.MAIN1)) { - boolean wait = true; - if (card.getSVar("PlayMain1").equals("TRUE")) { - wait = false; - } - if ((card.isCreature() && (ComputerAIGeneral.hasACardGivingHaste() - || card.hasKeyword("Haste"))) || card.hasKeyword("Exalted")) { - wait = false; - } - if (card.hasKeyword("Soulbond") && !AllZoneUtil.getCreaturesInPlay(AllZone.getComputerPlayer()).isEmpty()) { - wait = false; - } - // get all cards the computer controls with BuffedBy - final CardList buffed = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); - for (int j = 0; j < buffed.size(); j++) { - final Card buffedcard = buffed.get(j); - if (buffedcard.getSVar("BuffedBy").length() > 0) { - final String buffedby = buffedcard.getSVar("BuffedBy"); - final String[] bffdby = buffedby.split(","); - if (card.isValid(bffdby, buffedcard.getController(), buffedcard)) { - wait = false; - } - } - } // BuffedBy - - // get all cards the human controls with AntiBuffedBy - final CardList antibuffed = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); - for (int k = 0; k < antibuffed.size(); k++) { - final Card buffedcard = antibuffed.get(k); - if (buffedcard.getSVar("AntiBuffedBy").length() > 0) { - final String buffedby = buffedcard.getSVar("AntiBuffedBy"); - final String[] bffdby = buffedby.split(","); - if (card.isValid(bffdby, buffedcard.getController(), buffedcard)) { - wait = false; - } - } - } // AntiBuffedBy - final CardList vengevines = AllZone.getComputerPlayer().getCardsIn(ZoneType.Graveyard, "Vengevine"); - if (vengevines.size() > 0) { - final CardList creatures = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); - final CardList creatures2 = new CardList(); - for (int i = 0; i < creatures.size(); i++) { - if (creatures.get(i).isCreature() - && (CardUtil.getConvertedManaCost(creatures.get(i).getManaCost()) <= 3)) { - creatures2.add(creatures.get(i)); - } - } - if (((creatures2.size() + CardUtil.getThisTurnCast("Creature.YouCtrl", vengevines.get(0)) - .size()) > 1) - && card.isCreature() - && (CardUtil.getConvertedManaCost(card.getManaCost()) <= 3)) { - wait = false; - } - } // AI Improvement for Vengevine Beached As End - if (wait) { - return false; - } + if (Singletons.getModel().getGameState().getPhaseHandler().is(PhaseType.MAIN1) + && !ComputerUtil.castPermanentInMain1(this)) { + return false; } // save cards with flash for surprise blocking if (card.hasKeyword("Flash") diff --git a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java index 5066cc3eb2a..216465ff5cf 100644 --- a/src/main/java/forge/card/staticability/StaticAbilityContinuous.java +++ b/src/main/java/forge/card/staticability/StaticAbilityContinuous.java @@ -277,19 +277,6 @@ public class StaticAbilityContinuous { } } - // add abilities - if (addAbilities != null) { - for (final String abilty : addAbilities) { - if (abilty.startsWith("AB")) { // grant the ability - final AbilityFactory af = new AbilityFactory(); - final SpellAbility sa = af.getAbility(abilty, affectedCard); - sa.setType("Temporary"); - sa.setOriginalHost(hostCard); - affectedCard.addSpellAbility(sa); - } - } - } - // add SVars if (addSVars != null) { for (final String sVar : addSVars) { @@ -304,6 +291,19 @@ public class StaticAbilityContinuous { } } + // add abilities + if (addAbilities != null) { + for (final String abilty : addAbilities) { + if (abilty.startsWith("AB")) { // grant the ability + final AbilityFactory af = new AbilityFactory(); + final SpellAbility sa = af.getAbility(abilty, affectedCard); + sa.setType("Temporary"); + sa.setOriginalHost(hostCard); + affectedCard.addSpellAbility(sa); + } + } + } + // add Types if ((addTypes != null) || (removeTypes != null)) { affectedCard.addChangedCardTypes(addTypes, removeTypes, removeSuperTypes, removeCardTypes, diff --git a/src/main/java/forge/card/trigger/TriggerAttacks.java b/src/main/java/forge/card/trigger/TriggerAttacks.java index 272aa0ab37d..2a6020f012e 100644 --- a/src/main/java/forge/card/trigger/TriggerAttacks.java +++ b/src/main/java/forge/card/trigger/TriggerAttacks.java @@ -20,9 +20,6 @@ package forge.card.trigger; import java.util.HashMap; import java.util.Map; -import org.apache.commons.lang3.StringUtils; - - import forge.Card; import forge.CardList; import forge.card.spellability.SpellAbility; @@ -64,9 +61,7 @@ public class TriggerAttacks extends Trigger { } if (this.getMapParams().containsKey("Attacked")) { - if (this.getMapParams().get("Attacked").equals("Player") - && StringUtils.isNumeric(runParams2.get("Attacked").toString()) - && (Integer.parseInt(runParams2.get("Attacked").toString()) > 0)) { + if (this.getMapParams().get("Attacked").equals("Player") && (Integer) runParams2.get("Attacked") > 0) { return false; } } diff --git a/src/main/java/forge/card/trigger/TriggerHandler.java b/src/main/java/forge/card/trigger/TriggerHandler.java index e55ffb04743..bc89a92ffd0 100644 --- a/src/main/java/forge/card/trigger/TriggerHandler.java +++ b/src/main/java/forge/card/trigger/TriggerHandler.java @@ -372,10 +372,6 @@ public class TriggerHandler { } //System.out.println( " " + regtrig.getMode().toString() + "@" + regtrig.getHostCard() + "> " + TextUtil.mapToString(params)); - - if (!regtrig.zonesCheck(AllZone.getZoneOf(regtrig.getHostCard()))) { - return false; // Host card isn't where it needs to be. - } if (!regtrig.phasesCheck()) { return false; // It's not the right phase to go off. } @@ -398,14 +394,17 @@ public class TriggerHandler { if (regtrig.isSuppressed()) { return false; // Trigger removed by effect } + if (!regtrig.zonesCheck(AllZone.getZoneOf(regtrig.getHostCard()))) { + return false; // Host card isn't where it needs to be. + } // Torpor Orb check - if (mode.equals(TriggerType.ChangesZone) && AllZoneUtil.isCardInPlay("Torpor Orb")) { + if (mode.equals(TriggerType.ChangesZone)) { if (runParams.get("Destination") instanceof String) { String dest = (String) runParams.get("Destination"); if (dest.equals("Battlefield") && runParams.get("Card") instanceof Card) { Card card = (Card) runParams.get("Card"); - if (card.isCreature()) { + if (card.isCreature() && AllZoneUtil.isCardInPlay("Torpor Orb")) { return false; } } diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java index 7a7bad40025..ab70d685cc1 100644 --- a/src/main/java/forge/control/FControl.java +++ b/src/main/java/forge/control/FControl.java @@ -31,8 +31,12 @@ import javax.swing.WindowConstants; import forge.AllZone; import forge.Singletons; import forge.control.KeyboardShortcuts.Shortcut; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.VDeckEditorUI; +import forge.gui.framework.SOverflowUtil; +import forge.gui.framework.SResizingUtil; import forge.gui.home.VHomeUI; -import forge.gui.home.quest.SubmenuQuestUtil; +import forge.gui.home.quest.SSubmenuQuestUtil; import forge.gui.match.VMatchUI; import forge.gui.match.controllers.CDock; import forge.gui.toolbox.CardFaceSymbols; @@ -55,16 +59,24 @@ public enum FControl { private JLayeredPane display; private int state = -1; - private WindowListener waDefault, waConcede, waLeaveBazaar; + private WindowListener waDefault, waConcede, waLeaveBazaar, waLeaveEditor; /** */ public static final int HOME_SCREEN = 0; /** */ public static final int MATCH_SCREEN = 1; /** */ - public static final int DEFAULT_EDITOR = 2; + public static final int DECK_EDITOR_CONSTRUCTED = 2; /** */ public static final int QUEST_BAZAAR = 3; + /** */ + public static final int DECK_EDITOR_LIMITED = 4; + /** */ + public static final int DECK_EDITOR_QUEST = 5; + /** */ + public static final int QUEST_CARD_SHOP = 6; + /** */ + public static final int DRAFTING_PROCESS = 7; /** *

@@ -75,11 +87,23 @@ public enum FControl { * instantiated separately by each state's top level view class. */ private FControl() { + this.waDefault = new WindowAdapter() { + @Override + public void windowClosing(final WindowEvent e) { + Singletons.getView().getFrame().setDefaultCloseOperation( + WindowConstants.EXIT_ON_CLOSE); + + System.exit(0); + } + }; + // "Close" button override during match this.waConcede = new WindowAdapter() { @Override public void windowClosing(final WindowEvent e) { - Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + Singletons.getView().getFrame().setDefaultCloseOperation( + WindowConstants.DO_NOTHING_ON_CLOSE); + CDock.SINGLETON_INSTANCE.concede(); } }; @@ -88,19 +112,27 @@ public enum FControl { this.waLeaveBazaar = new WindowAdapter() { @Override public void windowClosing(final WindowEvent e) { - Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - changeState(0); - SubmenuQuestUtil.updateStatsAndPet(); + Singletons.getView().getFrame().setDefaultCloseOperation( + WindowConstants.DO_NOTHING_ON_CLOSE); + + changeState(FControl.HOME_SCREEN); + SSubmenuQuestUtil.updateStatsAndPet(); } }; - // Default action on window close - this.waDefault = new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent e) { - Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - } + this.waLeaveEditor = new WindowAdapter() { + @Override + public void windowClosing(final WindowEvent ev) { + Singletons.getView().getFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + + if (CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().exit()) { + changeState(FControl.HOME_SCREEN); + } + } }; + + FView.SINGLETON_INSTANCE.getLpnDocument().addMouseListener(SOverflowUtil.getHideOverflowListener()); + FView.SINGLETON_INSTANCE.getLpnDocument().addComponentListener(SResizingUtil.getWindowResizeListener()); } /** After view and model have been initialized, control can start. */ @@ -117,8 +149,6 @@ public enum FControl { this.shortcuts = KeyboardShortcuts.attachKeyboardShortcuts(); this.display = FView.SINGLETON_INSTANCE.getLpnDocument(); - //Singletons.getView().initialize(); - // Handles resizing in null layouts of layers in JLayeredPane. Singletons.getView().getFrame().addComponentListener(new ComponentAdapter() { @Override @@ -141,17 +171,19 @@ public enum FControl { clearChildren(JLayeredPane.DEFAULT_LAYER); this.state = i0; - /// TODO should these be here? + Singletons.getView().getFrame().removeWindowListener(waDefault); Singletons.getView().getFrame().removeWindowListener(waConcede); Singletons.getView().getFrame().removeWindowListener(waLeaveBazaar); - Singletons.getView().getFrame().addWindowListener(waDefault); + Singletons.getView().getFrame().removeWindowListener(waLeaveEditor); // Fire up new state switch (i0) { case HOME_SCREEN: + Singletons.getView().getFrame().addWindowListener(waDefault); VHomeUI.SINGLETON_INSTANCE.populate(); FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(false); - //sizeChildren(); + VHomeUI.SINGLETON_INSTANCE.updateLayout(); + sizeChildren(); break; case MATCH_SCREEN: @@ -160,8 +192,14 @@ public enum FControl { Singletons.getView().getFrame().addWindowListener(waConcede); break; - case DEFAULT_EDITOR: - display.add(Singletons.getView().getViewEditor(), JLayeredPane.DEFAULT_LAYER); + case DECK_EDITOR_CONSTRUCTED: + case DECK_EDITOR_LIMITED: + case DECK_EDITOR_QUEST: + case QUEST_CARD_SHOP: + case DRAFTING_PROCESS: + VDeckEditorUI.SINGLETON_INSTANCE.populate(); + FView.SINGLETON_INSTANCE.getPnlInsets().setVisible(true); + Singletons.getView().getFrame().addWindowListener(waLeaveEditor); break; case QUEST_BAZAAR: diff --git a/src/main/java/forge/control/input/InputControl.java b/src/main/java/forge/control/input/InputControl.java index b127521e72f..806757362fb 100644 --- a/src/main/java/forge/control/input/InputControl.java +++ b/src/main/java/forge/control/input/InputControl.java @@ -21,13 +21,13 @@ import java.util.LinkedList; import java.util.Stack; import forge.AllZone; -import forge.MyObservable; import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.ComputerAIInput; import forge.game.player.Player; import forge.gui.match.CMatchUI; import forge.model.FModel; +import forge.util.MyObservable; /** *

diff --git a/src/main/java/forge/deck/Deck.java b/src/main/java/forge/deck/Deck.java index ee4cf8a67aa..5413a3823e9 100644 --- a/src/main/java/forge/deck/Deck.java +++ b/src/main/java/forge/deck/Deck.java @@ -33,7 +33,7 @@ import org.apache.commons.lang3.StringUtils; import forge.deck.io.DeckFileHeader; import forge.deck.io.DeckSerializer; -import forge.gui.deckeditor.elements.TableSorter; +import forge.gui.deckeditor.tables.TableSorter; import forge.item.CardPrinted; import forge.item.ItemPoolView; import forge.util.FileSection; diff --git a/src/main/java/forge/game/GameNew.java b/src/main/java/forge/game/GameNew.java index 69ad820af9d..a5f685ebee6 100644 --- a/src/main/java/forge/game/GameNew.java +++ b/src/main/java/forge/game/GameNew.java @@ -490,14 +490,12 @@ public class GameNew { sb.append(ForgeProps.getLocalized(GameActionText.COMPUTER_CUT) + ga.getComputerCut().getName() + " (" + ga.getComputerCut().getManaCost() + ")" + "\r\n"); sb.append("\r\n" + "Number of times the deck has been cut: " + cutCount + "\r\n"); - if (CardUtil.getConvertedManaCost(ga.getComputerCut().getManaCost()) > CardUtil.getConvertedManaCost( - ga.getHumanCut().getManaCost())) { + if (ga.getComputerCut().getManaCost().getCMC() > ga.getHumanCut().getManaCost().getCMC()) { GameNew.computerStartsGame(); JOptionPane.showMessageDialog(null, sb + ForgeProps.getLocalized(GameActionText.COMPUTER_STARTS), "", JOptionPane.INFORMATION_MESSAGE); return; - } else if (CardUtil.getConvertedManaCost(ga.getComputerCut().getManaCost()) < CardUtil - .getConvertedManaCost(ga.getHumanCut().getManaCost())) { + } else if (ga.getComputerCut().getManaCost().getCMC() < ga.getHumanCut().getManaCost().getCMC()) { JOptionPane.showMessageDialog(null, sb + ForgeProps.getLocalized(GameActionText.HUMAN_STARTS), "", JOptionPane.INFORMATION_MESSAGE); return; diff --git a/src/main/java/forge/game/limited/BoosterDraft.java b/src/main/java/forge/game/limited/BoosterDraft.java index 6daa597e514..ab08aae76c0 100644 --- a/src/main/java/forge/game/limited/BoosterDraft.java +++ b/src/main/java/forge/game/limited/BoosterDraft.java @@ -290,7 +290,12 @@ public final class BoosterDraft implements IBoosterDraft { } } // computerChoose() - private int getCurrentBoosterIndex() { + /** + * + * TODO: Write javadoc for this method. + * @return int + */ + public int getCurrentBoosterIndex() { return this.currentBoosterPick % BoosterDraft.N_PLAYERS; } diff --git a/src/main/java/forge/game/limited/BoosterDraftAI.java b/src/main/java/forge/game/limited/BoosterDraftAI.java index 2a192e3ea4e..9a7c5553b72 100644 --- a/src/main/java/forge/game/limited/BoosterDraftAI.java +++ b/src/main/java/forge/game/limited/BoosterDraftAI.java @@ -31,6 +31,9 @@ import forge.CardList; import forge.CardListFilter; import forge.CardListUtil; import forge.Constant; +import forge.card.CardColor; +import forge.card.CardManaCost; +import forge.card.mana.ManaCostShard; import forge.card.spellability.AbilityMana; import forge.deck.Deck; import forge.util.MyRandom; @@ -514,23 +517,22 @@ public class BoosterDraftAI { // count each card color using mana costs // TODO: count hybrid mana differently? for (i = 0; i < outList.size(); i++) { - final String mc = outList.get(i).getManaCost(); + final CardManaCost mc = outList.get(i).getManaCost(); // count each mana symbol in the mana cost - for (int j = 0; j < mc.length(); j++) { - final char c = mc.charAt(j); - - if (c == 'W') { + for (ManaCostShard shard : mc.getShards()) { + byte mask = shard.getColorMask(); + + if ((mask & CardColor.WHITE) > 0 ) clrCnts[0].setCount(clrCnts[0].getCount() + 1); - } else if (c == 'U') { + if ((mask & CardColor.BLUE) > 0 ) clrCnts[1].setCount(clrCnts[1].getCount() + 1); - } else if (c == 'B') { + if ((mask & CardColor.BLACK) > 0 ) clrCnts[2].setCount(clrCnts[2].getCount() + 1); - } else if (c == 'R') { + if ((mask & CardColor.RED) > 0 ) clrCnts[3].setCount(clrCnts[3].getCount() + 1); - } else if (c == 'G') { + if ((mask & CardColor.GREEN) > 0 ) clrCnts[4].setCount(clrCnts[4].getCount() + 1); - } } } diff --git a/src/main/java/forge/game/limited/SealedDeck.java b/src/main/java/forge/game/limited/SealedDeck.java index 62ba544c7e5..af435e5dfaf 100644 --- a/src/main/java/forge/game/limited/SealedDeck.java +++ b/src/main/java/forge/game/limited/SealedDeck.java @@ -32,8 +32,11 @@ import forge.Constant; import forge.Singletons; import forge.card.BoosterGenerator; import forge.card.CardBlock; +import forge.card.CardColor; import forge.card.CardEdition; +import forge.card.CardManaCost; import forge.card.UnOpenedProduct; +import forge.card.mana.ManaCostShard; import forge.card.spellability.AbilityMana; import forge.deck.Deck; import forge.gui.GuiUtils; @@ -352,23 +355,22 @@ public class SealedDeck { // count each card color using mana costs // TODO: count hybrid mana differently? for (i = 0; i < deck.size(); i++) { - final String mc = deck.get(i).getManaCost(); + final CardManaCost mc = deck.get(i).getManaCost(); // count each mana symbol in the mana cost - for (int j = 0; j < mc.length(); j++) { - final char c = mc.charAt(j); - - if (c == 'W') { + for (ManaCostShard shard : mc.getShards()) { + byte mask = shard.getColorMask(); + + if ((mask & CardColor.WHITE) > 0 ) clrCnts[0].setCount(clrCnts[0].getCount() + 1); - } else if (c == 'U') { + if ((mask & CardColor.BLUE) > 0 ) clrCnts[1].setCount(clrCnts[1].getCount() + 1); - } else if (c == 'B') { + if ((mask & CardColor.BLACK) > 0 ) clrCnts[2].setCount(clrCnts[2].getCount() + 1); - } else if (c == 'R') { + if ((mask & CardColor.RED) > 0 ) clrCnts[3].setCount(clrCnts[3].getCount() + 1); - } else if (c == 'G') { + if ((mask & CardColor.GREEN) > 0 ) clrCnts[4].setCount(clrCnts[4].getCount() + 1); - } } } diff --git a/src/main/java/forge/game/phase/Combat.java b/src/main/java/forge/game/phase/Combat.java index 61068cf2f29..075a75fccdf 100644 --- a/src/main/java/forge/game/phase/Combat.java +++ b/src/main/java/forge/game/phase/Combat.java @@ -18,10 +18,8 @@ package forge.game.phase; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -65,9 +63,8 @@ public class Combat { private int nextDefender = 0; // This Hash keeps track of - private final HashMap attackerToDefender = new HashMap(); + private final HashMap attackerToDefender = new HashMap(); - private int attackingDamage; private Player attackingPlayer = null; private Player defendingPlayer = null; @@ -91,12 +88,12 @@ public class Combat { this.blocked.clear(); this.unblockedMap.clear(); - - this.attackingDamage = 0; this.defendingDamageMap.clear(); this.attackingPlayer = null; this.defendingPlayer = null; + this.currentDefender = 0; + this.nextDefender = 0; this.initiatePossibleDefenders(Singletons.getModel().getGameState().getPhaseHandler().getPlayerTurn().getOpponent()); } @@ -111,8 +108,6 @@ public class Combat { */ public final void initiatePossibleDefenders(final Player defender) { this.defenders.clear(); - this.currentDefender = 0; - this.nextDefender = 0; this.defenders.add(defender); CardList planeswalkers = defender.getCardsIn(ZoneType.Battlefield); planeswalkers = planeswalkers.getType("Planeswalker"); @@ -128,7 +123,7 @@ public class Combat { * * @return a {@link java.lang.Object} object. */ - public final Object nextDefender() { + public final GameEntity nextDefender() { if (this.nextDefender >= this.defenders.size()) { return null; } @@ -204,17 +199,6 @@ public class Combat { return pwDefending; } - /** - *

- * getDeclaredAttackers. - *

- * - * @return a int. - */ - public final int getDeclaredAttackers() { - return this.attackerToDefender.size(); - } - /** *

* Setter for the field attackingPlayer. @@ -280,26 +264,6 @@ public class Combat { return this.defendingDamageMap; } - /** - *

- * getTotalDefendingDamage. - *

- * - * @return a int. - */ - public final int getTotalDefendingDamage() { - int total = 0; - - final Collection c = this.defendingDamageMap.values(); - - final Iterator itr = c.iterator(); - while (itr.hasNext()) { - total += itr.next(); - } - - return total; - } - /** *

* setDefendingDamage. @@ -369,11 +333,11 @@ public class Combat { * a {@link forge.Card} object. */ public final void addDefendingDamage(final int n, final Card source) { - final String slot = this.getDefenderByAttacker(source).toString(); - final Object o = this.defenders.get(Integer.parseInt(slot)); + final int slot = this.getDefenderByAttacker(source); + final GameEntity ge = this.defenders.get(slot); - if (o instanceof Card) { - final Card pw = (Card) o; + if (ge instanceof Card) { + final Card pw = (Card) ge; pw.addAssignedDamage(n, source); return; @@ -386,29 +350,6 @@ public class Combat { } } - /** - *

- * addAttackingDamage. - *

- * - * @param n - * a int. - */ - public final void addAttackingDamage(final int n) { - this.attackingDamage += n; - } - - /** - *

- * Getter for the field attackingDamage. - *

- * - * @return a int. - */ - public final int getAttackingDamage() { - return this.attackingDamage; - } - /** *

* sortAttackerByDefender. @@ -423,8 +364,7 @@ public class Combat { } for (final Card atk : this.attackerToDefender.keySet()) { - final Object o = this.attackerToDefender.get(atk); - final int i = Integer.parseInt(o.toString()); + final int i = this.attackerToDefender.get(atk); attackers[i].add(atk); } @@ -457,6 +397,26 @@ public class Combat { this.attackerToDefender.put(c, this.currentDefender); } + /** + *

+ * addAttacker. + *

+ * + * @param c + * a {@link forge.Card} object. + * @param defender + * a GameEntity object. + */ + public final void addAttacker(final Card c, GameEntity defender) { + int n = defenders.indexOf(defender); + if (-1 == n) { + System.out.println("Trying to add Attacker " + c + " to missing defender " + defender); + } else { + this.map.put(c, new CardList()); + this.attackerToDefender.put(c, n); + } + } + /** *

* getDefenderByAttacker. @@ -466,7 +426,7 @@ public class Combat { * a {@link forge.Card} object. * @return a {@link java.lang.Object} object. */ - public final Object getDefenderByAttacker(final Card c) { + public final Integer getDefenderByAttacker(final Card c) { return this.attackerToDefender.get(c); } @@ -527,7 +487,7 @@ public class Combat { */ public final void addBlocker(final Card attacker, final Card blocker) { this.blocked.add(attacker); - this.getList(attacker).add(blocker); + this.getBlockerList(attacker).add(blocker); } /** @@ -558,10 +518,10 @@ public class Combat { * @return a {@link forge.CardList} object. */ public final CardList getBlockers(final Card attacker) { - if (this.getList(attacker) == null) { + if (this.getBlockerList(attacker) == null) { return new CardList(); } else { - return new CardList(this.getList(attacker)); + return new CardList(this.getBlockerList(attacker)); } } @@ -595,7 +555,7 @@ public class Combat { * a {@link forge.Card} object. * @return a {@link forge.CardList} object. */ - private CardList getList(final Card attacker) { + private CardList getBlockerList(final Card attacker) { return this.map.get(attacker); } @@ -616,7 +576,7 @@ public class Combat { } else { // card is a blocker for (final Card a : att) { if (this.getBlockers(a).contains(c)) { - this.getList(a).remove(c); + this.getBlockerList(a).remove(c); // TODO if Declare Blockers and Declare Blockers (Abilities) // merge this logic needs to be tweaked if ((this.getBlockers(a).size() == 0) @@ -853,9 +813,7 @@ public class Combat { } } // for - // if attacker has no trample, and there's damage left, assign the - // rest - // to a random blocker + // if attacker has no trample, and there's damage left, assign the rest to a random blocker if ((damage > 0) && !(c.hasKeyword("Trample") && killsAllBlockers)) { final int index = CardUtil.getRandomIndex(block); block.get(index).addAssignedDamage(damage, c); diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index 75917f6afb6..1954b03ad2e 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -29,12 +29,12 @@ import forge.Card; import forge.CardList; import forge.CardListFilter; import forge.GameActionUtil; -import forge.MyObservable; import forge.Singletons; import forge.card.trigger.TriggerType; import forge.game.player.Player; import forge.game.zone.ZoneType; import forge.properties.ForgePreferences.FPref; +import forge.util.MyObservable; /** *

@@ -343,7 +343,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable { break; case COMBAT_BEGIN: - PhaseUtil.verifyCombat(); + //PhaseUtil.verifyCombat(); PhaseUtil.handleCombatBegin(); break; diff --git a/src/main/java/forge/game/player/ComputerUtil.java b/src/main/java/forge/game/player/ComputerUtil.java index d8f4ee4be60..94160b3cb80 100644 --- a/src/main/java/forge/game/player/ComputerUtil.java +++ b/src/main/java/forge/game/player/ComputerUtil.java @@ -1891,4 +1891,74 @@ public class ComputerUtil { } return prevented; } + + /** + *

+ * castPermanentInMain1. + *

+ * + * @param sa + * a SpellAbility object. + * @return a boolean. + */ + public static boolean castPermanentInMain1(final SpellAbility sa) { + final Card card = sa.getSourceCard(); + if (card.getSVar("PlayMain1").equals("TRUE")) { + return true; + } + if ((card.isCreature() && (ComputerAIGeneral.hasACardGivingHaste() + || card.hasKeyword("Haste"))) || card.hasKeyword("Exalted")) { + return true; + } + + // get all cards the computer controls with BuffedBy + final CardList buffed = AllZone.getComputerPlayer().getCardsIn(ZoneType.Battlefield); + for (int j = 0; j < buffed.size(); j++) { + final Card buffedcard = buffed.get(j); + if (buffedcard.getSVar("BuffedBy").length() > 0) { + final String buffedby = buffedcard.getSVar("BuffedBy"); + final String[] bffdby = buffedby.split(","); + if (card.isValid(bffdby, buffedcard.getController(), buffedcard)) { + return true; + } + } + if (card.isEquipment() && buffedcard.isCreature() && CombatUtil.canAttack(buffedcard)) { + return true; + } + if (card.isCreature() && buffedcard.hasKeyword("Soulbond") && !buffedcard.isPaired()) { + return true; + } + if (card.hasKeyword("Soulbond") && buffedcard.isCreature() && !buffedcard.isPaired()) { + return true; + } + } // BuffedBy + + // get all cards the human controls with AntiBuffedBy + final CardList antibuffed = AllZone.getHumanPlayer().getCardsIn(ZoneType.Battlefield); + for (int k = 0; k < antibuffed.size(); k++) { + final Card buffedcard = antibuffed.get(k); + if (buffedcard.getSVar("AntiBuffedBy").length() > 0) { + final String buffedby = buffedcard.getSVar("AntiBuffedBy"); + final String[] bffdby = buffedby.split(","); + if (card.isValid(bffdby, buffedcard.getController(), buffedcard)) { + return true; + } + } + } // AntiBuffedBy + final CardList vengevines = AllZone.getComputerPlayer().getCardsIn(ZoneType.Graveyard, "Vengevine"); + if (vengevines.size() > 0) { + final CardList creatures = AllZone.getComputerPlayer().getCardsIn(ZoneType.Hand); + final CardList creatures2 = new CardList(); + for (int i = 0; i < creatures.size(); i++) { + if (creatures.get(i).isCreature() && creatures.get(i).getManaCost().getCMC() <= 3) { + creatures2.add(creatures.get(i)); + } + } + if (((creatures2.size() + CardUtil.getThisTurnCast("Creature.YouCtrl", vengevines.get(0)).size()) > 1) + && card.isCreature() && card.getManaCost().getCMC() <= 3) { + return true; + } + } + return false; + } } diff --git a/src/main/java/forge/game/player/ComputerUtilAttack.java b/src/main/java/forge/game/player/ComputerUtilAttack.java index 107923fa4c7..0af3c6bea4d 100644 --- a/src/main/java/forge/game/player/ComputerUtilAttack.java +++ b/src/main/java/forge/game/player/ComputerUtilAttack.java @@ -672,19 +672,15 @@ public class ComputerUtilAttack { // at 0 ratio expect to potentially gain an advantage by attacking // first // if the ai has a slight advantage - // or the ai has a significant advantage numerically but only a - // slight disadvantage damage/life - this.aiAggression = 2; // attack expecting to destroy creatures/be - // unblockable + // or the ai has a significant advantage numerically but only a slight disadvantage damage/life + this.aiAggression = 2; // attack expecting to destroy creatures/be unblockable } else if ((ratioDiff < 0) && (aiLifeToPlayerDamageRatio > 1)) { // the player is overmatched but there are a few turns before death - this.aiAggression = 2; // attack expecting to destroy creatures/be - // unblockable + this.aiAggression = 2; // attack expecting to destroy creatures/be unblockable } else if (doUnblockableAttack || ((ratioDiff * -1) < turnsUntilDeathByUnblockable)) { - this.aiAggression = 1; // look for unblockable creatures that might - // be - // able to attack for a bit of - // fatal damage even if the player is significantly better + this.aiAggression = 1; + // look for unblockable creatures that might be + // able to attack for a bit of fatal damage even if the player is significantly better } else if (ratioDiff < 0) { this.aiAggression = 0; } // stay at home to block @@ -703,14 +699,13 @@ public class ComputerUtilAttack { for (int i = 0; i < attackersLeft.size(); i++) { final Card attacker = attackersLeft.get(i); - int totalFirstStrikeBlockPower = 0; - if (!attacker.hasFirstStrike() && !attacker.hasDoubleStrike()) { - totalFirstStrikeBlockPower = CombatUtil.getTotalFirstStrikeBlockPower(attacker, - AllZone.getHumanPlayer()); + if ((this.aiAggression < 3) && !attacker.hasFirstStrike() && !attacker.hasDoubleStrike() + && CombatUtil.getTotalFirstStrikeBlockPower(attacker, AllZone.getHumanPlayer()) + >= attacker.getKillDamage()) { + continue; } if (this.shouldAttack(attacker, this.blockers, combat) - && ((totalFirstStrikeBlockPower < attacker.getKillDamage()) || (this.aiAggression == 5)) && CombatUtil.canAttack(attacker, combat)) { combat.addAttacker(attacker); } @@ -782,6 +777,7 @@ public class ComputerUtilAttack { // wither or infect boolean isWorthLessThanAllKillers = true; boolean canBeBlocked = false; + boolean hasAttackEffect = attacker.getSVar("HasAttackEffect").equals("TRUE") || attacker.hasStartOfKeyword("Annihilator"); int numberOfPossibleBlockers = 0; if (!this.isEffectiveAttacker(attacker, combat)) { @@ -855,7 +851,7 @@ public class ComputerUtilAttack { } case 2: // attack expecting to attract a group block or destroying a // single blocker and surviving - if ((canKillAll && !canBeKilledByOne) || !canBeBlocked) { + if (((canKillAll || hasAttackEffect) && !canBeKilledByOne) || !canBeBlocked) { System.out.println(attacker.getName() + " = attacking expecting to survive or attract group block"); return true; } diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 99f4e7961bd..16e7f6cdeb8 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -49,7 +49,7 @@ import forge.game.zone.PlayerZone; import forge.game.zone.PlayerZoneComesIntoPlay; import forge.game.zone.ZoneType; import forge.gui.GuiUtils; -import forge.gui.match.VMatchUI; +import forge.properties.ForgePreferences.FPref; import forge.util.MyRandom; /** @@ -1838,7 +1838,8 @@ public abstract class Player extends GameEntity { * @return a boolean. */ public final boolean canPlayLand() { - if (VMatchUI.SINGLETON_INSTANCE.getViewDevMode().getLblUnlimitedLands().getEnabled() && this.isHuman() + if (Singletons.getModel().getPreferences().getPrefBoolean(FPref.DEV_UNLIMITED_LAND) + && this.isHuman() && Constant.Runtime.DEV_MODE[0]) { return PhaseHandler.canCastSorcery(this); } diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index 2e4515a5763..c08655a86e9 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -31,7 +31,6 @@ import forge.CardList; import forge.CardListFilter; import forge.Command; import forge.GameActionUtil; -import forge.MyObservable; import forge.Singletons; import forge.card.abilityfactory.AbilityFactory; import forge.card.cardfactory.CardFactoryUtil; @@ -60,6 +59,7 @@ import forge.gui.GuiUtils; import forge.gui.framework.EDocID; import forge.gui.framework.SDisplayUtil; import forge.gui.match.CMatchUI; +import forge.util.MyObservable; import forge.view.ButtonUtil; /** @@ -237,6 +237,21 @@ public class MagicStack extends MyObservable { this.getFrozenStack().clear(); } + /** + *

+ * removeFromFrozenStack. + *

+ * @param sa + * a SpellAbility. + */ + public final void removeFromFrozenStack(SpellAbility sa) { + SpellAbilityStackInstance si = this.getInstanceFromSpellAbility(sa); + this.getFrozenStack().remove(si); + if (this.getFrozenStack().isEmpty()) { + clearFrozen(); + } + } + /** *

* setResolving. diff --git a/src/main/java/forge/game/zone/PlayerZone.java b/src/main/java/forge/game/zone/PlayerZone.java index 042a952cced..6067fbf6eac 100644 --- a/src/main/java/forge/game/zone/PlayerZone.java +++ b/src/main/java/forge/game/zone/PlayerZone.java @@ -19,7 +19,7 @@ package forge.game.zone; import java.util.Observer; -import forge.MyObservable; +import forge.util.MyObservable; //PlayerZone observers the cards that are added to its zone /** diff --git a/src/main/java/forge/game/zone/PlayerZoneComesIntoPlay.java b/src/main/java/forge/game/zone/PlayerZoneComesIntoPlay.java index 3724ea98e93..2f5a598d9c9 100644 --- a/src/main/java/forge/game/zone/PlayerZoneComesIntoPlay.java +++ b/src/main/java/forge/game/zone/PlayerZoneComesIntoPlay.java @@ -76,7 +76,7 @@ public class PlayerZoneComesIntoPlay extends DefaultPlayerZone { final Player player = c.getController(); if (this.trigger) { - if (c.hasKeyword("CARDNAME enters the battlefield tapped.")) { + if (c.hasKeyword("CARDNAME enters the battlefield tapped.") || c.hasKeyword("Hideaway")) { // it enters the battlefield this way, and should not fire // triggers c.setTapped(true); diff --git a/src/main/java/forge/gui/CardDetailPanel.java b/src/main/java/forge/gui/CardDetailPanel.java index 608ae458f10..051bc6a99d2 100644 --- a/src/main/java/forge/gui/CardDetailPanel.java +++ b/src/main/java/forge/gui/CardDetailPanel.java @@ -30,6 +30,7 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.border.EtchedBorder; @@ -59,6 +60,7 @@ public class CardDetailPanel extends JPanel implements CardContainer { private final JLabel idLabel; private final JLabel setInfoLabel; private final JTextArea cdArea; + private final JScrollPane scrArea; /** *

@@ -114,13 +116,15 @@ public class CardDetailPanel extends JPanel implements CardContainer { this.setInfoLabel.setHorizontalAlignment(SwingConstants.CENTER); this.cdArea = new JTextArea(4, 12); - GridBagConstraints areaConstrains = new GridBagConstraints(); - areaConstrains.fill = GridBagConstraints.BOTH; - areaConstrains.gridx = 0; - areaConstrains.gridy = 1; - areaConstrains.weightx = 1.0; - areaConstrains.weighty = 1.0; - this.add(new JScrollPane(this.cdArea), areaConstrains); + this.scrArea = new JScrollPane(this.cdArea); + + GridBagConstraints areaConstraints = new GridBagConstraints(); + areaConstraints.fill = GridBagConstraints.BOTH; + areaConstraints.gridx = 0; + areaConstraints.gridy = 1; + areaConstraints.weightx = 1.0; + areaConstraints.weighty = 1.0; + this.add(scrArea, areaConstraints); this.cdArea.setLineWrap(true); this.cdArea.setWrapStyleWord(true); this.cdArea.setEditable(false); @@ -465,6 +469,13 @@ public class CardDetailPanel extends JPanel implements CardContainer { } this.cdArea.setText(area.toString()); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + scrArea.getVerticalScrollBar().setValue(scrArea.getVerticalScrollBar().getMinimum()); + } + }); } /** diff --git a/src/main/java/forge/gui/GuiInput.java b/src/main/java/forge/gui/GuiInput.java index c4a19cc149b..178da6f6b7c 100644 --- a/src/main/java/forge/gui/GuiInput.java +++ b/src/main/java/forge/gui/GuiInput.java @@ -22,11 +22,11 @@ import java.util.Observer; import forge.AllZone; import forge.Card; -import forge.MyObservable; import forge.Singletons; import forge.control.input.Input; import forge.game.player.Player; import forge.game.zone.PlayerZone; +import forge.util.MyObservable; /** *

diff --git a/src/main/java/forge/gui/SOverlayUtils.java b/src/main/java/forge/gui/SOverlayUtils.java index f75d78a7ff5..1eec6a85e87 100644 --- a/src/main/java/forge/gui/SOverlayUtils.java +++ b/src/main/java/forge/gui/SOverlayUtils.java @@ -44,10 +44,10 @@ public final class SOverlayUtils { pnl.setBackground(FSkin.getColor(FSkin.Colors.CLR_ACTIVE)); pnl.setBounds(new Rectangle(((w - pnlW) / 2), ((h - pnlH) / 2), pnlW, pnlH)); - pnl.add(new FLabel.Builder().icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_LOGO)).build(), + pnl.add(new FLabel.Builder().icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_LOGO)).build(), "h 200px!, align center"); pnl.add(new FLabel.Builder().text("Loading new game...") - .fontScaleAuto(false).fontSize(22).build(), "h 40px!, align center"); + .fontSize(22).build(), "h 40px!, align center"); overlay.add(pnl); @@ -75,7 +75,7 @@ public final class SOverlayUtils { pnlLoading.setBounds(((w - 170) / 2), ((h - 80) / 2), 170, 80); pnlLoading.setLayout(new MigLayout("wrap, align center")); pnlLoading.add(new FLabel.Builder().fontSize(18) - .fontScaleAuto(false).text(msg0).build(), "h 20px!, w 140px!, gap 0 0 5px 0"); + .text(msg0).build(), "h 20px!, w 140px!, gap 0 0 5px 0"); pnlLoading.add(lblLoading, "gap 0 0 0 10px"); overlay.add(pnlLoading); diff --git a/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java b/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java new file mode 100644 index 00000000000..5fe830b5f6a --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/CDeckEditorUI.java @@ -0,0 +1,113 @@ +/* + * 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.gui.deckeditor; + +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import forge.Card; +import forge.gui.CardContainer; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.match.controllers.CDetail; +import forge.gui.match.controllers.CPicture; + +/** + * Constructs instance of deck editor UI controller, used as a single point of + * top-level control for child UIs. Tasks targeting the view of individual + * components are found in a separate controller for that component and + * should not be included here. + * + *

(C at beginning of class name denotes a control class.) + */ +public enum CDeckEditorUI implements CardContainer { + /** */ + SINGLETON_INSTANCE; + + private ACEditorBase childController; + + private CDeckEditorUI() { + } + + //========== Overridden from CardContainer + + @Override + public void setCard(final Card c) { + CDetail.SINGLETON_INSTANCE.showCard(c); + CPicture.SINGLETON_INSTANCE.showCard(c); + } + + @Override + public Card getCard() { + return CDetail.SINGLETON_INSTANCE.getCurrentCard(); + } + + //========= Accessor/mutator methods + /** + * @return ACEditorBase + */ + public ACEditorBase getCurrentEditorController() { + return childController; + } + + /** + * Set controller for current configuration of editor. + * @param editor0   {@link forge.gui.deckeditor.controllers.ACEditorBase} + */ + public void setCurrentEditorController(ACEditorBase editor0) { + this.childController = editor0; + updateController(); + } + + //========== Other methods + /** + * Updates listeners for current controller. + */ + private void updateController() { + childController.getTableCatalog().getTable().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if (e.getKeyChar() == ' ') { childController.addCard(); } + } + }); + + childController.getTableDeck().getTable().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if (e.getKeyChar() == ' ') { childController.removeCard(); } + } + }); + + childController.getTableCatalog().getTable().addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent e) { + if (e.getClickCount() == 2) { childController.addCard(); } + } + }); + + childController.getTableDeck().getTable().addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent e) { + if (e.getClickCount() == 2) { childController.removeCard(); } + } + }); + + childController.init(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorBase.java b/src/main/java/forge/gui/deckeditor/DeckEditorBase.java deleted file mode 100644 index e2e586975e3..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorBase.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; - -import forge.Command; -import forge.deck.DeckBase; -import forge.gui.deckeditor.elements.CardPanelBase; -import forge.gui.deckeditor.elements.DeckAnalysis; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.item.ItemPoolView; -import forge.util.closures.Predicate; - -/** - * The Class DeckEditorBase. - * - * @param the generic type - * @param the generic type - */ -public abstract class DeckEditorBase extends JDialog { - private static final long serialVersionUID = -401223933343539977L; - - /** The filter boxes. */ - private FilterCheckBoxes filterBoxes; - // set this to false when resetting filter from code (like - // "clearFiltersPressed"), reset when done. - /** The is filters change firing update. */ - private boolean isFiltersChangeFiringUpdate = true; - - /** The card view. */ - private CardPanelBase cardView; - - // CardPools and Table data for top and bottom lists - /** The top. */ - private TableView topTableWithCards; - - /** The bottom. */ - private TableView bottomTableWithCards; - /** - * Instantiates a new deck editor base. - * - * @param parent the parent frame for this deck editor - */ - public DeckEditorBase(JFrame parent) { - super(parent, ModalityType.APPLICATION_MODAL); - } - - // top shows available card pool - // if constructed, top shows all cards - // if sealed, top shows N booster packs - // if draft, top shows cards that were chosen - /** - * Gets the top table model. - * - * @return the top table model - */ - public final TableView getTopTableModel() { - return this.getTopTableWithCards(); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckDisplay#getTop() - */ - /** - * Gets the top. - * - * @return the top - */ - public final ItemPoolView getTop() { - return this.getTopTableWithCards().getCards(); - } - - // bottom shows player's choice - be it deck or draft - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckDisplay#getBottom() - */ - /** - * Gets the bottom. - * - * @return the bottom - */ - public final ItemPoolView getBottom() { - return this.getBottomTableWithCards().getCards(); - } - - /** - * Gets the controller. - * - * @return the controller - */ - public abstract DeckController getController(); - - // THIS IS HERE FOR OVERLOADING!!!1 - // or may be return abstract getFilter from derived class + this filter ... - // virtual protected member, but later - /** - * Builds the filter. - * - * @return the predicate - */ - protected abstract Predicate buildFilter(); - - /** - * Show. - * - * @param exitCommand the exit command - */ - public abstract void show(final Command exitCommand); - - /** - * Analysis button_action performed. - * - * @param e - * the e - */ - final void analysisButtonActionPerformed(final ActionEvent e) { - final ItemPoolView deck = ItemPool.createFrom(this.getBottomTableWithCards().getCards(), - CardPrinted.class); - if (deck.isEmpty()) { - JOptionPane.showMessageDialog(null, "Cards in deck not found.", "Analysis Deck", - JOptionPane.INFORMATION_MESSAGE); - } else { - final DeckEditorBase g = DeckEditorBase.this; - final DeckAnalysis dAnalysis = new DeckAnalysis(g, deck); - dAnalysis.setVisible(true); - g.setEnabled(false); - } - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckDisplay#setItems(forge.item.ItemPoolView, - * forge.item.ItemPoolView, forge.game.GameType) - */ - /** - * Update view. - */ - public abstract void updateView(); - - /** - * Update display. - */ - public final void updateDisplay() { - this.getTopTableWithCards().setFilter(this.buildFilter()); - } - - /** The item listener updates display. */ - private ItemListener itemListenerUpdatesDisplay = new ItemListener() { - @Override - public void itemStateChanged(final ItemEvent e) { - if (DeckEditorBase.this.isFiltersChangeFiringUpdate()) { - DeckEditorBase.this.updateDisplay(); - } - } - }; - - /** - * This class is used for a feature: when you start typing card name, the - * list gets auto-filtered. - */ - protected class OnChangeTextUpdateDisplay implements DocumentListener { - private void onChange() { - if (DeckEditorBase.this.isFiltersChangeFiringUpdate()) { - DeckEditorBase.this.updateDisplay(); - } - } - - /* - * (non-Javadoc) - * - * @see - * javax.swing.event.DocumentListener#insertUpdate(javax.swing.event - * .DocumentEvent) - */ - @Override - public final void insertUpdate(final DocumentEvent e) { - this.onChange(); - } - - /* - * (non-Javadoc) - * - * @see - * javax.swing.event.DocumentListener#removeUpdate(javax.swing.event - * .DocumentEvent) - */ - @Override - public final void removeUpdate(final DocumentEvent e) { - this.onChange(); - } - - /* - * (non-Javadoc) - * - * @see - * javax.swing.event.DocumentListener#changedUpdate(javax.swing.event - * .DocumentEvent) - */ - @Override - public void changedUpdate(final DocumentEvent e) { - } // Happend only on ENTER pressed - } - - /** - * Gets the item listener updates display. - * - * @return the itemListenerUpdatesDisplay - */ - public ItemListener getItemListenerUpdatesDisplay() { - return this.itemListenerUpdatesDisplay; - } - - /** - * Sets the item listener updates display. - * - * @param itemListenerUpdatesDisplay - * the itemListenerUpdatesDisplay to set - */ - public void setItemListenerUpdatesDisplay(final ItemListener itemListenerUpdatesDisplay) { - this.itemListenerUpdatesDisplay = itemListenerUpdatesDisplay; // TODO: - // Add 0 - // to - // parameter's - // name. - } - - /** - * Checks if is filters change firing update. - * - * @return the isFiltersChangeFiringUpdate - */ - public boolean isFiltersChangeFiringUpdate() { - return this.isFiltersChangeFiringUpdate; - } - - /** - * Sets the filters change firing update. - * - * @param isFiltersChangeFiringUpdate - * the isFiltersChangeFiringUpdate to set - */ - public void setFiltersChangeFiringUpdate(final boolean isFiltersChangeFiringUpdate) { - this.isFiltersChangeFiringUpdate = isFiltersChangeFiringUpdate; // TODO: - // Add 0 - // to - // parameter's - // name. - } - - /** - * Gets the card view. - * - * @return the cardView - */ - public CardPanelBase getCardView() { - return this.cardView; - } - - /** - * Sets the card view. - * - * @param cardView0 - * the cardView to set - */ - protected void setCardView(final CardPanelBase cardView0) { - this.cardView = cardView0; - } - - /** - * Gets the filter boxes. - * - * @return the filterBoxes - */ - public FilterCheckBoxes getFilterBoxes() { - return this.filterBoxes; - } - - /** - * Sets the filter boxes. - * - * @param filterBoxes0 - * the filterBoxes to set - */ - public void setFilterBoxes(final FilterCheckBoxes filterBoxes0) { - this.filterBoxes = filterBoxes0; - } - - /** - * Gets the bottom table with cards. - * - * @return the bottomTableWithCards - */ - public TableView getBottomTableWithCards() { - return this.bottomTableWithCards; - } - - /** - * Sets the bottom table with cards. - * - * @param bottomTableWithCards0 - * the bottomTableWithCards to set - */ - public void setBottomTableWithCards(final TableView bottomTableWithCards0) { - this.bottomTableWithCards = bottomTableWithCards0; - } - - /** - * Gets the top table with cards. - * - * @return the topTableWithCards - */ - public TableView getTopTableWithCards() { - return this.topTableWithCards; - } - - /** - * Sets the top table with cards. - * - * @param topTableWithCards0 - * the topTableWithCards to set - */ - public void setTopTableWithCards(final TableView topTableWithCards0) { - this.topTableWithCards = topTableWithCards0; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java b/src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java deleted file mode 100644 index fa4058b03ce..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorConstructed.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JLabel; - -import forge.Command; -import forge.Singletons; -import forge.deck.Deck; -import forge.error.ErrorViewer; -import forge.gui.deckeditor.elements.CardPanelHeavy; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardDb; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.util.closures.Lambda0; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -/** - *

- * Gui_DeckEditor class. - *

- * - * @author Forge - * @version $Id$ - */ -public final class DeckEditorConstructed extends DeckEditorBase { - /** Constant serialVersionUID=130339644136746796L. */ - private static final long serialVersionUID = 130339644136746796L; - - private final JButton removeButton = new JButton(); - private final JButton addButton = new JButton(); - private final JButton importButton = new JButton(); - - private final JButton analysisButton = new JButton(); - private final JButton clearFilterButton = new JButton(); - - private final JLabel jLabelAnalysisGap = new JLabel(""); - private FilterNameTypeSetPanel filterNameTypeSet; - - private final DeckController controller; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = 5210924838133689758L; - - @Override - public void execute() { - DeckEditorConstructed.this.dispose(); - if (exitCommand != null) { - exitCommand.execute(); - } - } - }; - - final MenuCommon menu = new MenuCommon(this.getController(), exit); - this.setJMenuBar(menu); - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - menu.close(); - } - }); - - this.setup(); - - this.controller.newModel(); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - - } // show(Command) - - private void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 175, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 75, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 60, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 60, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 25, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("AI", 30, PresetColumns.FN_AI_STATUS_COMPARE, - PresetColumns.FN_AI_STATUS_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.getCardView()); - this.getBottomTableWithCards().setup(columns, this.getCardView()); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - this.setSize(1024, 740); - } - - /** - * Instantiates a new deck editor common. - * - * @param parent the parent frame for this deck editor instance - */ - public DeckEditorConstructed(JFrame parent) { - super(parent); - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("Available Cards", true, true, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Deck", true, CardPrinted.class)); - this.setCardView(new CardPanelHeavy()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - - final Lambda0 newCreator = new Lambda0() { - @Override - public Deck apply() { - return new Deck(); - } - }; - this.controller = new DeckController(Singletons.getModel().getDecks().getConstructed(), this, newCreator); - } - - private void jbInit() { - - final Font fButtons = new java.awt.Font("Dialog", 0, 13); - this.removeButton.setFont(fButtons); - this.addButton.setFont(fButtons); - this.importButton.setFont(fButtons); - this.clearFilterButton.setFont(fButtons); - this.analysisButton.setFont(fButtons); - - this.addButton.setText("Add to Deck"); - this.removeButton.setText("Remove from Deck"); - this.importButton.setText("Import a Deck"); - this.clearFilterButton.setText("Clear Filter"); - this.analysisButton.setText("Deck Analysis"); - - this.removeButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.removeButtonClicked(e); - } - }); - this.addButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.addButtonActionPerformed(e); - } - }); - this.importButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.importButtonActionPerformed(e); - } - }); - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.clearFilterButtonActionPerformed(e); - } - }); - this.analysisButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorConstructed.this.analysisButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - // Do not lower statsLabel any lower, we want this to be visible at 1024 - // x 768 screen size - this.setTitle("Deck Editor"); - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - content.add(this.getTopTableWithCards().getLabel(), "cell 0 4"); - - content.add(this.addButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.removeButton, "w 100, h 49, sg button"); - content.add(this.importButton, "w 100, h 49, sg button, gapleft 40px"); - // Label is used to push the analysis button to the right to separate - // analysis button from add/remove card ones - content.add(this.jLabelAnalysisGap, "wmin 75, growx"); - content.add(this.analysisButton, "w 100, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - content.add(this.getBottomTableWithCards().getLabel(), "cell 0 7"); - - content.add(this.getCardView(), "cell 1 0 1 8, flowy, grow"); - - this.getTopTableWithCards().getTable().addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - DeckEditorConstructed.this.addCardToDeck(); - } - } - }); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DeckEditorConstructed.this.addCardToDeck(); - } - } - }); - - // javax.swing.JRootPane rootPane = this.getRootPane(); - // rootPane.setDefaultButton(filterButton); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and(this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - return Predicate.instanceOf(cardFilter, CardPrinted.class); - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - /** - * Adds the button_action performed. - * - * @param e - * the e - */ - void addButtonActionPerformed(final ActionEvent e) { - this.addCardToDeck(); - } - - /** - * Adds the card to deck. - */ - void addCardToDeck() { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().addCard(card); - this.controller.notifyModelChanged(); - } - - /** - * Removes the button clicked. - * - * @param e - * the e - */ - void removeButtonClicked(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().removeCard(card); - this.controller.notifyModelChanged(); - } - - /** - * Import button_action performed. - * - * @param e - * the e - */ - void importButtonActionPerformed(final ActionEvent e) { - final DeckEditorConstructed g = this; - final DeckImport dImport = new DeckImport(g); - dImport.setModalityType(ModalityType.APPLICATION_MODAL); - dImport.setVisible(true); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - // if constructed, can add the all cards above - this.getTopTableWithCards().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class)); - this.getBottomTableWithCards().setDeck(this.controller.getModel().getMain()); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return this.controller; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorLimited.java b/src/main/java/forge/gui/deckeditor/DeckEditorLimited.java deleted file mode 100644 index c96551c0b56..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorLimited.java +++ /dev/null @@ -1,415 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JLabel; - -import forge.Command; -import forge.deck.Deck; -import forge.deck.DeckGroup; -import forge.error.ErrorViewer; -import forge.gui.deckeditor.elements.CardPanelHeavy; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.util.IStorage; -import forge.util.closures.Lambda0; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -/** - *

- * Gui_DeckEditor class. - *

- * - * @author Forge - * @version $Id: DeckEditorCommon.java 12850 2011-12-26 14:55:09Z slapshot5 $ - */ -public final class DeckEditorLimited extends DeckEditorBase { - /** Constant serialVersionUID=130339644136746796L. */ - private static final long serialVersionUID = 130339644136746796L; - - private final JButton removeButton = new JButton(); - private final JButton addButton = new JButton(); - - private final JButton analysisButton = new JButton(); - private final JButton clearFilterButton = new JButton(); - - private final JLabel jLabelAnalysisGap = new JLabel(""); - private FilterNameTypeSetPanel filterNameTypeSet; - - private final DeckController controller; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = 5210924838133689758L; - - @Override - public void execute() { - DeckEditorLimited.this.dispose(); - if (exitCommand != null) { - exitCommand.execute(); - } - } - }; - - final MenuLimited menu = new MenuLimited(this.getController(), exit); - - this.setJMenuBar(menu); - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - menu.close(); - } - }); - - this.setup(); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - - } // show(Command) - - private void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 175, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 75, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 60, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 60, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 25, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("AI", 30, PresetColumns.FN_AI_STATUS_COMPARE, - PresetColumns.FN_AI_STATUS_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.getCardView()); - this.getBottomTableWithCards().setup(columns, this.getCardView()); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - this.setSize(1024, 740); - } - - /** - * Instantiates a new deck editor common. - * - * @param mainFrame the parent frame for this deck editor instance - * @param deckMap the deck map - */ - public DeckEditorLimited(JFrame mainFrame, final IStorage deckMap) { - super(mainFrame); - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("Avaliable Cards", true, true, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Deck", true, CardPrinted.class)); - this.setCardView(new CardPanelHeavy()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - - final Lambda0 newCreator = new Lambda0() { - @Override - public DeckGroup apply() { - return new DeckGroup(""); - } - }; - this.controller = new DeckController(deckMap, this, newCreator); - } - - private void jbInit() { - - final Font fButtons = new java.awt.Font("Dialog", 0, 13); - this.removeButton.setFont(fButtons); - this.addButton.setFont(fButtons); - this.clearFilterButton.setFont(fButtons); - this.analysisButton.setFont(fButtons); - - this.addButton.setText("Add to Deck"); - this.removeButton.setText("Remove from Deck"); - this.clearFilterButton.setText("Clear Filter"); - this.analysisButton.setText("Deck Analysis"); - - this.removeButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.removeButtonClicked(e); - } - }); - this.addButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.addButtonActionPerformed(e); - } - }); - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.clearFilterButtonActionPerformed(e); - } - }); - this.analysisButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorLimited.this.analysisButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - // Do not lower statsLabel any lower, we want this to be visible at 1024 - // x 768 screen size - this.setTitle("Deck Editor"); - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - content.add(this.getTopTableWithCards().getLabel(), "cell 0 4"); - - content.add(this.addButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.removeButton, "w 100, h 49, sg button"); - // Label is used to push the analysis button to the right to separate - // analysis button from add/remove card ones - content.add(this.jLabelAnalysisGap, "wmin 75, growx"); - content.add(this.analysisButton, "w 100, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - content.add(this.getBottomTableWithCards().getLabel(), "cell 0 7"); - - content.add(this.getCardView(), "cell 1 0 1 8, flowy, grow"); - - this.getTopTableWithCards().getTable().addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - DeckEditorLimited.this.addCardToDeck(); - } - } - }); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DeckEditorLimited.this.addCardToDeck(); - } - } - }); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and(this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - return Predicate.instanceOf(cardFilter, CardPrinted.class); - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - /** - * Adds the button_action performed. - * - * @param e - * the e - */ - void addButtonActionPerformed(final ActionEvent e) { - this.addCardToDeck(); - } - - /** - * Adds the card to deck. - */ - void addCardToDeck() { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - // update view - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().addCard(card); - this.getTopTableWithCards().removeCard(card); - - /* - * update model Deck model = - * getSelectedDeck(getController().getModel()); - * model.getMain().add(card); model.getSideboard().remove(card); - */ - - this.getController().notifyModelChanged(); - } - - /** - * TODO: Write javadoc for this method. - * - * @param model - * @return - */ - private Deck getSelectedDeck(final DeckGroup model) { - return model.getHumanDeck(); - } - - /** - * Removes the button clicked. - * - * @param e - * the e - */ - void removeButtonClicked(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - // update view - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().removeCard(card); - this.getTopTableWithCards().addCard(card); - - /* - * update model Deck model = - * getSelectedDeck(getController().getModel()); - * model.getMain().remove(card); model.getSideboard().add(card); - */ - - this.getController().notifyModelChanged(); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return this.controller; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - Deck toEdit = this.getSelectedDeck(this.controller.getModel()); - this.getTopTableWithCards().setDeck(toEdit.getSideboard()); - this.getBottomTableWithCards().setDeck(toEdit.getMain()); - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorQuest.java b/src/main/java/forge/gui/deckeditor/DeckEditorQuest.java deleted file mode 100644 index dac5ef7edd6..00000000000 --- a/src/main/java/forge/gui/deckeditor/DeckEditorQuest.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * 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.gui.deckeditor; - -// import java.awt.Font; -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JFrame; -import javax.swing.WindowConstants; - -import forge.Command; -import forge.Constant; -import forge.deck.Deck; -import forge.error.ErrorViewer; -import forge.gui.deckeditor.elements.CardPanelHeavy; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.quest.QuestController; -import forge.util.closures.Lambda0; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -//import forge.quest.data.QuestBoosterPack; - -/** - *

- * Gui_Quest_DeckEditor class. - *

- * - * @author Forge - * @version $Id$ - */ -public final class DeckEditorQuest extends DeckEditorBase { - /** Constant serialVersionUID=152061168634545L. */ - private static final long serialVersionUID = 152061168634545L; - - /** The custom menu. */ - private final JButton clearFilterButton = new JButton(); - private final JButton addButton = new JButton(); - private final JButton removeButton = new JButton(); - private final JLabel jLabelAnalysisGap = new JLabel(""); - private final JButton analysisButton = new JButton(); - - private FilterNameTypeSetPanel filterNameTypeSet; - - private final QuestController questData; - private final DeckController controller; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = -7428793574300520612L; - - @Override - public void execute() { - DeckEditorQuest.this.dispose(); - exitCommand.execute(); - } - }; - - this.setup(); - - final MenuQuest menu = new MenuQuest(this.getController(), exit); - this.setJMenuBar(menu); - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - menu.close(); - } - }); - - Deck deck = Constant.Runtime.HUMAN_DECK[0] == null ? null : this.questData.getMyDecks().get( - Constant.Runtime.HUMAN_DECK[0].getName()); - - if (deck == null) { - deck = new Deck(); - } - - // tell Gui_Quest_DeckEditor the name of the deck - - this.getController().setModel(deck); - - // this affects the card pool - this.getTopTableWithCards().sort(4, true); // sort by type - this.getTopTableWithCards().sort(3, true); // then sort by color - this.getBottomTableWithCards().sort(1, true); - } // show(Command) - - /** - *

- * setup. - *

- */ - public void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 180, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 70, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 50, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 40, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 35, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("New", 30, this.questData.getCards().getFnNewCompare(), - this.questData.getCards().getFnNewGet())); - - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.getCardView()); - this.getBottomTableWithCards().setup(columns, this.getCardView()); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - setSize(1024, 740); - } - - /** - * Instantiates a new deck editor quest. - * - * @param parent - * the parent frame for this deck editor instance - * @param questData2 - * the quest data2 - */ - public DeckEditorQuest(JFrame parent, final QuestController questData2) { - super(parent); - this.questData = questData2; - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("All Cards", true, true, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Your deck", true, CardPrinted.class)); - this.setCardView(new CardPanelHeavy()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - - final Lambda0 newCreator = new Lambda0() { - @Override - public Deck apply() { - return new Deck(); - } - }; - this.controller = new DeckController(questData2.getMyDecks(), this, newCreator); - } - - private void jbInit() throws Exception { - - this.setTitle("Deck Editor"); - this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - - final Font fButtons = new java.awt.Font("Dialog", 0, 13); - this.removeButton.setFont(fButtons); - this.addButton.setFont(fButtons); - this.clearFilterButton.setFont(fButtons); - this.analysisButton.setFont(fButtons); - - this.addButton.setText("Add to Deck"); - this.removeButton.setText("Remove from Deck"); - this.clearFilterButton.setText("Clear Filter"); - this.analysisButton.setText("Deck Analysis"); - - this.removeButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.removeButtonActionPerformed(e); - } - }); - this.addButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.addButtonActionPerformed(e); - } - }); - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.clearFilterButtonActionPerformed(e); - } - }); - this.analysisButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckEditorQuest.this.analysisButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - content.add(this.getTopTableWithCards().getLabel(), "cell 0 4"); - - content.add(this.addButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.removeButton, "w 100, h 49, sg button"); - - content.add(this.jLabelAnalysisGap, "wmin 75, growx"); - content.add(this.analysisButton, "w 100, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - content.add(this.getBottomTableWithCards().getLabel(), "cell 0 7"); - - content.add(this.getCardView(), "cell 1 0 1 8, flowy, growy"); - - this.getTopTableWithCards().getTable().addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - DeckEditorQuest.this.addCardToDeck(); - } - } - }); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DeckEditorQuest.this.addCardToDeck(); - } - } - }); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and(this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - return Predicate.instanceOf(cardFilter, CardPrinted.class); - } - - private void addButtonActionPerformed(final ActionEvent e) { - addCardToDeck(); - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - /** - * Adds the card to deck. - */ - void addCardToDeck() { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getTopTableWithCards().removeCard(card); - this.getBottomTableWithCards().addCard(card); - this.controller.notifyModelChanged(); - } - - private void removeButtonActionPerformed(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getTopTableWithCards().addCard(card); - this.getBottomTableWithCards().removeCard(card); - } - - /** - * Adds the cheat card. - * - * @param card - * the card - */ - public void addCheatCard(final CardPrinted card) { - this.getTopTableWithCards().addCard(card); - this.questData.getCards().getCardpool().add(card); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return this.controller; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - final Deck deck = this.controller.getModel(); - - final ItemPool cardpool = new ItemPool(CardPrinted.class); - cardpool.addAll(this.questData.getCards().getCardpool()); - // remove bottom cards that are in the deck from the card pool - cardpool.removeAll(deck.getMain()); - // show cards, makes this user friendly - this.getTopTableWithCards().setDeck(cardpool); - this.getBottomTableWithCards().setDeck(deck.getMain()); - } - -} diff --git a/src/main/java/forge/gui/deckeditor/DeckImport.java b/src/main/java/forge/gui/deckeditor/DeckImport.java index 2e5ff3060a2..a5d9880caf5 100644 --- a/src/main/java/forge/gui/deckeditor/DeckImport.java +++ b/src/main/java/forge/gui/deckeditor/DeckImport.java @@ -41,15 +41,22 @@ import javax.swing.text.ElementIterator; import net.miginfocom.swing.MigLayout; import forge.deck.Deck; +import forge.deck.DeckBase; import forge.deck.DeckRecognizer; import forge.deck.DeckRecognizer.TokenType; import forge.gui.GuiUtils; +import forge.gui.deckeditor.controllers.ACEditorBase; import forge.item.CardPrinted; +import forge.item.InventoryItem; /** + * * Dialog for quick import of decks. + * + * @param + * @param */ -public class DeckImport extends JDialog { +public class DeckImport extends JDialog { private static final long serialVersionUID = -5837776824284093004L; private final JTextArea txtInput = new JTextArea(); @@ -83,7 +90,7 @@ public class DeckImport extends JDialog { /** The tokens. */ private final List tokens = new ArrayList(); - private final DeckEditorConstructed host; + private final ACEditorBase host; /** * Instantiates a new deck import. @@ -91,7 +98,7 @@ public class DeckImport extends JDialog { * @param g * the g */ - public DeckImport(final DeckEditorConstructed g) { + public DeckImport(final ACEditorBase g) { this.host = g; final int wWidth = 600; @@ -136,6 +143,7 @@ public class DeckImport extends JDialog { }); this.cmdAccept.addActionListener(new ActionListener() { + @SuppressWarnings("unchecked") @Override public void actionPerformed(final ActionEvent e) { final String warning = "This will replace contents of your currently open deck with whatever you are importing. Proceed?"; @@ -145,7 +153,7 @@ public class DeckImport extends JDialog { return; } final Deck toSet = DeckImport.this.buildDeck(); - DeckImport.this.host.getController().setModel(toSet); + DeckImport.this.host.getDeckController().setModel((TModel) toSet); DeckImport.this.processWindowEvent(new WindowEvent(DeckImport.this, WindowEvent.WINDOW_CLOSING)); } }); diff --git a/src/main/java/forge/gui/deckeditor/DraftingProcess.java b/src/main/java/forge/gui/deckeditor/DraftingProcess.java deleted file mode 100644 index 28ce286948a..00000000000 --- a/src/main/java/forge/gui/deckeditor/DraftingProcess.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.awt.Rectangle; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.InputEvent; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.ArrayList; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.JTable; -import javax.swing.WindowConstants; - -import forge.Command; -import forge.Constant; -import forge.Singletons; -import forge.deck.Deck; -import forge.deck.DeckGroup; -import forge.error.ErrorViewer; -import forge.game.limited.IBoosterDraft; -import forge.gui.GuiUtils; -import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.elements.CardPanelLite; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.gui.home.sanctioned.CSubmenuDraft; -import forge.item.CardDb; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.ItemPoolView; -import forge.properties.ForgeProps; -import forge.properties.NewConstants.Lang.GuiBoosterDraft; -import forge.util.closures.Predicate; - -/** - *

- * DeckEditorDraft class. - *

- * - * @author Forge - * @version $Id$ - */ -public class DraftingProcess extends DeckEditorBase { - /** - * Constant serialVersionUID=-6055633915602448260L. - */ - private static final long serialVersionUID = -6055633915602448260L; - - private IBoosterDraft boosterDraft; - - private final JButton jButtonPick = new JButton(); - - private CardPanelLite cardView = new CardPanelLite(); - - private final MouseListener pickWithMouse = new MouseAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - // Pick on left-button double click - if (((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) && (e.getClickCount() == 2)) { - DraftingProcess.this.jButtonPickClicked(null); - } else if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { - // pick on right click - final JTable table = DraftingProcess.this.getTopTableWithCards().getTable(); - final int rowNumber = table.rowAtPoint(e.getPoint()); - // after hittest - if it was outside of rows - discard this - // click - if (rowNumber == -1) { - return; - } - - // if row was not selected, select it. If it was, pick a card - if (rowNumber != table.getSelectedRow()) { - table.getSelectionModel().setSelectionInterval(rowNumber, rowNumber); - } else { - DraftingProcess.this.jButtonPickClicked(null); - } - } - } - }; - - /** - * Show gui. - * - * @param inBoosterDraft - * the in_booster draft - */ - public final void showGui(final IBoosterDraft inBoosterDraft) { - this.boosterDraft = inBoosterDraft; - this.show(null); - } - - /** - *

- * addListeners. - *

- */ - private void addListeners() { - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - final int n = JOptionPane.showConfirmDialog(null, - ForgeProps.getLocalized(GuiBoosterDraft.CLOSE_MESSAGE), "", JOptionPane.YES_NO_OPTION); - if (n == JOptionPane.YES_OPTION) { - DraftingProcess.this.dispose(); - CSubmenuDraft.SINGLETON_INSTANCE.update(); - SOverlayUtils.hideOverlay(); - } - } // windowClosing() - }); - } // addListeners() - - /** - *

- * setup. - *

- */ - private void setup() { - this.addListeners(); - // setupMenu(); - - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 180, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 70, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 50, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 40, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 35, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 40, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.add(new TableColumnInfo("AI", 30, PresetColumns.FN_AI_STATUS_COMPARE, - PresetColumns.FN_AI_STATUS_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - this.getTopTableWithCards().setup(columns, this.cardView); - this.getBottomTableWithCards().setup(columns, this.cardView); - - this.setSize(980, 740); - GuiUtils.centerFrame(this); - this.setResizable(false); - - this.getTopTableWithCards().getTable().addMouseListener(this.pickWithMouse); - this.getTopTableWithCards().getTable().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(final KeyEvent e) { - if (e.getKeyChar() == ' ') { - DraftingProcess.this.jButtonPickClicked(null); - } - } - }); - - } - - /** - * Instantiates a new deck editor draft. - */ - public DraftingProcess(JFrame parent) { - super(parent); - try { - this.setTopTableWithCards(new TableView("Choose one card", false, CardPrinted.class)); - this.setBottomTableWithCards(new TableView("Previously picked cards", true, CardPrinted.class)); - this.setFilterBoxes(null); - this.cardView = new CardPanelLite(); - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - } - - /** - *

- * jbInit. - *

- * - * @throws java.lang.Exception - * if any. - */ - private void jbInit() throws Exception { - this.getContentPane().setLayout(null); - - this.getTopTableWithCards().getTableDecorated().setBounds(new Rectangle(19, 28, 680, 344)); - this.getBottomTableWithCards().getTableDecorated().setBounds(new Rectangle(19, 478, 680, 184)); - this.getBottomTableWithCards().getLabel().setBounds(new Rectangle(19, 680, 665, 31)); - - this.cardView.setBounds(new Rectangle(715, 23, 240, 666)); - - this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); - this.setTitle("Booster Draft"); - - this.jButtonPick.setBounds(new Rectangle(238, 418, 147, 44)); - this.jButtonPick.setFont(new java.awt.Font("Dialog", 0, 16)); - this.jButtonPick.setText("Choose Card"); - this.jButtonPick.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DraftingProcess.this.jButtonPickClicked(e); - } - }); - - this.getContentPane().add(this.cardView, null); - this.getContentPane().add(this.getTopTableWithCards().getTableDecorated(), null); - this.getContentPane().add(this.getBottomTableWithCards().getLabel(), null); - this.getContentPane().add(this.getBottomTableWithCards().getTableDecorated(), null); - this.getContentPane().add(this.jButtonPick, null); - } - - /** - *

- * jButton1_actionPerformed. - *

- * - * @param e - * a {@link java.awt.event.ActionEvent} object. - */ - final void jButtonPickClicked(final ActionEvent e) { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - - this.getBottomTableWithCards().addCard(card); - - // get next booster pack - this.boosterDraft.setChoice(card); - if (this.boosterDraft.hasNextChoice()) { - this.showChoices(this.boosterDraft.nextChoice()); - } else { - this.boosterDraft.finishedDrafting(); - - // quit - this.saveDraft(); - this.dispose(); - } - } /* OK Button */ - - /** - *

- * showChoices. - *

- * - * @param list - * a {@link forge.CardList} object. - */ - private void showChoices(final ItemPoolView list) { - this.getTopTableWithCards().setDeck(list); - this.cardView.showCard(null); - this.getTopTableWithCards().fixSelection(0); - } // showChoices() - - /** - *

- * getPlayersDeck. - *

- * - * @return a {@link forge.deck.Deck} object. - */ - private Deck getPlayersDeck() { - final Deck deck = new Deck(); - Constant.Runtime.HUMAN_DECK[0] = deck; - - // add sideboard to deck - deck.getSideboard().addAll(this.getBottomTableWithCards().getCards()); - - final String landSet = IBoosterDraft.LAND_SET_CODE[0]; - final int landsCount = 20; - deck.getSideboard().add(CardDb.instance().getCard("Forest", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Mountain", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Swamp", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Island", landSet), landsCount); - deck.getSideboard().add(CardDb.instance().getCard("Plains", landSet), landsCount); - - return deck; - } // getPlayersDeck() - - /** - *

- * saveDraft. - *

- */ - private void saveDraft() { - String s = ""; - while ((s == null) || (s.length() == 0)) { - s = JOptionPane.showInputDialog(null, ForgeProps.getLocalized(GuiBoosterDraft.SAVE_DRAFT_MESSAGE), - ForgeProps.getLocalized(GuiBoosterDraft.SAVE_DRAFT_TITLE), JOptionPane.QUESTION_MESSAGE); - } - // TODO: check if overwriting the same name, and let the user delete old - // drafts - - // construct computer's decks - // save draft - final Deck[] computer = this.boosterDraft.getDecks(); - - final DeckGroup finishedDraft = new DeckGroup(s); - finishedDraft.setHumanDeck((Deck) this.getPlayersDeck().copyTo(s)); - finishedDraft.addAiDecks(computer); - - // DeckManager deckManager = new - // DeckManager(ForgeProps.getFile(NEW_DECKS)); - Singletons.getModel().getDecks().getDraft().add(finishedDraft); // write - // file - // right - // here - - // close and open next screen - DraftingProcess.this.dispose(); - - // This should be handled in the exit command of the editor, not here. - CSubmenuDraft.SINGLETON_INSTANCE.update(); - SOverlayUtils.hideOverlay(); - } /* saveDraft() */ - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected final Predicate buildFilter() { - return Predicate.getTrue(CardPrinted.class); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return null; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#show(forge.Command) - */ - @Override - public void show(final Command exitCommand) { - this.setup(); - this.showChoices(this.boosterDraft.nextChoice()); - this.getBottomTableWithCards().setDeck((Iterable) null); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - - this.setVisible(true); - } -} diff --git a/src/main/java/forge/gui/deckeditor/MenuBase.java b/src/main/java/forge/gui/deckeditor/MenuBase.java deleted file mode 100644 index bc04ef9e7bc..00000000000 --- a/src/main/java/forge/gui/deckeditor/MenuBase.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.List; - -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; - -import org.apache.commons.lang3.StringUtils; - -import forge.Command; -import forge.deck.DeckBase; -import forge.error.ErrorViewer; -import forge.gui.GuiUtils; - -/** - *

- * Gui_DeckEditor_Menu class. - *

- * - * @param the generic type - * @author Forge - * @version $Id: DeckEditorCommonMenu.java 13590 2012-01-27 20:46:27Z Max mtg $ - */ -public class MenuBase extends JMenuBar { - - private static final long serialVersionUID = -4037993759604768755L; - private final Command exitCommand; - private final DeckController controller; - - /** - * Menu for Deck Editor. - * - * @param ctrl the ctrl - * @param exit a Command - */ - public MenuBase(final DeckController ctrl, final Command exit) { - this.controller = ctrl; - this.exitCommand = exit; - - this.setupMenu(); - } - - /** - * Gets the controller. - * - * @return the controller - */ - protected final DeckController getController() { - return this.controller; - } - - /** - * Setup menu. - */ - protected void setupMenu() { - this.add(this.getDefaultFileMenu()); - this.add(this.getSortMenu()); - } - - /** - * New constructed. - * - * @param careAboutOldDeck - * a boolean - */ - protected final void newDocument(final boolean careAboutOldDeck) { - if (careAboutOldDeck && !this.canLeaveCurrentDeck()) { - return; - } - - this.controller.newModel(); - } - - /** - * Gets the user input open deck. - * - * @return the user input open deck - */ - protected final String getUserInputOpenDeck() { - final List choices = this.controller.getSavedNames(); - if (choices.isEmpty()) { - JOptionPane.showMessageDialog(null, "No decks found", "Open Deck", JOptionPane.PLAIN_MESSAGE); - return null; - } - - final Object o = GuiUtils.chooseOneOrNone("Open Deck", choices.toArray()); - return o == null ? null : o.toString(); - } - - // deck.setName(currentDeckName); - - /** - * Open. - */ - protected final void open() { - if (!this.canLeaveCurrentDeck()) { - return; - } - final String name = this.getUserInputOpenDeck(); - if (StringUtils.isBlank(name)) { - return; - } - this.controller.load(name); - } - - /** - * Save. - */ - protected final void save() { - if (StringUtils.isBlank(this.controller.getModel().getName())) { - this.saveAs(); - return; - } - - this.controller.save(); - } - - /** - * Save as. - */ - protected final void saveAs() { - final String name = this.getDeckNameFromDialog(); - - if (StringUtils.isBlank(name)) { - final int n = JOptionPane.showConfirmDialog(null, "This name is incorrect. Enter another one?", - "Cannot save", JOptionPane.YES_NO_OPTION); - - if (n == JOptionPane.NO_OPTION) { - return; - } - } - - if (this.controller.fileExists(name)) { - final int m = JOptionPane.showConfirmDialog(null, "There is already saved an item named '" + name - + "'. Would you like to overwrite it?", "Confirm overwrite", JOptionPane.YES_NO_OPTION); - - if (m == JOptionPane.NO_OPTION) { - return; - } - } - - this.controller.saveAs(name); - } - - /** - * Delete. - */ - protected final void delete() { - if (!this.controller.isModelInStore()) { - return; - } - - final int n = JOptionPane.showConfirmDialog(null, "Do you want to delete this deck " - + this.controller.getModel().getName() + " ?", "Delete", JOptionPane.YES_NO_OPTION); - - if (n == JOptionPane.NO_OPTION) { - return; - } - - this.controller.delete(); - } - - /** - * - * close window. - */ - public final void close() { - if (!this.canLeaveCurrentDeck()) { - return; - } - this.exitCommand.execute(); - } - - /** - * Can leave current deck. - * - * @return true, if successful - */ - protected final boolean canLeaveCurrentDeck() { - if (this.controller.isSaved()) { - return true; - } - final String message = String.format("Do you wish to save changes you made to your current deck '%s'?", - this.controller.getModel().getName()); - final int choice = JOptionPane - .showConfirmDialog(this.controller.getOwnerWindow(), message, "You have unsaved changes in your deck", - JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); - if (JOptionPane.CANCEL_OPTION == choice) { - return false; - } - if (JOptionPane.NO_OPTION == choice) { - return true; - } - - this.save(); - return true; - } - - /** - *

- * getUserInput_GetDeckName. - *

- * - * @return a {@link java.lang.String} object. - */ - protected final String getDeckNameFromDialog() { - final Object o = JOptionPane.showInputDialog(null, "Save As", "Deck Name", JOptionPane.OK_CANCEL_OPTION); - - if (o == null) { - return ""; - } - - final String deckName = o.toString(); - final boolean isGoodName = this.controller.isGoodName(deckName); - - if (isGoodName) { - return deckName; - } - - JOptionPane.showMessageDialog(null, "Please pick another deck name, another deck currently has that name."); - return this.getDeckNameFromDialog(); - } - - /** - * Gets the default file menu. - * - * @return the default file menu - */ - protected JMenu getDefaultFileMenu() { - final JMenu fileMenu = new JMenu("Deck"); - - final JMenuItem newDoc = new JMenuItem("New"); - final JMenuItem open = new JMenuItem("Open"); - final JMenuItem save = new JMenuItem("Save"); - final JMenuItem saveAs = new JMenuItem("Save As..."); - final JMenuItem delete = new JMenuItem("Delete"); - - fileMenu.add(newDoc); - fileMenu.add(open); - fileMenu.addSeparator(); - - fileMenu.add(save); - fileMenu.add(saveAs); - fileMenu.add(delete); - - newDoc.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.newDocument(true); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : newConstructed() error - " + ex); - } - } - }); - - open.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.open(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : open() error - " + ex); - } - } - }); - - save.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.save(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : save() error - " + ex); - } - } - }); - - saveAs.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.saveAs(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : saveAs() error - " + ex); - } - } - }); - - delete.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.delete(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : delete() error - " + ex); - } - } - }); - return fileMenu; - } - - /** - * Append close menu item to. - * - * @param fileMenu the file menu - */ - protected void appendCloseMenuItemTo(final JMenu fileMenu) { - final JMenuItem close = new JMenuItem("Close"); - fileMenu.addSeparator(); - fileMenu.add(close); - - close.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - try { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - MenuBase.this.close(); - } - }); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : close() error - " + ex); - } - } - }); - } // setupMenu() - - /** - *

- * setupSortMenu. - *

- * - * @return the sort menu - */ - protected final JMenuItem getSortMenu() { - final JMenuItem name = new JMenuItem("Card Name"); - final JMenuItem cost = new JMenuItem("Cost"); - final JMenuItem color = new JMenuItem("Color"); - final JMenuItem type = new JMenuItem("Type"); - final JMenuItem stats = new JMenuItem("Power/Toughness"); - final JMenuItem rarity = new JMenuItem("Rarity"); - - final JMenu menu = new JMenu("Sort By"); - menu.add(name); - menu.add(cost); - menu.add(color); - menu.add(type); - menu.add(stats); - menu.add(rarity); - - name.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(1, true); - } - }); - - // 0 1 2 3 4 5 6 - // private String column[] = {"Qty", "Name", "Cost", "Color", "Type", - // "Stats", "Rarity"}; - cost.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(4).sort(3).sort(2); - } - }); - - color.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(4).sort(2).sort(3); - } - }); - - type.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(2).sort(3).sort(4); - } - }); - - stats.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - (MenuBase.this.controller).getView().getTopTableModel().sort(4).sort(2).sort(3).sort(5); - } - }); - - rarity.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent ev) { - // sort by cost, type, color, rarity - (MenuBase.this.controller).getView().getTopTableModel().sort(2).sort(4).sort(3).sort(6); - } - }); - - return menu; - } // setupSortMenu() -} diff --git a/src/main/java/forge/gui/deckeditor/MenuCommon.java b/src/main/java/forge/gui/deckeditor/MenuCommon.java index c779f98778b..9d74f5fd588 100644 --- a/src/main/java/forge/gui/deckeditor/MenuCommon.java +++ b/src/main/java/forge/gui/deckeditor/MenuCommon.java @@ -17,24 +17,6 @@ */ package forge.gui.deckeditor; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import javax.swing.JFileChooser; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.SwingUtilities; - -import forge.Command; -import forge.card.CardRules; -import forge.deck.Deck; -import forge.deck.generate.Generate2ColorDeck; -import forge.deck.io.DeckSerializer; -import forge.error.ErrorViewer; -import forge.game.player.PlayerType; -import forge.item.CardDb; -import forge.item.CardPrinted; -import forge.util.closures.Predicate; /** *

@@ -44,11 +26,11 @@ import forge.util.closures.Predicate; * @author Forge * @version $Id$ */ -public final class MenuCommon extends MenuBase { +public final class MenuCommon { - /** Constant serialVersionUID=-4037993759604768755L. */ + /** Constant serialVersionUID=-4037993759604768755L. * private static final long serialVersionUID = -4037993759604768755L; - /** Constant previousDirectory. */ + /** Constant previousDirectory. * private static File previousDirectory = null; /** @@ -58,7 +40,7 @@ public final class MenuCommon extends MenuBase { * the ctrl * @param exit * a Command - */ + * public MenuCommon(final DeckController ctrl, final Command exit) { super(ctrl, exit); @@ -132,7 +114,7 @@ public final class MenuCommon extends MenuBase { *

* exportDeck. *

- */ + * private void exportDeck() { final File filename = this.getExportFilename(); if (filename == null) { @@ -168,7 +150,7 @@ public final class MenuCommon extends MenuBase { *

* Generate Proxy for a Deck. *

- */ + * private void generateProxies() { final File filename = this.getProxiesFilename(); if (filename == null) { @@ -206,7 +188,7 @@ public final class MenuCommon extends MenuBase { * (non-Javadoc) * * @see forge.gui.deckeditor.MenuBase#getDefaultFileMenu() - */ + * @Override protected JMenu getDefaultFileMenu() { final JMenu fileMenu = super.getDefaultFileMenu(); @@ -327,4 +309,5 @@ public final class MenuCommon extends MenuBase { return fileMenu; } // setupMenu() + */ } diff --git a/src/main/java/forge/gui/deckeditor/MenuLimited.java b/src/main/java/forge/gui/deckeditor/MenuLimited.java deleted file mode 100644 index b13a388e92d..00000000000 --- a/src/main/java/forge/gui/deckeditor/MenuLimited.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.gui.deckeditor; - -import forge.Command; -import forge.deck.DeckGroup; - -/** - *

- * Gui_DeckEditor_Menu class. - *

- * - * @author Forge - * @version $Id: DeckEditorCommonMenu.java 13590 2012-01-27 20:46:27Z Max mtg $ - */ -public final class MenuLimited extends MenuBase { - - /** Constant serialVersionUID=-4037993759604768755L. */ - private static final long serialVersionUID = -4037993759604768755L; - - /** - * Menu for Deck Editor. - * - * @param ctrl the ctrl - * @param exit a Command - */ - public MenuLimited(final DeckController ctrl, final Command exit) { - super(ctrl, exit); - } - - // deck.setName(currentDeckName); - -} diff --git a/src/main/java/forge/gui/deckeditor/MenuQuest.java b/src/main/java/forge/gui/deckeditor/MenuQuest.java deleted file mode 100644 index a4c9d89b0a5..00000000000 --- a/src/main/java/forge/gui/deckeditor/MenuQuest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.swing.JFileChooser; -import javax.swing.JMenu; -import javax.swing.JMenuItem; - -import forge.Command; -import forge.Constant; -import forge.deck.Deck; -import forge.deck.io.DeckSerializer; -import forge.error.ErrorViewer; -import forge.gui.ListChooser; -import forge.item.CardDb; -import forge.item.CardPrinted; - -//presumes AllZone.getQuestData() is not null -/** - *

- * Gui_Quest_DeckEditor_Menu class. - *

- * - * @author Forge - * @version $Id$ - */ -public class MenuQuest extends MenuBase { - /** Constant serialVersionUID=-4052319220021158574L. */ - private static final long serialVersionUID = -4052319220021158574L; - - // used for import and export, try to made the gui user friendly - /** Constant previousDirectory. */ - private static File previousDirectory = null; - - /** - *

- * Constructor for Gui_Quest_DeckEditor_Menu. - *

- * - * @param d - * a {@link forge.gui.deckeditor.IDeckDisplay} object. - * @param exit - * a {@link forge.Command} object. - */ - public MenuQuest(final DeckController d, final Command exit) { - super(d, exit); - } - - /** - *

- * importDeck. - *

- */ - private void importDeck() { - final File file = this.getImportFilename(); - - if ((file != null) && file.getName().endsWith(".dck")) { - try { - final Deck newDeck = Deck.fromFile(file); - this.getController().importDeck(newDeck); - - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : importDeck() error, " + ex); - } - } - - } // importDeck() - - /** - *

- * getImportFilename. - *

- * - * @return a {@link java.io.File} object. - */ - private File getImportFilename() { - final JFileChooser chooser = new JFileChooser(MenuQuest.previousDirectory); - - chooser.addChoosableFileFilter(DeckSerializer.DCK_FILTER); - final int returnVal = chooser.showOpenDialog(null); - - if (returnVal == JFileChooser.APPROVE_OPTION) { - final File file = chooser.getSelectedFile(); - MenuQuest.previousDirectory = file.getParentFile(); - return file; - } - - return null; - } // openFileDialog() - - private final ActionListener addCardActionListener = new ActionListener() { - @Override - public void actionPerformed(final ActionEvent a) { - - // Provide a model here: all unique cards to be displayed by only - // name (unlike default toString) - final Iterable uniqueCards = CardDb.instance().getAllUniqueCards(); - final List cards = new ArrayList(); - for (final CardPrinted c : uniqueCards) { - cards.add(c.getName()); - } - Collections.sort(cards); - - // use standard forge's list selection dialog - final ListChooser c = new ListChooser("Cheat - Add Card to Your Cardpool", 0, 1, cards); - if (c.show()) { - ((DeckEditorQuest) MenuQuest.this.getController().getView()).addCheatCard(CardDb.instance().getCard( - c.getSelectedValue())); - } - } - }; - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.MenuBase#getDefaultFileMenu() - */ - @Override - protected JMenu getDefaultFileMenu() { - final JMenu deckMenu = super.getDefaultFileMenu(); - - final JMenuItem addCard = new JMenuItem("Cheat - Add Card"); - - addCard.addActionListener(this.addCardActionListener); - - if (Constant.Runtime.DEV_MODE[0]) { - deckMenu.addSeparator(); - deckMenu.add(addCard); - } - - deckMenu.addSeparator(); - this.addImportExport(deckMenu, true); - - this.appendCloseMenuItemTo(deckMenu); - return deckMenu; - - } - - /** - *

- * addImportExport. - *

- * - * @param menu - * a {@link javax.swing.JMenu} object. - * @param isHumanMenu - * a boolean. - */ - private void addImportExport(final JMenu menu, final boolean isHumanMenu) { - final JMenuItem import2 = new JMenuItem("Import"); - final JMenuItem export = new JMenuItem("Export"); - - import2.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent a) { - MenuQuest.this.importDeck(); // importDeck(isHumanMenu); - } - }); // import - - export.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent a) { - MenuQuest.this.exportDeck(); - } - }); // export - - menu.add(import2); - menu.add(export); - - } // addImportExport() - - private void exportDeck() { - final File filename = this.getExportFilename(); - if (filename == null) { - return; - } - - try { - DeckSerializer.writeDeck(this.getController().getModel(), filename); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - throw new RuntimeException("Gui_DeckEditor_Menu : exportDeck() error, " + ex); - } - } - - private File getExportFilename() { - final JFileChooser save = new JFileChooser(MenuQuest.previousDirectory); - save.setDialogTitle("Export Deck Filename"); - save.setDialogType(JFileChooser.SAVE_DIALOG); - save.setFileFilter(DeckSerializer.DCK_FILTER); - - if (save.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { - final File file = save.getSelectedFile(); - final String check = file.getAbsolutePath(); - - MenuQuest.previousDirectory = file.getParentFile(); - - return check.endsWith(".dck") ? file : new File(check + ".dck"); - } - return null; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/PresetColumns.java b/src/main/java/forge/gui/deckeditor/PresetColumns.java deleted file mode 100644 index 364039e3c68..00000000000 --- a/src/main/java/forge/gui/deckeditor/PresetColumns.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.util.Map.Entry; -import java.util.regex.Pattern; - -import forge.Singletons; -import forge.card.CardColor; -import forge.card.CardEdition; -import forge.card.CardManaCost; -import forge.card.CardRarity; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.InventoryItemFromSet; -import forge.util.closures.Lambda1; - -/** - * TODO: Write javadoc for this type. - * - */ -public abstract class PresetColumns { - - private static final Pattern AE_FINDER = Pattern.compile("AE", Pattern.LITERAL); - - private static CardManaCost toManaCost(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getManaCost() : CardManaCost.EMPTY; - } - - private static CardColor toColor(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getColor() : CardColor.getNullColor(); - } - - private static String toPTL(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getPTorLoyalty() : ""; - } - - private static CardRarity toRarity(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getRarity() : CardRarity.Unknown; - } - - private static CardEdition toSetCmp(final InventoryItem i) { - return i instanceof InventoryItemFromSet ? Singletons.getModel().getEditions() - .get(((InventoryItemFromSet) i).getEdition()) : CardEdition.UNKNOWN; - } - - private static String toSetStr(final InventoryItem i) { - return i instanceof InventoryItemFromSet ? ((InventoryItemFromSet) i).getEdition() : "n/a"; - } - - private static Integer toAiCmp(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatusComparable() : Integer.valueOf(-1); - } - - private static String toAiStr(final InventoryItem i) { - return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatus() : "n/a"; - } - - /** The Constant fnQtyCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_QTY_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return from.getValue(); - } - }; - - /** The Constant fnQtyGet. */ - public static final Lambda1> FN_QTY_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return from.getValue(); - } - }; - - /** The Constant fnNameCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_NAME_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return from.getKey().getName(); - } - }; - - /** The Constant fnNameGet. */ - public static final Lambda1> FN_NAME_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - final String name = from.getKey().getName(); - return name.contains("AE") ? PresetColumns.AE_FINDER.matcher(name).replaceAll("\u00C6") : name; - } - }; - - /** The Constant fnCostCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_COST_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toManaCost(from.getKey()); - } - }; - - /** The Constant fnCostGet. */ - public static final Lambda1> FN_COST_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toManaCost(from.getKey()); - } - }; - - /** The Constant fnColorCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_COLOR_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toColor(from.getKey()); - } - }; - - /** The Constant fnColorGet. */ - public static final Lambda1> FN_COLOR_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toColor(from.getKey()); - } - }; - - /** The Constant fnTypeCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_TYPE_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return from.getKey().getType(); - } - }; - - /** The Constant fnTypeGet. */ - public static final Lambda1> FN_TYPE_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return from.getKey().getType(); - } - }; - - /** The Constant fnStatsCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_STATS_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toPTL(from.getKey()); - } - }; - - /** The Constant fnStatsGet. */ - public static final Lambda1> FN_STATS_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toPTL(from.getKey()); - } - }; - - /** The Constant fnRarityCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_RARITY_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toRarity(from.getKey()); - } - }; - - /** The Constant fnRarityGet. */ - public static final Lambda1> FN_RARITY_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toRarity(from.getKey()); - } - }; - - /** The Constant fnSetCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_SET_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toSetCmp(from.getKey()); - } - }; - - /** The Constant fnSetGet. */ - public static final Lambda1> FN_SET_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toSetStr(from.getKey()); - } - }; - - /** The Constant fnAiStatusCompare. */ - @SuppressWarnings("rawtypes") - public static final Lambda1> FN_AI_STATUS_COMPARE = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return PresetColumns.toAiCmp(from.getKey()); - } - }; - - /** The Constant fnAiStatusGet. */ - public static final Lambda1> FN_AI_STATUS_GET = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return PresetColumns.toAiStr(from.getKey()); - } - }; -} diff --git a/src/main/java/forge/gui/deckeditor/QuestCardShop.java b/src/main/java/forge/gui/deckeditor/QuestCardShop.java deleted file mode 100644 index f75354c505f..00000000000 --- a/src/main/java/forge/gui/deckeditor/QuestCardShop.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - * 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.gui.deckeditor; - -import java.awt.Container; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; - - -import forge.Command; -import forge.deck.Deck; -import forge.deck.DeckBase; -import forge.error.ErrorViewer; -import forge.gui.CardListViewer; -import forge.gui.deckeditor.elements.CardPanelLite; -import forge.gui.deckeditor.elements.FilterCheckBoxes; -import forge.gui.deckeditor.elements.FilterNameTypeSetPanel; -import forge.gui.deckeditor.elements.ManaCostRenderer; -import forge.gui.deckeditor.elements.TableColumnInfo; -import forge.gui.deckeditor.elements.TableView; -import forge.item.BoosterPack; -import forge.item.CardPrinted; -import forge.item.FatPack; -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.item.ItemPoolView; -import forge.item.ItemPredicate; -import forge.item.OpenablePack; -import forge.item.PreconDeck; -import forge.item.TournamentPack; -import forge.quest.QuestController; -import forge.quest.io.ReadPriceList; -import forge.util.closures.Lambda1; -import forge.util.closures.Predicate; -import net.miginfocom.swing.MigLayout; - -/** - *

- * Gui_CardShop class. - *

- * - * @author Forge - * @version $Id$ - */ -public final class QuestCardShop extends DeckEditorBase { - /** Constant serialVersionUID=3988857075791576483L. */ - private static final long serialVersionUID = 3988857075791576483L; - - private final JButton clearFilterButton = new JButton(); - private FilterNameTypeSetPanel filterNameTypeSet; - - private final JButton buyButton = new JButton(); - private final JButton sellButton = new JButton(); - - private final JLabel creditsLabel = new JLabel(); - private final JLabel sellPercentageLabel = new JLabel(); - - private double multiplier; - - private final QuestController questData; - - // get pricelist: - private final ReadPriceList r = new ReadPriceList(); - private final Map mapPrices = this.r.getPriceList(); - private Map decksUsingMyCards; - - /** - * Show. - * - * @param exitCommand - * the exit command - */ - @Override - public void show(final Command exitCommand) { - final Command exit = new Command() { - private static final long serialVersionUID = -7428793574300520612L; - - @Override - public void execute() { - QuestCardShop.this.dispose(); - exitCommand.execute(); - } - }; - - // do not change this!!!! - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent ev) { - exit.execute(); - } - }); - - this.setup(); - - this.decksUsingMyCards = this.countDecksForEachCard(); - - this.multiplier = this.questData.getCards().getSellMutliplier(); - - ItemPoolView forSale = this.questData.getCards().getShopList(); - if (forSale.isEmpty()) { - this.questData.getCards().generateCardsInShop(); - forSale = this.questData.getCards().getShopList(); - } - // newCardsList = questData.getCards().getNewCards(); - final ItemPool ownedItems = new ItemPool(InventoryItem.class); - ownedItems.addAll(this.questData.getCards().getCardpool().getView()); - - this.getTopTableModel().setDeck(forSale); - this.getBottomTableWithCards().setDeck(ownedItems); - - this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); - - final double multiPercent = this.multiplier * 100; - final NumberFormat formatter = new DecimalFormat("#0.00"); - String maxSellingPrice = ""; - final int maxSellPrice = this.questData.getCards().getSellPriceLimit(); - - if (maxSellPrice < Integer.MAX_VALUE) { - maxSellingPrice = String.format("Maximum selling price is %d credits.", maxSellPrice); - } - this.sellPercentageLabel.setText("Selling cards at " + formatter.format(multiPercent) - + "% of their value.
" + maxSellingPrice + ""); - - this.filterNameTypeSet.setListeners(new OnChangeTextUpdateDisplay(), this.getItemListenerUpdatesDisplay()); - - this.getTopTableWithCards().sort(1, true); - this.getBottomTableWithCards().sort(1, true); - } // show(Command) - - // fills number of decks using each card - private Map countDecksForEachCard() { - final Map result = new HashMap(); - for (final Deck deck : this.questData.getMyDecks()) { - for (final Entry e : deck.getMain()) { - final CardPrinted card = e.getKey(); - final Integer amount = result.get(card); - result.put(card, Integer.valueOf(amount == null ? 1 : 1 + amount.intValue())); - } - } - return result; - } - - /** - *

- * setup. - *

- */ - private void setup() { - final List> columns = new ArrayList>(); - columns.add(new TableColumnInfo("Qty", 30, PresetColumns.FN_QTY_COMPARE, - PresetColumns.FN_QTY_GET)); - columns.add(new TableColumnInfo("Name", 176, PresetColumns.FN_NAME_COMPARE, - PresetColumns.FN_NAME_GET)); - columns.add(new TableColumnInfo("Cost", 70, PresetColumns.FN_COST_COMPARE, - PresetColumns.FN_COST_GET)); - columns.add(new TableColumnInfo("Color", 50, PresetColumns.FN_COLOR_COMPARE, - PresetColumns.FN_COLOR_GET)); - columns.add(new TableColumnInfo("Type", 100, PresetColumns.FN_TYPE_COMPARE, - PresetColumns.FN_TYPE_GET)); - columns.add(new TableColumnInfo("Stats", 40, PresetColumns.FN_STATS_COMPARE, - PresetColumns.FN_STATS_GET)); - columns.add(new TableColumnInfo("R", 25, PresetColumns.FN_RARITY_COMPARE, - PresetColumns.FN_RARITY_GET)); - columns.add(new TableColumnInfo("Set", 35, PresetColumns.FN_SET_COMPARE, - PresetColumns.FN_SET_GET)); - columns.get(2).setCellRenderer(new ManaCostRenderer()); - - final List> columnsBelow = new ArrayList>(columns); - columns.add(new TableColumnInfo("Price", 45, this.fnPriceCompare, this.fnPriceGet)); - this.getTopTableWithCards().setup(columns, this.getCardView()); - - columnsBelow.add(new TableColumnInfo("Dks", 30, this.fnDeckCompare, this.fnDeckGet)); - columnsBelow.add(new TableColumnInfo("New", 35, this.questData.getCards().getFnNewCompare(), - this.questData.getCards().getFnNewGet())); - columnsBelow.add(new TableColumnInfo("Price", 45, this.fnPriceCompare, this.fnPriceSellGet)); - this.getBottomTableWithCards().setup(columnsBelow, this.getCardView()); - - this.setSize(1024, 740); - } - - /** - *

- * Constructor for Gui_CardShop. - *

- * - * @param parent the parent frame for this deck editor instance - * @param qd - * a {@link forge.quest.data.QuestData} object. - */ - public QuestCardShop(JFrame parent, final QuestController qd) { - super(parent); - this.questData = qd; - try { - this.setFilterBoxes(new FilterCheckBoxes(true)); - this.setTopTableWithCards(new TableView("Cards for sale", false, false, InventoryItem.class)); - this.setBottomTableWithCards(new TableView("Owned Cards", false, InventoryItem.class)); - this.setCardView(new CardPanelLite()); - this.filterNameTypeSet = new FilterNameTypeSetPanel(); - this.jbInit(); - } catch (final Exception ex) { - ErrorViewer.showError(ex); - } - } - - /** - *

- * jbInit. - *

- * - * @throws java.lang.Exception - * if any. - */ - private void jbInit() throws Exception { - - final Font font = new java.awt.Font("Dialog", 0, 13); - this.clearFilterButton.setFont(font); - this.buyButton.setFont(font); - this.sellButton.setFont(font); - this.creditsLabel.setFont(font); - this.sellPercentageLabel.setFont(font); - - this.clearFilterButton.setText("Clear Filter"); - this.buyButton.setText("Buy Card"); - this.sellButton.setText("Sell Card"); - - this.clearFilterButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - QuestCardShop.this.clearFilterButtonActionPerformed(e); - } - }); - this.buyButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - QuestCardShop.this.buyButtonActionPerformed(e); - } - }); - this.sellButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - QuestCardShop.this.sellButtonActionPerformed(e); - } - }); - - // Type filtering - final Font f = new Font("Tahoma", Font.PLAIN, 10); - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - box.setFont(f); - box.setOpaque(false); - } - - // Color filtering - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - box.setOpaque(false); - } - - this.setTitle("Card Shop"); - - final Container content = this.getContentPane(); - final MigLayout layout = new MigLayout("fill"); - content.setLayout(layout); - - boolean isFirst = true; - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - String growParameter = "grow"; - if (isFirst) { - growParameter = "cell 0 0, egx checkbox, grow, split 14"; - isFirst = false; - } - content.add(box, growParameter); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - content.add(box, "grow"); - box.addItemListener(this.getItemListenerUpdatesDisplay()); - } - - content.add(this.clearFilterButton, "wmin 100, hmin 25, wmax 140, hmax 25, grow"); - - content.add(this.filterNameTypeSet, "cell 0 1, grow"); - content.add(this.getTopTableWithCards().getTableDecorated(), "cell 0 2 1 2, push, grow"); - - content.add(this.buyButton, "w 100, h 49, sg button, cell 0 5, split 5"); - content.add(this.sellButton, "w 100, h 49, sg button"); - - content.add(this.creditsLabel, "w 100, h 49"); - content.add(this.sellPercentageLabel, "w 300, h 49, wrap"); - - content.add(this.getBottomTableWithCards().getTableDecorated(), "cell 0 6, grow"); - - content.add(this.getCardView(), "cell 1 0 1 7, flowy, grow"); - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#buildFilter() - */ - @Override - protected Predicate buildFilter() { - final Predicate cardFilter = Predicate.and( - this.getFilterBoxes().buildFilter(), - this.filterNameTypeSet.buildFilter()); - - // Until this is filterable, always show packs and decks in the card shop - Predicate filter = Predicate.instanceOf(cardFilter, CardPrinted.class); - filter = Predicate.or(filter, ItemPredicate.Presets.IS_PACK); - filter = Predicate.or(filter, ItemPredicate.Presets.IS_DECK); - - return filter; - } - - /** - * Clear filter button_action performed. - * - * @param e - * the e - */ - void clearFilterButtonActionPerformed(final ActionEvent e) { - // disable automatic update triggered by listeners - this.setFiltersChangeFiringUpdate(false); - - for (final JCheckBox box : this.getFilterBoxes().getAllTypes()) { - if (!box.isSelected()) { - box.doClick(); - } - } - for (final JCheckBox box : this.getFilterBoxes().getAllColors()) { - if (!box.isSelected()) { - box.doClick(); - } - } - - this.filterNameTypeSet.clearFilters(); - - this.setFiltersChangeFiringUpdate(true); - - this.getTopTableWithCards().setFilter(null); - } - - // TODO: move to cardshop - private Integer getCardValue(final InventoryItem card) { - if (this.mapPrices.containsKey(card.getName())) { - return this.mapPrices.get(card.getName()); - } else if (card instanceof CardPrinted) { - switch (((CardPrinted) card).getRarity()) { - case BasicLand: - return Integer.valueOf(4); - case Common: - return Integer.valueOf(6); - case Uncommon: - return Integer.valueOf(40); - case Rare: - return Integer.valueOf(120); - case MythicRare: - return Integer.valueOf(600); - default: - return Integer.valueOf(15); - } - } else if (card instanceof BoosterPack) { - return 395; - } else if (card instanceof TournamentPack) { - return 995; - } else if (card instanceof FatPack) { - return 2365; - } else if (card instanceof PreconDeck) { - return ((PreconDeck) card).getRecommendedDeals().getCost(); - } - return 1337; - } - - private void buyButtonActionPerformed(final ActionEvent e) { - final InventoryItem item = this.getTopTableWithCards().getSelectedCard(); - if (item == null) { - return; - } - - final int value = this.getCardValue(item); - - if (value <= this.questData.getAssets().getCredits()) { - - if (item instanceof CardPrinted) { - this.getTopTableWithCards().removeCard(item); - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().addCard(card); - this.questData.getCards().buyCard(card, value); - - } else if (item instanceof OpenablePack) { - this.getTopTableWithCards().removeCard(item); - - OpenablePack booster = null; - if (item instanceof BoosterPack) { - booster = (BoosterPack) ((BoosterPack) item).clone(); - } else if (item instanceof TournamentPack) { - booster = (TournamentPack) ((TournamentPack) item).clone(); - } else if (item instanceof FatPack) { - booster = (FatPack) ((FatPack) item).clone(); - } - this.questData.getCards().buyPack(booster, value); - final List newCards = booster.getCards(); - for (final CardPrinted card : newCards) { - this.getBottomTableWithCards().addCard(card); - } - final CardListViewer c = new CardListViewer(booster.getName(), - "You have found the following cards inside:", newCards); - c.show(); - } else if (item instanceof PreconDeck) { - this.getTopTableWithCards().removeCard(item); - final PreconDeck deck = (PreconDeck) item; - this.questData.getCards().buyPreconDeck(deck, value); - - for (final CardPrinted card : deck.getDeck().getMain().toFlatList()) { - this.getBottomTableWithCards().addCard(card); - } - JOptionPane.showMessageDialog(null, String.format( - "Deck '%s' was added to your decklist.%n%nCards from it were also added to your pool.", - deck.getName()), "Thanks for purchasing!", JOptionPane.INFORMATION_MESSAGE); - - } - - this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); - } else { - JOptionPane.showMessageDialog(null, "Not enough credits!"); - } - } - - private void sellButtonActionPerformed(final ActionEvent e) { - final InventoryItem item = this.getBottomTableWithCards().getSelectedCard(); - if ((item == null) || !(item instanceof CardPrinted)) { - return; - } - - final CardPrinted card = (CardPrinted) item; - this.getBottomTableWithCards().removeCard(card); - this.getTopTableWithCards().addCard(card); - - final int price = Math.min((int) (this.multiplier * this.getCardValue(card)), this.questData.getCards() - .getSellPriceLimit()); - this.questData.getCards().sellCard(card, price); - - this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); - } - - @SuppressWarnings("rawtypes") - private final Lambda1> fnPriceCompare = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - return QuestCardShop.this.getCardValue(from.getKey()); - } - }; - private final Lambda1> fnPriceGet = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return QuestCardShop.this.getCardValue(from.getKey()); - } - }; - private final Lambda1> fnPriceSellGet = new Lambda1>() { - @Override - public Object apply(final Entry from) { - return (int) (QuestCardShop.this.multiplier * QuestCardShop.this.getCardValue(from.getKey())); - } - }; - - @SuppressWarnings("rawtypes") - private final Lambda1> fnDeckCompare = new Lambda1>() { - @Override - public Comparable apply(final Entry from) { - final Integer iValue = QuestCardShop.this.decksUsingMyCards.get(from.getKey()); - return iValue == null ? Integer.valueOf(0) : iValue; - } - }; - private final Lambda1> fnDeckGet = new Lambda1>() { - @Override - public Object apply(final Entry from) { - final Integer iValue = QuestCardShop.this.decksUsingMyCards.get(from.getKey()); - return iValue == null ? "" : iValue.toString(); - } - }; - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#getController() - */ - @Override - public DeckController getController() { - return null; - } - - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.DeckEditorBase#updateView() - */ - @Override - public void updateView() { - } - -} diff --git a/src/main/java/forge/gui/deckeditor/SEditorIO.java b/src/main/java/forge/gui/deckeditor/SEditorIO.java new file mode 100644 index 00000000000..9037d0103c3 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/SEditorIO.java @@ -0,0 +1,326 @@ +package forge.gui.deckeditor; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +import javax.swing.JOptionPane; +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; + +import forge.deck.DeckBase; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.SColumnUtil.SortState; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.item.InventoryItem; +import forge.properties.NewConstants; + +/** + * Handles editor preferences saving and loading. + * + *

(S at beginning of class name denotes a static factory.) + */ +public class SEditorIO { + /** Used in the XML IO to extract properties from PREFS file. */ + private enum ColumnProperty { /** */ + enumval, /** */ + identifier, /** */ + index, /** */ + show, /** */ + sortpriority, /** */ + sortstate, /** */ + width + } + + /** Preferences (must match with PREFS file). */ + public enum EditorPreference { /** */ + stats_deck, /** */ + stats_catalog + } + + private static final XMLEventFactory EVENT_FACTORY = XMLEventFactory.newInstance(); + private static final XMLEvent NEWLINE = EVENT_FACTORY.createDTD("\n"); + private static final XMLEvent TAB = EVENT_FACTORY.createDTD("\t"); + + private static final Map PREFS + = new HashMap(); + + private static final Map> COLS + = new TreeMap>(); + + /** + * Retrieve a preference from the editor preference map. + * + * @param name0   {@link forge.gui.deckeditor.SEditorUtil.EditorPreference} + * @return TableColumnInfo + */ + public static boolean getPref(final EditorPreference name0) { + return PREFS.get(name0); + } + + /** + * Set a preference in the editor preference map. + * + * @param name0   {@link forge.gui.deckeditor.SEditorUtil.EditorPreference} + * @param val0   boolean + */ + public static void setPref(final EditorPreference name0, final boolean val0) { + PREFS.put(name0, val0); + } + + /** + * Retrieve a custom column. + * + * @param name0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return TableColumnInfo + */ + public static TableColumnInfo getColumn(final ColumnName name0) { + return COLS.get(name0); + } + + /** + * Saves the current deck, with various prompts depending on the + * current save environment. + * + * @return boolean, true if success + */ + @SuppressWarnings("unchecked") + public static boolean saveDeck() { + final DeckController controller = (DeckController) CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckController(); + final String name = VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().getText(); + + // Warn if no name + if (name.equals("[New Deck]") || name.isEmpty()) { + JOptionPane.showMessageDialog(null, + "Please name your deck using the 'Title' box.", + "Save Error!", + JOptionPane.ERROR_MESSAGE); + return false; + } + // Confirm if overwrite + else if (controller.fileExists(name)) { + final int m = JOptionPane.showConfirmDialog(null, + "There is already a deck named '" + name + "'. Overwrite?", + "Overwrite Deck?", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (m == JOptionPane.YES_OPTION) { controller.save(); } + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("Current Deck"); + } + // Confirm if a new deck will be created + else { + final int m = JOptionPane.showConfirmDialog(null, + "This will create a new deck named '" + name + "'. Continue?", + "Create Deck?", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (m == JOptionPane.YES_OPTION) { controller.saveAs(name); } + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("Current Deck"); + } + + return true; + } + + /** + * Prompts to save changes if necessary. + * + * @return boolean, true if success + */ + @SuppressWarnings("unchecked") + public static boolean confirmSaveChanges() { + if (!((DeckController) CDeckEditorUI + .SINGLETON_INSTANCE.getCurrentEditorController().getDeckController()).isSaved()) { + final int choice = JOptionPane.showConfirmDialog(null, + "Save changes to current deck?", + "Save Changes?", + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (choice == JOptionPane.CANCEL_OPTION) { return false; } + + if (choice == JOptionPane.YES_OPTION && !saveDeck()) { return false; } + } + + return true; + } + + /** Publicly-accessible save method, to neatly handle exception handling. */ + public static void savePreferences() { + try { save(); } + catch (final Exception e) { e.printStackTrace(); } + } + + /** Publicly-accessible load method, to neatly handle exception handling. */ + public static void loadPreferences() { + try { load(); } + catch (final Exception e) { e.printStackTrace(); } + } + + /** + * + * TODO: Write javadoc for this method. + * + * @param extends InventoryItem + * @param extends DeckBase + */ + private static void save() throws Exception { + final XMLOutputFactory out = XMLOutputFactory.newInstance(); + final XMLEventWriter writer = out.createXMLEventWriter(new FileOutputStream(NewConstants.PREFS_EDITOR_FILE)); + + writer.add(EVENT_FACTORY.createStartDocument()); + writer.add(NEWLINE); + writer.add(EVENT_FACTORY.createStartElement("", "", "preferences")); + writer.add(EVENT_FACTORY.createAttribute("type", "editor")); + writer.add(NEWLINE); + + for (final EditorPreference p : PREFS.keySet()) { + writer.add(TAB); + writer.add(EVENT_FACTORY.createStartElement("", "", "pref")); + writer.add(EVENT_FACTORY.createAttribute( + "name", p.toString())); + writer.add(EVENT_FACTORY.createAttribute( + "value", PREFS.get(p).toString())); + writer.add(EVENT_FACTORY.createEndElement("", "", "pref")); + writer.add(NEWLINE); + } + + for (final ColumnName c : COLS.keySet()) { + // If column is not in view, retain previous model index for the next time + // that the column will be in the view. + int index = SColumnUtil.getColumnViewIndex(c); + if (index == -1) { + index = COLS.get(c).getModelIndex(); + } + + writer.add(TAB); + writer.add(EVENT_FACTORY.createStartElement("", "", "col")); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.enumval.toString(), COLS.get(c).getEnumValue())); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.identifier.toString(), COLS.get(c).getIdentifier().toString())); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.index.toString(), String.valueOf(index))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.show.toString(), String.valueOf(COLS.get(c).isShowing()))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.sortpriority.toString(), String.valueOf(COLS.get(c).getSortPriority()))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.sortstate.toString(), String.valueOf(COLS.get(c).getSortState()))); + writer.add(EVENT_FACTORY.createAttribute( + ColumnProperty.width.toString(), String.valueOf(COLS.get(c).getWidth()))); + writer.add(EVENT_FACTORY.createEndElement("", "", "col")); + writer.add(NEWLINE); + } + + writer.add(EVENT_FACTORY.createEndDocument()); + writer.flush(); + writer.close(); + } + + private static void load() throws Exception { + // Preferences files have been consolidated into res/preferences/. + // This code is here temporarily to facilitate this transfer. + // After a while, this can be deleted. Doublestrike 21-5-12 + final File oldFile = new File("editor.preferences"); + if (oldFile.exists()) { + final File newFile = new File(NewConstants.PREFS_EDITOR_FILE); + final InputStream in = new FileInputStream(oldFile); + final OutputStream out = new FileOutputStream(newFile); + + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + in.close(); + out.close(); + + oldFile.delete(); + } // END TEMPORARY CONSOLIDATION FACILITATION + + final XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + final String fileAddress = NewConstants.PREFS_EDITOR_FILE; + final XMLEventReader reader = inputFactory.createXMLEventReader(new FileInputStream(fileAddress)); + + PREFS.clear(); + COLS.clear(); + + XMLEvent event; + StartElement element; + Iterator attributes; + Attribute attribute; + EditorPreference pref; + TableColumnInfo tempcol; + String tagname; + + while (reader.hasNext()) { + event = reader.nextEvent(); + + if (event.isStartElement()) { + element = event.asStartElement(); + tagname = element.getName().getLocalPart(); + + // Assemble preferences + if (tagname.equals("pref")) { + // Retrieve name of pref + attributes = element.getAttributes(); + pref = EditorPreference.valueOf(((Attribute) attributes.next()).getValue()); + + // Add to map + PREFS.put(pref, Boolean.valueOf(((Attribute) attributes.next()).getValue())); + } + // Assemble columns + else if (tagname.equals("col")) { + attributes = element.getAttributes(); + tempcol = new TableColumnInfo(); + + while (attributes.hasNext()) { + attribute = (Attribute) attributes.next(); + if (attribute.getName().toString().equals(ColumnProperty.enumval.toString())) { + COLS.put(ColumnName.valueOf(attribute.getValue()), tempcol); + tempcol.setEnumValue(attribute.getValue()); + } + else if (attribute.getName().toString().equals(ColumnProperty.identifier.toString())) { + tempcol.setIdentifier(attribute.getValue()); + tempcol.setHeaderValue(attribute.getValue()); + } + else if (attribute.getName().toString().equals(ColumnProperty.width.toString())) { + tempcol.setPreferredWidth(Integer.valueOf(attribute.getValue())); + } + else if (attribute.getName().toString().equals(ColumnProperty.show.toString())) { + tempcol.setShowing(Boolean.valueOf(attribute.getValue())); + } + else if (attribute.getName().toString().equals(ColumnProperty.sortpriority.toString())) { + tempcol.setSortPriority(Integer.valueOf(attribute.getValue())); + } + else if (attribute.getName().toString().equals(ColumnProperty.sortstate.toString())) { + tempcol.setSortState(SortState.valueOf(attribute.getValue().toString())); + } + else if (attribute.getName().toString().equals(ColumnProperty.index.toString())) { + tempcol.setModelIndex(Integer.valueOf(attribute.getValue())); + } + } + } + } + } + + SColumnUtil.attachSortAndDisplayFunctions(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/SEditorUtil.java b/src/main/java/forge/gui/deckeditor/SEditorUtil.java new file mode 100644 index 00000000000..081cfd21d71 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/SEditorUtil.java @@ -0,0 +1,149 @@ +package forge.gui.deckeditor; + +import javax.swing.ImageIcon; + +import forge.card.CardRules; +import forge.gui.deckeditor.views.ITableContainer; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.toolbox.FSkin; +import forge.item.InventoryItem; +import forge.item.ItemPoolView; + +/** + * Static methods for working with top-level editor methods, + * included but not limited to preferences IO, icon generation, + * and stats analysis. + * + *

+ * (S at beginning of class name denotes a static factory.) + * + */ +public final class SEditorUtil { + /** Pre-cached resized version. */ + public static final ImageIcon ICO_ARTIFACT = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_ARTIFACT, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_CREATURE = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_CREATURE, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_ENCHANTMENT = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_ENCHANTMENT, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_INSTANT = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_INSTANT, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_LAND = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_LAND, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_PLANESWALKER = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_PLANESWALKER, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_SORCERY = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_SORCERY, 18, 18)); + + /** Pre-cached resized version. */ + public static final ImageIcon ICO_TOTAL = + new ImageIcon(FSkin.getImage(FSkin.ZoneImages.ICO_HAND, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_MULTI = + new ImageIcon(FSkin.getImage(FSkin.EditorImages.IMG_MULTI, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_BLACK = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_BLACK, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_BLUE = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_BLUE, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_GREEN = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_GREEN, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_RED = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_RED, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_WHITE = + new ImageIcon(FSkin.getImage(FSkin.ManaImages.IMG_WHITE, 18, 18)); + /** Pre-cached resized version. */ + public static final ImageIcon ICO_COLORLESS = + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_X, 18, 18)); + + /** + * Divides X by Y, multiplies by 100, rounds, returns. + * + * @param x0   Numerator (int) + * @param y0   Denominator (int) + * @return rounded result (int) + */ + public static int calculatePercentage(final int x0, final int y0) { + return (int) Math.round((double) x0 / (double) y0 * 100); + } + + /** + * setStats. + * + * @param   the generic type + * @param deck   ItemPoolView + * @param view   {@link forge.gui.deckeditor.views.ITableContainer} + */ + public static void setStats(final ItemPoolView deck, final ITableContainer view) { + view.getLblTotal().setText(String.valueOf(deck.countAll())); + + view.getLblCreature().setText(String.valueOf(CardRules.Predicates.Presets + .IS_CREATURE.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblLand().setText(String.valueOf(CardRules.Predicates.Presets + .IS_LAND.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblEnchantment().setText(String.valueOf(CardRules.Predicates.Presets + .IS_ENCHANTMENT.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblArtifact().setText(String.valueOf(CardRules.Predicates.Presets + .IS_ARTIFACT.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblInstant().setText(String.valueOf(CardRules.Predicates.Presets + .IS_INSTANT.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblSorcery().setText(String.valueOf(CardRules.Predicates.Presets + .IS_SORCERY.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblPlaneswalker().setText(String.valueOf(CardRules.Predicates.Presets + .IS_PLANESWALKER.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblColorless().setText(String.valueOf(CardRules.Predicates.Presets + .IS_COLORLESS.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblBlack().setText(String.valueOf(CardRules.Predicates.Presets + .IS_BLACK.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblBlue().setText(String.valueOf(CardRules.Predicates.Presets + .IS_BLUE.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblGreen().setText(String.valueOf(CardRules.Predicates.Presets + .IS_GREEN.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblRed().setText(String.valueOf(CardRules.Predicates.Presets + .IS_RED.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + + view.getLblWhite().setText(String.valueOf(CardRules.Predicates.Presets + .IS_WHITE.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()))); + } // getStats() + + /** + * Set all components visible that may have been hidden + * by various configurations of the deck editor. + */ + public static void resetUI() { + VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(true); + VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(true); + + VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(true); + VCurrentDeck.SINGLETON_INSTANCE.getBtnNew().setVisible(true); + VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen().setVisible(true); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setEnabled(true); + VCardCatalog.SINGLETON_INSTANCE.getLblTitle().setText(""); + + VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(true); + VCardCatalog.SINGLETON_INSTANCE.getPnlHeader().setVisible(true); + } +} diff --git a/src/main/java/forge/gui/deckeditor/SFilterUtil.java b/src/main/java/forge/gui/deckeditor/SFilterUtil.java new file mode 100644 index 00000000000..705bbb7e50f --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/SFilterUtil.java @@ -0,0 +1,515 @@ +package forge.gui.deckeditor; + +import java.awt.Graphics; +import java.awt.Image; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.border.EmptyBorder; + +import forge.card.CardEdition; +import forge.card.CardRules; +import forge.game.GameFormat; +import forge.gui.WrapLayout; +import forge.gui.deckeditor.controllers.CFilters; +import forge.gui.deckeditor.views.VFilters; +import forge.item.CardPrinted; +import forge.util.closures.Predicate; +import forge.util.closures.Predicate.ComparableOp; +import forge.util.closures.PredicateString.StringOp; + +/** + * Static factory; holds blocks of form elements and predicates + * which are used in various editing environments. + *

+ * (S at beginning of class name denotes a static factory.) + */ +public class SFilterUtil { + /** An enum to reference checkbox objects in their respective maps. */ + private enum FilterProperty { /** */ + BLACK, /** */ + BLUE, /** */ + COLORLESS, /** */ + GREEN, /** */ + MULTICOLOR, /** */ + RED, /** */ + WHITE, /** */ + + ARTIFACT, /** */ + CREATURE, /** */ + ENCHANTMENT, /** */ + INSTANT, /** */ + LAND, /** */ + PLANESWALKER, /** */ + SORCERY + } + + private static final Map MAP_COLOR_CHECKBOXES = + new HashMap(); + + private static final Map MAP_TYPE_CHECKBOXES = + new HashMap(); + + /** + + */ + private static boolean preventFiltering = false; + + /** + * This will prevent a filter event on a checkbox state change. + * It's used for programmatic changes to the checkboxes when rebuilding + * the filter each time is expensive. + * + * @return boolean   true if filtering is prevented + */ + public static boolean isFilteringPrevented() { + return preventFiltering; + } + + /** + * This will prevent a filter event on a checkbox state change. + * It's used for programmatic changes to the checkboxes when rebuilding + * the filter each time is expensive. + * + * @param bool0   true to prevent filtering + */ + public static void setPreventFiltering(final boolean bool0) { + preventFiltering = bool0; + } + + /** + * Fills and returns a JPanel with checkboxes for color filter set. + * + * @return {@link javax.swing.JPanel} + */ + public static JPanel populateColorFilters() { + MAP_COLOR_CHECKBOXES.clear(); + + MAP_COLOR_CHECKBOXES.put(FilterProperty.BLACK, + new ChbPnl(SEditorUtil.ICO_BLACK.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.MULTICOLOR, + new ChbPnl(SEditorUtil.ICO_MULTI.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.BLUE, + new ChbPnl(SEditorUtil.ICO_BLUE.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.BLACK, + new ChbPnl(SEditorUtil.ICO_BLACK.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.GREEN, + new ChbPnl(SEditorUtil.ICO_GREEN.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.RED, + new ChbPnl(SEditorUtil.ICO_RED.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.WHITE, + new ChbPnl(SEditorUtil.ICO_WHITE.getImage())); + MAP_COLOR_CHECKBOXES.put(FilterProperty.COLORLESS, + new ChbPnl(SEditorUtil.ICO_COLORLESS.getImage())); + + + final JPanel pnl = new JPanel(new WrapLayout(SwingConstants.CENTER, 10, 5)); + pnl.setOpaque(false); + + for (FilterProperty p : MAP_COLOR_CHECKBOXES.keySet()) { + pnl.add(MAP_COLOR_CHECKBOXES.get(p)); + } + return pnl; + } + + /** + * Fills and returns a JPanel with checkboxes for color filter set. + * + * @return {@link javax.swing.JPanel} + */ + public static JPanel populateTypeFilters() { + MAP_TYPE_CHECKBOXES.clear(); + + MAP_TYPE_CHECKBOXES.put(FilterProperty.ARTIFACT, + new ChbPnl(SEditorUtil.ICO_ARTIFACT.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.CREATURE, + new ChbPnl(SEditorUtil.ICO_CREATURE.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.ENCHANTMENT, + new ChbPnl(SEditorUtil.ICO_ENCHANTMENT.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.INSTANT, + new ChbPnl(SEditorUtil.ICO_INSTANT.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.LAND, + new ChbPnl(SEditorUtil.ICO_LAND.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.PLANESWALKER, + new ChbPnl(SEditorUtil.ICO_PLANESWALKER.getImage())); + MAP_TYPE_CHECKBOXES.put(FilterProperty.SORCERY, + new ChbPnl(SEditorUtil.ICO_SORCERY.getImage())); + + + final JPanel pnl = new JPanel(new WrapLayout(SwingConstants.CENTER, 10, 5)); + pnl.setOpaque(false); + + for (FilterProperty p : MAP_TYPE_CHECKBOXES.keySet()) { + pnl.add(MAP_TYPE_CHECKBOXES.get(p)); + } + return pnl; + } + + /** Turns all type checkboxes off or on. + * @param select0   boolean */ + public static void toggleTypeCheckboxes(final boolean select0) { + for (FilterProperty p : MAP_TYPE_CHECKBOXES.keySet()) { + ((ChbPnl) MAP_TYPE_CHECKBOXES.get(p)).getCheckBox().setSelected(select0); + } + } + + /** Turns all type checkboxes off or on. + * @param select0   boolean */ + public static void toggleColorCheckboxes(final boolean select0) { + for (FilterProperty p : MAP_COLOR_CHECKBOXES.keySet()) { + ((ChbPnl) MAP_COLOR_CHECKBOXES.get(p)).getCheckBox().setSelected(select0); + } + } + + /** + * Assembles checkboxes for color and returns a filter predicate. + *

+ * Handles "multicolor" label, which is quite tricky. + * + * @return Predicate + */ + public static Predicate buildColorFilter() { + if (MAP_COLOR_CHECKBOXES.isEmpty()) { return Predicate.getTrue(CardPrinted.class); } + + final List> ors = new ArrayList>(); + JCheckBox chbTemp; + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.BLACK)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_BLACK); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.BLUE)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_BLUE); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.GREEN)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_GREEN); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.RED)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_RED); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.WHITE)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_WHITE); } + + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.COLORLESS)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_COLORLESS); } + + // Multi-colored needs special XOR treatment, since "not multi" when OR-ed + // with any other of its colors except colorless, will return true. + // Careful when changing this. + chbTemp = ((ChbPnl) MAP_COLOR_CHECKBOXES.get(FilterProperty.MULTICOLOR)).getCheckBox(); + final Predicate preMulti; + if (chbTemp.isSelected()) { + preMulti = Predicate.getTrue(CardPrinted.class); + } + else { + preMulti = Predicate.not(Predicate.brigde( + CardRules.Predicates.Presets.IS_MULTICOLOR, CardPrinted.FN_GET_RULES)); + } + + final Predicate preColors = + Predicate.brigde(Predicate.or(ors), CardPrinted.FN_GET_RULES); + + // Corner case: if multi is checked, and the rest are empty, AND won't work. + // This still doesn't work perfectly :/ + boolean allEmptyExceptMulti = true; + for (FilterProperty p : MAP_COLOR_CHECKBOXES.keySet()) { + if (p.equals(FilterProperty.MULTICOLOR)) { continue; } + if (((ChbPnl) MAP_COLOR_CHECKBOXES.get(p)).getCheckBox().isSelected()) { + allEmptyExceptMulti = false; + break; + } + } + + if (allEmptyExceptMulti) { + return Predicate.brigde( + CardRules.Predicates.Presets.IS_MULTICOLOR, CardPrinted.FN_GET_RULES); + } + else { + return Predicate.and(preColors, preMulti); + } + } + + /** + * Filters the set/format combo box. + * + * @return Predicate + */ + public static Predicate buildSetAndFormatFilter() { + // Set/Format filter + if (VFilters.SINGLETON_INSTANCE.getCbxSets().getSelectedIndex() == 0) { + return Predicate.getTrue(CardPrinted.class); + } + + final Object selected = VFilters.SINGLETON_INSTANCE.getCbxSets().getSelectedItem(); + final Predicate filter; + if (selected instanceof CardEdition) { + filter = CardPrinted.Predicates.printedInSets(((CardEdition) selected).getCode()); + } + else { + filter = ((GameFormat) selected).getFilterRules(); + } + + return filter; + } + + /** + * Assembles checkboxes for type and returns a filter predicate. + * + * @return Predicate + */ + public static Predicate buildTypeFilter() { + if (MAP_TYPE_CHECKBOXES.isEmpty()) { return Predicate.getTrue(CardPrinted.class); } + + final List> ors = new ArrayList>(); + JCheckBox chbTemp; + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.ARTIFACT)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_ARTIFACT); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.CREATURE)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_CREATURE); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.ENCHANTMENT)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_ENCHANTMENT); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.INSTANT)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_INSTANT); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.LAND)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_LAND); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.PLANESWALKER)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_PLANESWALKER); } + + chbTemp = ((ChbPnl) MAP_TYPE_CHECKBOXES.get(FilterProperty.SORCERY)).getCheckBox(); + if (chbTemp.isSelected()) { ors.add(CardRules.Predicates.Presets.IS_SORCERY); } + + return Predicate.brigde(Predicate.or(ors), CardPrinted.FN_GET_RULES); + } + + /** + * Validates text field input (from txfContains and txfWithout), + * then assembles AND and NOT predicates accordingly, ANDs + * together, and returns. + * + * @return Predicate + */ + public static Predicate buildTextFilter() { + Predicate filterAnd = Predicate.getTrue(CardPrinted.class); + Predicate filterNot = Predicate.getTrue(CardPrinted.class); + + final String strContains = VFilters.SINGLETON_INSTANCE.getTxfContains().getText(); + final String strWithout = VFilters.SINGLETON_INSTANCE.getTxfWithout().getText(); + + if (!strContains.isEmpty()) { + final String[] splitContains = strContains + .replaceAll(",", "") + .replaceAll(" ", " ") + .toLowerCase().split(" "); + + final List> ands = new ArrayList>(); + + for (final String s : splitContains) { + final List> subands = new ArrayList>(); + subands.add(Predicate.brigde(CardRules.Predicates.name( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subands.add(Predicate.brigde(CardRules.Predicates.joinedType( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subands.add(Predicate.brigde(CardRules.Predicates.rules( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + + ands.add(Predicate.or(subands)); + } + + filterAnd = Predicate.and(ands); + } + + if (!strWithout.isEmpty()) { + final String[] splitWithout = strWithout + .replaceAll(" ", " ") + .replaceAll(",", "") + .toLowerCase().split(" "); + + final List> nots = new ArrayList>(); + + for (final String s : splitWithout) { + final List> subnots = new ArrayList>(); + + subnots.add(Predicate.brigde(CardRules.Predicates.name( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subnots.add(Predicate.brigde(CardRules.Predicates.joinedType( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + subnots.add(Predicate.brigde(CardRules.Predicates.rules( + StringOp.CONTAINS, s), CardPrinted.FN_GET_RULES)); + + nots.add(Predicate.or(subnots)); + } + + filterNot = Predicate.not(Predicate.or(nots)); + } + + return Predicate.and(filterAnd, filterNot); + } + + /** + * Validates combo box input, assembles predicate filters for each case, + * stacks them all together, and returns the predicate. + * + * @return Predicate + */ + public static Predicate buildIntervalFilter() { + final VFilters view = VFilters.SINGLETON_INSTANCE; + Predicate filter = Predicate.getTrue(CardPrinted.class); + + // Must include -1 so non-creatures are included by default. + final int plow = view.getCbxPLow().getSelectedItem().toString().equals("*") + ? -1 : Integer.valueOf(view.getCbxPLow().getSelectedItem().toString()); + final int tlow = view.getCbxTLow().getSelectedItem().toString().equals("*") + ? -1 : Integer.valueOf(view.getCbxTLow().getSelectedItem().toString()); + final int clow = view.getCbxCMCLow().getSelectedItem().toString().equals("*") + ? -1 : Integer.valueOf(view.getCbxCMCLow().getSelectedItem().toString()); + + // If a power, toughness, or CMC is higher than 100, that's bad. + final int phigh = view.getCbxPHigh().getSelectedItem().toString().equals("10+") + ? 100 : Integer.valueOf(view.getCbxPHigh().getSelectedItem().toString()); + final int thigh = view.getCbxTHigh().getSelectedItem().toString().equals("10+") + ? 100 : Integer.valueOf(view.getCbxTHigh().getSelectedItem().toString()); + final int chigh = view.getCbxCMCHigh().getSelectedItem().toString().equals("10+") + ? 100 : Integer.valueOf(view.getCbxCMCHigh().getSelectedItem().toString()); + + // Assemble final predicates + final Predicate prePower; + final Predicate preToughness; + final Predicate preCMC; + + // Power: CardRules returns null if no power, which means extra + // filtering must be applied to allow all cards to be shown if * is chosen. + // (Without this, lands and such would be filtered out by default.) + if (plow > phigh) { prePower = Predicate.getFalse(CardPrinted.class); } + else { + // If * is selected in the combo box, cards without power + // will be included in the filter. + final Predicate preNotCreature; + if (plow == -1) { + preNotCreature = Predicate.not( + Predicate.brigde(CardRules.Predicates.Presets.IS_CREATURE, + CardPrinted.FN_GET_RULES)); + } + // Otherwise, if 0 or higher is selected, cards without power + // are excluded. + else { + preNotCreature = Predicate.getFalse(CardPrinted.class); + } + + final Predicate prePowerTemp = Predicate.and( + Predicate.brigde(CardRules.Predicates.power( + ComparableOp.GT_OR_EQUAL, plow), CardPrinted.FN_GET_RULES), + Predicate.brigde(CardRules.Predicates.power( + ComparableOp.LT_OR_EQUAL, phigh), CardPrinted.FN_GET_RULES)); + + prePower = Predicate.or(preNotCreature, prePowerTemp); + } + + // Toughness: CardRules returns null if no toughness, which means extra + // filtering must be applied to allow all cards to be shown if * is chosen. + // (Without this, lands and such would be filtered out by default.) + if (tlow > thigh) { preToughness = Predicate.getFalse(CardPrinted.class); } + else { + // If * is selected in the combo box, cards without toughness + // will be included in the filter. + final Predicate preNotCreature; + if (tlow == -1) { + preNotCreature = Predicate.not( + Predicate.brigde(CardRules.Predicates.Presets.IS_CREATURE, + CardPrinted.FN_GET_RULES)); + } + // Otherwise, if 0 or higher is selected, cards without toughness + // are excluded. + else { + preNotCreature = Predicate.getFalse(CardPrinted.class); + } + + final Predicate preToughnessTemp = Predicate.and( + Predicate.brigde(CardRules.Predicates.toughness( + ComparableOp.GT_OR_EQUAL, tlow), CardPrinted.FN_GET_RULES), + Predicate.brigde(CardRules.Predicates.toughness( + ComparableOp.LT_OR_EQUAL, thigh), CardPrinted.FN_GET_RULES)); + + preToughness = Predicate.or(preNotCreature, preToughnessTemp); + } + + // CMC, thankfully, will return -1 if the card doesn't have a CMC, + // so it can be compared directly against the low value, and non-CMC + // cards will still be included if * is chosen. + if (clow > chigh) { preCMC = Predicate.getFalse(CardPrinted.class); } + else { + preCMC = Predicate.and( + Predicate.brigde(CardRules.Predicates.cmc( + ComparableOp.GT_OR_EQUAL, clow), CardPrinted.FN_GET_RULES), + Predicate.brigde(CardRules.Predicates.cmc( + ComparableOp.LT_OR_EQUAL, chigh), CardPrinted.FN_GET_RULES)); + } + + // Stack them all together and return. + filter = Predicate.and(preCMC, Predicate.and(prePower, preToughness)); + return filter; + } + + //========== Custom class handling + + /** + * A panel with a checkbox and an icon, which will toggle the + * checkbox when anywhere in the panel is clicked. + */ + @SuppressWarnings("serial") + private static class ChbPnl extends JPanel implements ItemListener { + private final JCheckBox checkBox = new JCheckBox(); + private final Image img; + + public ChbPnl(final Image img0) { + super(); + this.img = img0; + this.setOpaque(false); + checkBox.setBorder(new EmptyBorder(0, 20, 0, 0)); + checkBox.setOpaque(false); + checkBox.setSelected(true); + checkBox.addItemListener(this); + add(checkBox); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent me) { + checkBox.doClick(); + } + }); + } + + public JCheckBox getCheckBox() { + return this.checkBox; + } + + @Override + protected void paintComponent(final Graphics g) { + super.paintComponent(g); + g.drawImage(img, 0, 0, null); + } + + /* (non-Javadoc) + * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent) + */ + @Override + public void itemStateChanged(final ItemEvent arg0) { + if (!preventFiltering) { + ((CFilters) VFilters.SINGLETON_INSTANCE.getControl()).buildFilter(); + } + } + } +} diff --git a/src/main/java/forge/gui/deckeditor/VDeckEditorUI.java b/src/main/java/forge/gui/deckeditor/VDeckEditorUI.java new file mode 100644 index 00000000000..0a75721bbd4 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/VDeckEditorUI.java @@ -0,0 +1,43 @@ +package forge.gui.deckeditor; + +import javax.swing.SwingWorker; + +import forge.gui.framework.IVTopLevelUI; +import forge.gui.framework.SLayoutIO; + +/** +/** + * Top level view class; instantiates and assembles + * tabs used in deck editor UI drag layout.
+ * + *

(V at beginning of class name denotes a view class.) + * + */ +public enum VDeckEditorUI implements IVTopLevelUI { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVTopLevelUI#instantiate() + */ + @Override + public void instantiate() { + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVTopLevelUI#populate() + */ + @Override + public void populate() { + final SwingWorker w = new SwingWorker() { + @Override + public Void doInBackground() { + SLayoutIO.loadLayout(null); + return null; + } + }; + w.execute(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java b/src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java new file mode 100644 index 00000000000..4c010d25833 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/ACEditorBase.java @@ -0,0 +1,115 @@ +/* + * 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.gui.deckeditor.controllers; + +import forge.deck.DeckBase; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.TableView; +import forge.item.InventoryItem; + +/** + * Maintains a generically typed architecture for various editing + * environments. A basic editor instance requires a card catalog, the + * current deck being edited, and optional filters on the catalog. + *

+ * These requirements are collected in this class and manipulated + * in subclasses for different environments. There are two generic + * types for all card display and filter predicates. + * + *

(A at beginning of class name denotes an abstract class.) + *

(C at beginning of class name denotes a control class.) + * + * @param extends {@link forge.item.InventoryItem} + * @param extends {@link forge.deck.DeckBase} + */ +public abstract class ACEditorBase { + + private TableView tblCatalog; + private TableView tblDeck; + /** + * Operation to add one of selected card to current deck. + */ + public abstract void addCard(); + + /** + * Operation to remove one of selected card from current deck. + */ + public abstract void removeCard(); + + /** + * Resets the cards in the catalog table and current deck table. + */ + public abstract void resetTables(); + + /** + * Gets controller responsible for the current deck being edited. + * + * @return {@link forge.gui.deckeditor.tables.DeckController} + */ + public abstract DeckController getDeckController(); + + /** + * Called when an editor wants to exit. Should confirm save options, + * update next UI screen, etc. + * + * @return boolean   true if safe to exit + */ + public abstract boolean exit(); + + /** + * Resets and initializes the current editor. + */ + public abstract void init(); + + /** + * Gets the TableView holding the cards in the current deck. + * + * @return {@link forge.gui.deckeditor.tables.TableView} + */ + public TableView getTableDeck() { + return this.tblDeck; + } + + /** + * Sets the TableView holding the cards in the current deck. + * + * @param table0   {@link forge.gui.deckeditor.tables.TableView} + */ + public void setTableDeck(final TableView table0) { + this.tblDeck = table0; + } + + /** + * Gets the TableView holding the cards in the current catalog. + * + * @return {@link forge.gui.deckeditor.tables.TableView} + */ + public TableView getTableCatalog() { + return this.tblCatalog; + } + + /** + * Sets the TableView holding the cards in the current catalog. + * + * @param table0   {@link forge.gui.deckeditor.tables.TableView} + */ + public void setTableCatalog(final TableView table0) { + this.tblCatalog = table0; + } + +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java b/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java new file mode 100644 index 00000000000..c8a9c886374 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CAllDecks.java @@ -0,0 +1,68 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.Dialog.ModalityType; + +import forge.Command; +import forge.Singletons; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.DeckImport; +import forge.gui.deckeditor.views.VAllDecks; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.InventoryItem; + +/** + * Controls the "all decks" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CAllDecks implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @SuppressWarnings("serial") + @Override + public void initialize() { + VAllDecks.SINGLETON_INSTANCE.getLstDecks().setDecks( + Singletons.getModel().getDecks().getConstructed()); + + ((FLabel) VAllDecks.SINGLETON_INSTANCE.getBtnImport()) + .setCommand(new Command() { @Override + public void execute() { importDeck(); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + /** + * Opens dialog for importing a deck from a different MTG software. + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void importDeck() { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final DeckImport dImport = new DeckImport(ed); + dImport.setModalityType(ModalityType.APPLICATION_MODAL); + dImport.setVisible(true); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java b/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java new file mode 100644 index 00000000000..ff785392165 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CCardCatalog.java @@ -0,0 +1,76 @@ +package forge.gui.deckeditor.controllers; + +import forge.Command; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.InventoryItem; + +/** + * Controls the "card catalog" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CCardCatalog implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + // refresh analysis on add + + private CCardCatalog() { + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + @SuppressWarnings("serial") + public void initialize() { + // Add/remove buttons + ((FLabel) VCardCatalog.SINGLETON_INSTANCE.getBtnAdd()).setCommand(new Command() { + @Override + public void execute() { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().addCard(); + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getTableCatalog().getTable().requestFocusInWindow(); + CStatistics.SINGLETON_INSTANCE.update(); + CProbabilities.SINGLETON_INSTANCE.update(); + } + }); + + ((FLabel) VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4()).setCommand(new Command() { + @Override + public void execute() { + final InventoryItem item = CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableCatalog().getSelectedCard(); + + for (int i = 0; i < 4; i++) { + if (item.equals(CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableCatalog().getSelectedCard())) { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().addCard(); + } + } + CStatistics.SINGLETON_INSTANCE.update(); + CProbabilities.SINGLETON_INSTANCE.update(); + } + }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java b/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java new file mode 100644 index 00000000000..dd5c1b6ced3 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CCurrentDeck.java @@ -0,0 +1,202 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.io.File; + +import javax.swing.JFileChooser; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +import forge.Command; +import forge.deck.Deck; +import forge.deck.DeckBase; +import forge.deck.io.DeckSerializer; +import forge.error.ErrorViewer; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.InventoryItem; + +/** + * Controls the "current deck" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CCurrentDeck implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + private static File previousDirectory = null; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + @SuppressWarnings("serial") + public void initialize() { + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnSave()) + .setCommand(new Command() { @Override + public void execute() { SEditorIO.saveDeck(); } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs()) + .setCommand(new Command() { @Override + public void execute() { exportDeck(); } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen()) + .setCommand(new Command() { @Override + public void execute() { openDeck(); } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnNew()) + .setCommand(new Command() { @Override + public void execute() { newDeck(); } }); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().addFocusListener(new FocusAdapter() { + @Override + public void focusGained(final FocusEvent e) { + if (((JTextField) e.getSource()).getText().equals("[New Deck]")) { + ((JTextField) e.getSource()).setText(""); + } + } + + @Override + public void focusLost(final FocusEvent e) { + if (((JTextField) e.getSource()).getText().isEmpty()) { + ((JTextField) e.getSource()).setText("[New Deck]"); + } + } + }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove()).setCommand(new Command() { + @Override public void execute() { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().removeCard(); + } }); + + ((FLabel) VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4()).setCommand(new Command() { + @Override public void execute() { + final InventoryItem item = CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableDeck().getSelectedCard(); + + for (int i = 0; i < 4; i++) { + if (item.equals(CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getTableDeck().getSelectedCard())) { + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().removeCard(); + } + } + } + }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + // + + /** */ + @SuppressWarnings("unchecked") + private void newDeck() { + if (!SEditorIO.confirmSaveChanges()) { return; } + + try { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + ((DeckController) CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckController()).newModel(); + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setText(""); + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().requestFocusInWindow(); + } + }); + } catch (final Exception ex) { + ErrorViewer.showError(ex); + throw new RuntimeException("Error creating new deck. " + ex); + } + } + + /** */ + @SuppressWarnings("unchecked") + private void openDeck() { + if (!SEditorIO.confirmSaveChanges()) { return; } + + final File file = this.getImportFilename(); + + if (file != null && file.getName().endsWith(".dck")) { + try { + ((DeckController) CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getDeckController()) + .setModel(Deck.fromFile(file)); + + } catch (final Exception ex) { + ErrorViewer.showError(ex); + throw new RuntimeException("Error importing deck." + ex); + } + } + } + + /** */ + private File getImportFilename() { + final JFileChooser open = new JFileChooser(previousDirectory); + open.setDialogTitle("Import Deck"); + open.addChoosableFileFilter(DeckSerializer.DCK_FILTER); + final int returnVal = open.showOpenDialog(null); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + final File file = open.getSelectedFile(); + previousDirectory = file.getParentFile(); + return file; + } + return null; + } + + /** */ + @SuppressWarnings("unchecked") + private void exportDeck() { + final File filename = this.getExportFilename(); + if (filename == null) { + return; + } + + try { + DeckSerializer.writeDeck( + ((DeckController) CDeckEditorUI.SINGLETON_INSTANCE + .getCurrentEditorController().getDeckController()).getModel(), filename); + } catch (final Exception ex) { + ErrorViewer.showError(ex); + throw new RuntimeException("Error exporting deck." + ex); + } + } + + private File getExportFilename() { + final JFileChooser save = new JFileChooser(previousDirectory); + save.setDialogTitle("Export Deck"); + save.setDialogType(JFileChooser.SAVE_DIALOG); + save.setFileFilter(DeckSerializer.DCK_FILTER); + + if (save.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { + final File file = save.getSelectedFile(); + final String check = file.getAbsolutePath(); + + previousDirectory = file.getParentFile(); + + return check.endsWith(".dck") ? file : new File(check + ".dck"); + } + return null; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java b/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java new file mode 100644 index 00000000000..720b5162498 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CDeckgen.java @@ -0,0 +1,120 @@ +package forge.gui.deckeditor.controllers; + +import forge.Command; +import forge.card.CardRules; +import forge.deck.Deck; +import forge.deck.DeckBase; +import forge.deck.generate.Generate2ColorDeck; +import forge.deck.generate.Generate3ColorDeck; +import forge.deck.generate.Generate5ColorDeck; +import forge.game.player.PlayerType; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.views.VDeckgen; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.util.closures.Predicate; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CDeckgen implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @SuppressWarnings("serial") + @Override + public void initialize() { + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandCardpool()).setCommand(new Command() { + @Override + public void execute() { + newRandomConstructed(); + } + }); + + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck2()).setCommand(new Command() { + @Override public void execute() { newGenerateConstructed(2); } }); + + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck3()).setCommand(new Command() { + @Override public void execute() { newGenerateConstructed(3); } }); + + ((FLabel) VDeckgen.SINGLETON_INSTANCE.getBtnRandDeck5()).setCommand(new Command() { + @Override public void execute() { newGenerateConstructed(5); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + //========== Other methods + @SuppressWarnings("unchecked") + private void newRandomConstructed() { + if (!SEditorIO.confirmSaveChanges()) { return; } + + final Deck randomDeck = new Deck(); + + randomDeck.getMain().addAllFlat(Predicate.not(CardRules.Predicates.Presets.IS_BASIC_LAND) + .random(CardDb.instance().getAllUniqueCards(), CardPrinted.FN_GET_RULES, 15 * 5)); + randomDeck.getMain().add("Plains"); + randomDeck.getMain().add("Island"); + randomDeck.getMain().add("Swamp"); + randomDeck.getMain().add("Mountain"); + randomDeck.getMain().add("Forest"); + randomDeck.getMain().add("Terramorphic Expanse"); + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + ed.getDeckController().setModel((TModel) randomDeck); + } + + @SuppressWarnings("unchecked") + private void newGenerateConstructed(final int colorCount0) { + if (!SEditorIO.confirmSaveChanges()) { return; } + + final Deck genConstructed = new Deck(); + + switch (colorCount0) { + case 2: + genConstructed.getMain().addAll( + (new Generate2ColorDeck("AI", "AI")).get2ColorDeck(60, PlayerType.HUMAN)); + break; + case 3: + genConstructed.getMain().addAll( + (new Generate3ColorDeck("AI", "AI", "AI")).get3ColorDeck(60, PlayerType.HUMAN)); + break; + case 5: + genConstructed.getMain().addAll( + (new Generate5ColorDeck()).get5ColorDeck(60, PlayerType.HUMAN)); + break; + default: + } + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + ed.getDeckController().setModel((TModel) genConstructed); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java new file mode 100644 index 00000000000..2a58193b017 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorConstructed.java @@ -0,0 +1,158 @@ +/* + * 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.gui.deckeditor.controllers; + +import java.util.List; + +import forge.Singletons; +import forge.deck.Deck; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.util.closures.Lambda0; + +/** + * Child controller for constructed deck editor UI. + * This is the least restrictive mode; + * all cards are available. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id$ + */ +public final class CEditorConstructed extends ACEditorBase { + private final DeckController controller; + + //=========== Constructor + /** + * Child controller for constructed deck editor UI. + * This is the least restrictive mode; + * all cards are available. + */ + public CEditorConstructed() { + super(); + + final TableView tblCatalog = new TableView(true, CardPrinted.class); + final TableView tblDeck = new TableView(true, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + + final Lambda0 newCreator = new Lambda0() { + @Override + public Deck apply() { + return new Deck(); + } + }; + this.controller = new DeckController(Singletons.getModel().getDecks().getConstructed(), this, newCreator); + } + + //=========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().addCard(card); + this.controller.notifyModelChanged(); + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("*Current Deck"); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().removeCard(card); + this.controller.notifyModelChanged(); + VCurrentDeck.SINGLETON_INSTANCE.getTabLabel().setText("*Current Deck"); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + // Constructed mode can use all cards, no limitations. + this.getTableCatalog().setDeck(ItemPool.createFrom(CardDb.instance().getAllCards(), CardPrinted.class)); + this.getTableDeck().setDeck(this.controller.getModel().getMain()); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return this.controller; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + final List> lstCatalogCols = SColumnUtil.getCatalogDefaultColumns(); + lstCatalogCols.remove(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); + + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, lstCatalogCols); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, SColumnUtil.getDeckDefaultColumns()); + + SEditorUtil.resetUI(); + + this.controller.newModel(); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + return SEditorIO.confirmSaveChanges(); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java new file mode 100644 index 00000000000..80461fd50ec --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorDraftingProcess.java @@ -0,0 +1,249 @@ +/* + * 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.gui.deckeditor.controllers; + +import javax.swing.JOptionPane; + +import forge.Constant; +import forge.Singletons; +import forge.control.FControl; +import forge.deck.Deck; +import forge.deck.DeckGroup; +import forge.game.limited.BoosterDraft; +import forge.game.limited.IBoosterDraft; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.sanctioned.CSubmenuDraft; +import forge.item.CardDb; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPoolView; + +/** + * Updates the deck editor UI as necessary draft selection mode. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id$ + */ +public class CEditorDraftingProcess extends ACEditorBase { + private IBoosterDraft boosterDraft; + + //========== Constructor + + /** + * Updates the deck editor UI as necessary draft selection mode. + */ + public CEditorDraftingProcess() { + final TableView tblCatalog = new TableView(true, CardPrinted.class); + final TableView tblDeck = new TableView(true, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + } + + /** + * Show gui. + * + * @param inBoosterDraft + * the in_booster draft + */ + public final void showGui(final IBoosterDraft inBoosterDraft) { + this.boosterDraft = inBoosterDraft; + this.init(); + } + + /** + *

+ * setup. + *

+ */ + private void setup() { + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, SColumnUtil.getCatalogDefaultColumns()); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, SColumnUtil.getDeckDefaultColumns()); + + /* + this.getTableCatalog().getTable().addMouseListener(this.pickWithMouse); + this.getTableCatalog().getTable().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(final KeyEvent e) { + if (e.getKeyChar() == ' ') { + CEditorDraftingProcess.this.addCard(); + } + } + }); + */ + + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + + this.getTableDeck().addCard(card); + + // get next booster pack + this.boosterDraft.setChoice(card); + + if (this.boosterDraft.hasNextChoice()) { + this.showChoices(this.boosterDraft.nextChoice()); + } else { + this.boosterDraft.finishedDrafting(); + this.saveDraft(); + } + } + + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + } + + /** + *

+ * showChoices. + *

+ * + * @param list + * a {@link forge.CardList} object. + */ + private void showChoices(final ItemPoolView list) { + VCardCatalog.SINGLETON_INSTANCE.getLblTitle().setText("Select a card from pack number " + + (((BoosterDraft) boosterDraft).getCurrentBoosterIndex() + 1) + "."); + this.getTableCatalog().setDeck(list); + this.getTableCatalog().fixSelection(0); + } // showChoices() + + /** + *

+ * getPlayersDeck. + *

+ * + * @return a {@link forge.deck.Deck} object. + */ + private Deck getPlayersDeck() { + final Deck deck = new Deck(); + Constant.Runtime.HUMAN_DECK[0] = deck; + + // add sideboard to deck + deck.getSideboard().addAll(this.getTableDeck().getCards()); + + final String landSet = IBoosterDraft.LAND_SET_CODE[0]; + final int landsCount = 20; + deck.getSideboard().add(CardDb.instance().getCard("Forest", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Mountain", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Swamp", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Island", landSet), landsCount); + deck.getSideboard().add(CardDb.instance().getCard("Plains", landSet), landsCount); + + return deck; + } // getPlayersDeck() + + /** + *

+ * saveDraft. + *

+ */ + private void saveDraft() { + String s = ""; + while ((s == null) || (s.length() == 0)) { + s = JOptionPane.showInputDialog(null, + "Save this draft as:", + "Save draft", + JOptionPane.QUESTION_MESSAGE); + } + // TODO: check if overwriting the same name, and let the user delete old + // drafts + + // construct computer's decks + // save draft + final Deck[] computer = this.boosterDraft.getDecks(); + + final DeckGroup finishedDraft = new DeckGroup(s); + finishedDraft.setHumanDeck((Deck) this.getPlayersDeck().copyTo(s)); + finishedDraft.addAiDecks(computer); + + // DeckManager deckManager = new + // DeckManager(ForgeProps.getFile(NEW_DECKS)); + + // write the file + Singletons.getModel().getDecks().getDraft().add(finishedDraft); + + CSubmenuDraft.SINGLETON_INSTANCE.update(); + FControl.SINGLETON_INSTANCE.changeState(FControl.HOME_SCREEN); + } + + //========== Overridden from ACEditorBase + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return null; + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + this.setup(); + this.showChoices(this.boosterDraft.nextChoice()); + this.getTableDeck().setDeck((Iterable) null); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + CSubmenuDraft.SINGLETON_INSTANCE.update(); + return true; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java new file mode 100644 index 00000000000..364fc2cd17e --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorLimited.java @@ -0,0 +1,183 @@ +/* + * 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.gui.deckeditor.controllers; + +import forge.deck.Deck; +import forge.deck.DeckGroup; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.sanctioned.CSubmenuDraft; +import forge.gui.home.sanctioned.CSubmenuSealed; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.util.IStorage; +import forge.util.closures.Lambda0; + +/** + * Child controller for limited deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id: DeckEditorCommon.java 12850 2011-12-26 14:55:09Z slapshot5 $ + */ +public final class CEditorLimited extends ACEditorBase { + + private final DeckController controller; + + //========== Constructor + + /** + * Child controller for limited deck editor UI. + * + * @param deckMap0   {@link forge.deck.DeckGroup}<{@link forge.util.IStorage}> + */ + public CEditorLimited(final IStorage deckMap0) { + final TableView tblCatalog = new TableView(true, CardPrinted.class); + final TableView tblDeck = new TableView(true, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + + final Lambda0 newCreator = new Lambda0() { + @Override + public DeckGroup apply() { + return new DeckGroup(""); + } + }; + this.controller = new DeckController(deckMap0, this, newCreator); + } + + /** + * TODO: Write javadoc for this method. + * + * @param model + * @return + */ + private Deck getSelectedDeck(final DeckGroup model) { + return model.getHumanDeck(); + } + + //========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + // update view + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().addCard(card); + this.getTableCatalog().removeCard(card); + + this.getDeckController().notifyModelChanged(); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + // update view + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().removeCard(card); + this.getTableCatalog().addCard(card); + + Deck model = getSelectedDeck(getDeckController().getModel()); + model.getMain().remove(card); model.getSideboard().add(card); + + this.getDeckController().notifyModelChanged(); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + final Deck toEdit = this.getSelectedDeck(this.controller.getModel()); + this.getTableCatalog().setDeck(toEdit.getSideboard()); + this.getTableDeck().setDeck(toEdit.getMain()); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return this.controller; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, SColumnUtil.getCatalogDefaultColumns()); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, SColumnUtil.getDeckDefaultColumns()); + + SEditorUtil.resetUI(); + + VCardCatalog.SINGLETON_INSTANCE.getBtnAdd4().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getBtnRemove4().setVisible(false); + + VCurrentDeck.SINGLETON_INSTANCE.getBtnSaveAs().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getBtnNew().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getBtnOpen().setVisible(false); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setEnabled(false); + + VCardCatalog.SINGLETON_INSTANCE.getLblTitle().setText("Deck Editor: Limited Mode"); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + final boolean okToExit = SEditorIO.confirmSaveChanges(); + + if (okToExit) { + CSubmenuDraft.SINGLETON_INSTANCE.update(); + CSubmenuSealed.SINGLETON_INSTANCE.update(); + } + + return okToExit; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java new file mode 100644 index 00000000000..232d01703d1 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorPreferences.java @@ -0,0 +1,151 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.JCheckBox; + +import forge.Command; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorIO.EditorPreference; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.deckeditor.views.VEditorPreferences; +import forge.gui.framework.ICDoc; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CEditorPreferences implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + public void initialize() { + SEditorIO.loadPreferences(); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogColor().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_COLOR).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogRarity().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_RARITY).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogCMC().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_CMC).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogSet().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_SET).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogAI().setSelected( + SColumnUtil.getColumn(ColumnName.CAT_AI).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckColor().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_COLOR).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckRarity().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_RARITY).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckCMC().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_CMC).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckSet().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_SET).isShowing()); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckAI().setSelected( + SColumnUtil.getColumn(ColumnName.DECK_AI).isShowing()); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogStats().setSelected( + SEditorIO.getPref(EditorPreference.stats_catalog)); + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().setSelected( + SEditorIO.getPref(EditorPreference.stats_deck)); + + if (!SEditorIO.getPref(EditorPreference.stats_deck)) { + VCurrentDeck.SINGLETON_INSTANCE.getPnlStats().setVisible(false); + } + if (!SEditorIO.getPref(EditorPreference.stats_catalog)) { + VCardCatalog.SINGLETON_INSTANCE.getPnlStats().setVisible(false); + } + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogColor().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_COLOR)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogRarity().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_RARITY)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogCMC().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_CMC)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogSet().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_SET)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogAI().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.CAT_AI)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckColor().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_COLOR)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckRarity().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_RARITY)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckCMC().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_CMC)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckSet().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_SET)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckAI().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + SColumnUtil.toggleColumn(SColumnUtil.getColumn(ColumnName.DECK_AI)); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbCatalogStats().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + VCardCatalog.SINGLETON_INSTANCE.getPnlStats().setVisible( + ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.setPref(EditorPreference.stats_catalog, ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.savePreferences(); } }); + + VEditorPreferences.SINGLETON_INSTANCE.getChbDeckStats().addItemListener(new ItemListener() { + @Override public void itemStateChanged(final ItemEvent e) { + VCurrentDeck.SINGLETON_INSTANCE.getPnlStats().setVisible( + ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.setPref(EditorPreference.stats_deck, ((JCheckBox) e.getSource()).isSelected()); + SEditorIO.savePreferences(); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + //========== Other methods +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java new file mode 100644 index 00000000000..2210e6ccc5e --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuest.java @@ -0,0 +1,204 @@ +/* + * 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.gui.deckeditor.controllers; + +// import java.awt.Font; +import java.util.List; + +import forge.AllZone; +import forge.Constant; +import forge.deck.Deck; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.quest.CSubmenuQuestDecks; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.quest.QuestController; +import forge.util.closures.Lambda0; + +//import forge.quest.data.QuestBoosterPack; + +/** + * Child controller for quest deck editor UI. + *

+ * Card catalog and decks are drawn from a QuestController object. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id$ + */ +public final class CEditorQuest extends ACEditorBase { + private final QuestController questData; + private final DeckController controller; + + /** + * Child controller for quest deck editor UI. + *

+ * Card catalog and decks are drawn from a QuestController object. + * + * @param questData0   {@link forge.quest.QuestController} + */ + public CEditorQuest(final QuestController questData0) { + this.questData = questData0; + + final TableView tblCatalog = new TableView(false, CardPrinted.class); + final TableView tblDeck = new TableView(false, CardPrinted.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + + final Lambda0 newCreator = new Lambda0() { + @Override + public Deck apply() { + return new Deck(); + } + }; + this.controller = new DeckController(questData0.getMyDecks(), this, newCreator); + } + + /** + * Adds any card to the catalog and data pool. + * + * @param card {@link forge.item.CardPrinted} + */ + public void addCheatCard(final CardPrinted card) { + this.getTableCatalog().addCard(card); + this.questData.getCards().getCardpool().add(card); + } + + //=========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableCatalog().removeCard(card); + this.getTableDeck().addCard(card); + this.controller.notifyModelChanged(); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableCatalog().addCard(card); + this.getTableDeck().removeCard(card); + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#updateView() + */ + @Override + public void resetTables() { + final Deck deck = this.controller.getModel(); + + final ItemPool cardpool = new ItemPool(CardPrinted.class); + cardpool.addAll(this.questData.getCards().getCardpool()); + // remove bottom cards that are in the deck from the card pool + cardpool.removeAll(deck.getMain()); + // show cards, makes this user friendly + this.getTableCatalog().setDeck(cardpool); + this.getTableDeck().setDeck(deck.getMain()); + } + + //=========== Overridden from ACEditorBase + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return this.controller; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + final List> columnsCatalog = SColumnUtil.getCatalogDefaultColumns(); + final List> columnsDeck = SColumnUtil.getDeckDefaultColumns(); + + // Add "new" column in catalog and deck + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_NEW)); + + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), + this.questData.getCards().getFnNewGet()); + + columnsDeck.add(SColumnUtil.getColumn(ColumnName.DECK_NEW)); + + columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), + this.questData.getCards().getFnNewGet()); + + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, columnsCatalog); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, columnsDeck); + + Deck deck = Constant.Runtime.HUMAN_DECK[0] == null ? null : this.questData.getMyDecks().get( + Constant.Runtime.HUMAN_DECK[0].getName()); + + if (deck == null) { + deck = new Deck(); + } + + this.getDeckController().setModel(deck); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + final boolean okToExit = SEditorIO.confirmSaveChanges(); + if (okToExit) { + AllZone.getQuest().save(); + CSubmenuQuestDecks.SINGLETON_INSTANCE.update(); + } + return okToExit; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java new file mode 100644 index 00000000000..6b2496a7116 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CEditorQuestCardShop.java @@ -0,0 +1,368 @@ +/* + * 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.gui.deckeditor.controllers; + +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.swing.JLabel; +import javax.swing.JOptionPane; + +import forge.AllZone; +import forge.deck.Deck; +import forge.deck.DeckBase; +import forge.gui.CardListViewer; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.tables.DeckController; +import forge.gui.deckeditor.tables.SColumnUtil; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.TableColumnInfo; +import forge.gui.deckeditor.tables.TableView; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.home.quest.CSubmenuQuestDecks; +import forge.gui.home.quest.SSubmenuQuestUtil; +import forge.item.BoosterPack; +import forge.item.CardPrinted; +import forge.item.FatPack; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; +import forge.item.OpenablePack; +import forge.item.PreconDeck; +import forge.item.TournamentPack; +import forge.quest.QuestController; +import forge.quest.io.ReadPriceList; +import forge.util.closures.Lambda1; + +/** + * Child controller for quest card shop UI. + * + *

(C at beginning of class name denotes a control class.) + * + * @author Forge + * @version $Id: CEditorQuestCardShop.java 15088 2012-04-07 11:34:05Z Max mtg $ + */ +public final class CEditorQuestCardShop extends ACEditorBase { + private final JLabel creditsLabel = new JLabel(); + private final JLabel sellPercentageLabel = new JLabel(); + private double multiplier; + private final QuestController questData; + + // get pricelist: + private final ReadPriceList r = new ReadPriceList(); + private final Map mapPrices = this.r.getPriceList(); + private Map decksUsingMyCards; + + /** + * Child controller for quest card shop UI. + * + * @param qd + * a {@link forge.quest.data.QuestData} object. + */ + public CEditorQuestCardShop(final QuestController qd) { + this.questData = qd; + + final TableView tblCatalog = new TableView(false, InventoryItem.class); + final TableView tblDeck = new TableView(false, InventoryItem.class); + + VCardCatalog.SINGLETON_INSTANCE.setTableView(tblCatalog.getTable()); + VCurrentDeck.SINGLETON_INSTANCE.setTableView(tblDeck.getTable()); + + this.setTableCatalog(tblCatalog); + this.setTableDeck(tblDeck); + } + + /** + *

+ * setup. + *

+ */ + private void setup() { + final List> columnsCatalog = SColumnUtil.getCatalogDefaultColumns(); + final List> columnsDeck = SColumnUtil.getDeckDefaultColumns(); + + // Add "price", "decks", and "new" column in catalog and deck + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_PURCHASE_PRICE)); + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.fnPriceCompare, this.fnPriceGet); + + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_DECKS)); + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.fnDeckCompare, this.fnDeckGet); + + columnsCatalog.add(SColumnUtil.getColumn(ColumnName.CAT_NEW)); + columnsCatalog.get(columnsCatalog.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), this.questData.getCards().getFnNewGet()); + + columnsDeck.add(SColumnUtil.getColumn(ColumnName.DECK_SALE_PRICE)); + columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions( + this.fnPriceCompare, this.fnPriceSellGet); + + columnsDeck.add(SColumnUtil.getColumn(ColumnName.DECK_NEW)); + columnsDeck.get(columnsDeck.size() - 1).setSortAndDisplayFunctions( + this.questData.getCards().getFnNewCompare(), this.questData.getCards().getFnNewGet()); + + // Setup with current column set + this.getTableCatalog().setup(VCardCatalog.SINGLETON_INSTANCE, columnsCatalog); + this.getTableDeck().setup(VCurrentDeck.SINGLETON_INSTANCE, columnsDeck); + + SEditorUtil.resetUI(); + VCardCatalog.SINGLETON_INSTANCE.getPnlHeader().setVisible(false); + VCurrentDeck.SINGLETON_INSTANCE.getPnlHeader().setVisible(false); + } + + // fills number of decks using each card + private Map countDecksForEachCard() { + final Map result = new HashMap(); + for (final Deck deck : this.questData.getMyDecks()) { + for (final Entry e : deck.getMain()) { + final CardPrinted card = e.getKey(); + final Integer amount = result.get(card); + result.put(card, Integer.valueOf(amount == null ? 1 : 1 + amount.intValue())); + } + } + return result; + } + + private Integer getCardValue(final InventoryItem card) { + if (this.mapPrices.containsKey(card.getName())) { + return this.mapPrices.get(card.getName()); + } else if (card instanceof CardPrinted) { + switch (((CardPrinted) card).getRarity()) { + case BasicLand: + return Integer.valueOf(4); + case Common: + return Integer.valueOf(6); + case Uncommon: + return Integer.valueOf(40); + case Rare: + return Integer.valueOf(120); + case MythicRare: + return Integer.valueOf(600); + default: + return Integer.valueOf(15); + } + } else if (card instanceof BoosterPack) { + return 395; + } else if (card instanceof TournamentPack) { + return 995; + } else if (card instanceof FatPack) { + return 2365; + } else if (card instanceof PreconDeck) { + return ((PreconDeck) card).getRecommendedDeals().getCost(); + } + return 1337; + } + + @SuppressWarnings("rawtypes") + private final Lambda1> fnPriceCompare = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return CEditorQuestCardShop.this.getCardValue(from.getKey()); + } + }; + private final Lambda1> fnPriceGet = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return CEditorQuestCardShop.this.getCardValue(from.getKey()); + } + }; + private final Lambda1> fnPriceSellGet = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return (int) (CEditorQuestCardShop.this.multiplier * CEditorQuestCardShop.this.getCardValue(from.getKey())); + } + }; + + @SuppressWarnings("rawtypes") + private final Lambda1> fnDeckCompare = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + final Integer iValue = CEditorQuestCardShop.this.decksUsingMyCards.get(from.getKey()); + return iValue == null ? Integer.valueOf(0) : iValue; + } + }; + private final Lambda1> fnDeckGet = new Lambda1>() { + @Override + public Object apply(final Entry from) { + final Integer iValue = CEditorQuestCardShop.this.decksUsingMyCards.get(from.getKey()); + return iValue == null ? "" : iValue.toString(); + } + }; + + //=========== Overridden from ACEditorBase + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#addCard() + */ + @Override + public void addCard() { + final InventoryItem item = this.getTableCatalog().getSelectedCard(); + if (item == null) { + return; + } + + final int value = this.getCardValue(item); + + if (value <= this.questData.getAssets().getCredits()) { + + if (item instanceof CardPrinted) { + this.getTableCatalog().removeCard(item); + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().addCard(card); + this.questData.getCards().buyCard(card, value); + + } else if (item instanceof OpenablePack) { + this.getTableCatalog().removeCard(item); + + OpenablePack booster = null; + if (item instanceof BoosterPack) { + booster = (BoosterPack) ((BoosterPack) item).clone(); + } else if (item instanceof TournamentPack) { + booster = (TournamentPack) ((TournamentPack) item).clone(); + } else if (item instanceof FatPack) { + booster = (FatPack) ((FatPack) item).clone(); + } + this.questData.getCards().buyPack(booster, value); + final List newCards = booster.getCards(); + for (final CardPrinted card : newCards) { + this.getTableDeck().addCard(card); + } + final CardListViewer c = new CardListViewer(booster.getName(), + "You have found the following cards inside:", newCards); + c.show(); + } else if (item instanceof PreconDeck) { + this.getTableCatalog().removeCard(item); + final PreconDeck deck = (PreconDeck) item; + this.questData.getCards().buyPreconDeck(deck, value); + + for (final CardPrinted card : deck.getDeck().getMain().toFlatList()) { + this.getTableDeck().addCard(card); + } + JOptionPane.showMessageDialog(null, String.format( + "Deck '%s' was added to your decklist.%n%nCards from it were also added to your pool.", + deck.getName()), "Thanks for purchasing!", JOptionPane.INFORMATION_MESSAGE); + + } + + this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); + } else { + JOptionPane.showMessageDialog(null, "Not enough credits!"); + } + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#removeCard() + */ + @Override + public void removeCard() { + final InventoryItem item = this.getTableDeck().getSelectedCard(); + if ((item == null) || !(item instanceof CardPrinted)) { + return; + } + + final CardPrinted card = (CardPrinted) item; + this.getTableDeck().removeCard(card); + this.getTableCatalog().addCard(card); + + final int price = Math.min((int) (this.multiplier * this.getCardValue(card)), this.questData.getCards() + .getSellPriceLimit()); + this.questData.getCards().sellCard(card, price); + + this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); + } + + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#resetTables() + */ + @Override + public void resetTables() { + } + + /* + * (non-Javadoc) + * + * @see forge.gui.deckeditor.ACEditorBase#getController() + */ + @Override + public DeckController getDeckController() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.ACEditorBase#show(forge.Command) + */ + @Override + public void init() { + this.setup(); + + this.decksUsingMyCards = this.countDecksForEachCard(); + + this.multiplier = this.questData.getCards().getSellMultiplier(); + + ItemPoolView forSale = this.questData.getCards().getShopList(); + if (forSale.isEmpty()) { + this.questData.getCards().generateCardsInShop(); + forSale = this.questData.getCards().getShopList(); + } + + // newCardsList = questData.getCards().getNewCards(); + final ItemPool ownedItems = new ItemPool(InventoryItem.class); + ownedItems.addAll(this.questData.getCards().getCardpool().getView()); + + this.getTableCatalog().setDeck(forSale); + this.getTableDeck().setDeck(ownedItems); + + this.creditsLabel.setText("Credits: " + this.questData.getAssets().getCredits()); + + final double multiPercent = this.multiplier * 100; + final NumberFormat formatter = new DecimalFormat("#0.00"); + String maxSellingPrice = ""; + final int maxSellPrice = this.questData.getCards().getSellPriceLimit(); + + if (maxSellPrice < Integer.MAX_VALUE) { + maxSellingPrice = String.format("Maximum selling price is %d credits.", maxSellPrice); + } + this.sellPercentageLabel.setText("Selling cards at " + formatter.format(multiPercent) + + "% of their value.
" + maxSellingPrice + ""); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.controllers.ACEditorBase#exit() + */ + @Override + public boolean exit() { + final boolean okToExit = SEditorIO.confirmSaveChanges(); + if (okToExit) { + SSubmenuQuestUtil.updateStatsAndPet(); + AllZone.getQuest().save(); + CSubmenuQuestDecks.SINGLETON_INSTANCE.update(); + } + return okToExit; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CFilters.java b/src/main/java/forge/gui/deckeditor/controllers/CFilters.java new file mode 100644 index 00000000000..4e26a9ca0e2 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CFilters.java @@ -0,0 +1,176 @@ +package forge.gui.deckeditor.controllers; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.List; + +import forge.Command; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SFilterUtil; +import forge.gui.deckeditor.views.VFilters; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.util.closures.Predicate; + +/** + * Controls the "filters" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CFilters implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + private boolean filtersAllEnabled = true; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @SuppressWarnings("serial") + @Override + public void initialize() { + final ItemListener iliFilter = new ItemListener() { + @Override + public void itemStateChanged(final ItemEvent arg0) { + if (!SFilterUtil.isFilteringPrevented()) { + buildFilter(); + } + } + }; + + VFilters.SINGLETON_INSTANCE.getCbxSets().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxPLow().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxPHigh().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxTLow().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxTHigh().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxCMCLow().addItemListener(iliFilter); + VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().addItemListener(iliFilter); + + ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnToggle()).setCommand(new Command() { + @Override + public void execute() { + SFilterUtil.setPreventFiltering(true); + toggleColorTypeSetFilter(); + SFilterUtil.setPreventFiltering(false); + buildFilter(); + } + }); + + ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnResetIntervals()).setCommand(new Command() { + @Override + public void execute() { + SFilterUtil.setPreventFiltering(true); + VFilters.SINGLETON_INSTANCE.getCbxPLow().setSelectedIndex(0); + VFilters.SINGLETON_INSTANCE.getCbxTLow().setSelectedIndex(0); + VFilters.SINGLETON_INSTANCE.getCbxCMCLow().setSelectedIndex(0); + + VFilters.SINGLETON_INSTANCE.getCbxPHigh().setSelectedIndex( + VFilters.SINGLETON_INSTANCE.getCbxPHigh().getItemCount() - 1); + VFilters.SINGLETON_INSTANCE.getCbxTHigh().setSelectedIndex( + VFilters.SINGLETON_INSTANCE.getCbxTHigh().getItemCount() - 1); + VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().setSelectedIndex( + VFilters.SINGLETON_INSTANCE.getCbxCMCHigh().getItemCount() - 1); + + SFilterUtil.setPreventFiltering(false); + buildFilter(); + } + }); + + ((FLabel) VFilters.SINGLETON_INSTANCE.getBtnResetText()).setCommand(new Command() { + @Override + public void execute() { + VFilters.SINGLETON_INSTANCE.getTxfContains().setText(""); + VFilters.SINGLETON_INSTANCE.getTxfWithout().setText(""); + buildFilter(); + } + }); + + VFilters.SINGLETON_INSTANCE.getTxfContains().addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(final KeyEvent e) { + if (e.getKeyCode() == 10) { buildFilter(); } + } + }); + + VFilters.SINGLETON_INSTANCE.getTxfWithout().addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(final KeyEvent e) { + if (e.getKeyCode() == 10) { buildFilter(); } + } + }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + } + + /** + * Clear filter button_action performed. + * + * @param e + * the e + */ + private void toggleColorTypeSetFilter() { + VFilters.SINGLETON_INSTANCE.getCbxSets().setSelectedIndex(0); + + if (filtersAllEnabled) { + filtersAllEnabled = false; + SFilterUtil.toggleColorCheckboxes(false); + SFilterUtil.toggleTypeCheckboxes(false); + } + else { + filtersAllEnabled = true; + SFilterUtil.toggleColorCheckboxes(true); + SFilterUtil.toggleTypeCheckboxes(true); + } + } + + //=========== + + /** + * + * Assembles filter from the ones available. To prevent a block + * of filters from being used, set its parent panel's visibility to false. + * + * @param   extends InventoryItem + * @param   extends DeckBase + */ + @SuppressWarnings("unchecked") + public void buildFilter() { + // The main trick here is to apply a CardPrinted predicate + // to the table. CardRules will lead to difficulties. + final List> lstFilters = new ArrayList>(); + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + lstFilters.add(SFilterUtil.buildColorFilter()); + lstFilters.add(SFilterUtil.buildTypeFilter()); + lstFilters.add(SFilterUtil.buildSetAndFormatFilter()); + lstFilters.add(SFilterUtil.buildTextFilter()); + lstFilters.add(SFilterUtil.buildIntervalFilter()); + + // Apply to table + ed.getTableCatalog().setFilter((Predicate) Predicate.and(lstFilters)); + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java b/src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java new file mode 100644 index 00000000000..63241562caa --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CProbabilities.java @@ -0,0 +1,100 @@ +package forge.gui.deckeditor.controllers; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import forge.Command; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.views.VProbabilities; +import forge.gui.framework.ICDoc; +import forge.gui.toolbox.FLabel; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; +import forge.util.MyRandom; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CProbabilities implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + @SuppressWarnings("serial") + public void initialize() { + ((FLabel) VProbabilities.SINGLETON_INSTANCE.getLblReshuffle()).setCommand( + new Command() { @Override public void execute() { update(); } }); + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + VProbabilities.SINGLETON_INSTANCE.rebuildLabels(analyze()); + } + + //========== Other methods + @SuppressWarnings("unchecked") + private List analyze() { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final ItemPoolView deck = ItemPool.createFrom( + ed.getTableDeck().getCards(), CardPrinted.class); + + final List cardProbabilities = new ArrayList(); + + final List shuffled = deck.toFlatList(); + Collections.shuffle(shuffled, MyRandom.getRandom()); + + // Log totals of each card for decrementing + final Map cardTotals = new HashMap(); + for (final CardPrinted c : shuffled) { + if (cardTotals.containsKey(c)) { cardTotals.put(c, cardTotals.get(c) + 1); } + else { cardTotals.put(c, 1); } + } + + // Run through shuffled deck and calculate probabilities. + // Formulas is (remaining instances of this card / total cards remaining) + final Iterator itr = shuffled.iterator(); + CardPrinted tmp; + int prob; + while (itr.hasNext()) { + tmp = itr.next(); + + prob = SEditorUtil.calculatePercentage( + cardTotals.get(tmp), shuffled.size()); + + cardTotals.put(tmp, cardTotals.get(tmp) - 1); + cardProbabilities.add(tmp.getName() + " (" + prob + "%)"); + itr.remove(); + } + + return cardProbabilities; + } +} diff --git a/src/main/java/forge/gui/deckeditor/controllers/CStatistics.java b/src/main/java/forge/gui/deckeditor/controllers/CStatistics.java new file mode 100644 index 00000000000..71e26e70f9f --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/controllers/CStatistics.java @@ -0,0 +1,191 @@ +package forge.gui.deckeditor.controllers; + +import java.util.Map.Entry; + +import forge.Command; +import forge.card.CardColor; +import forge.card.CardRules; +import forge.card.CardRules.Predicates; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.views.VStatistics; +import forge.gui.framework.ICDoc; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; +import forge.util.closures.Predicate; + +/** + * Controls the "analysis" panel in the deck editor UI. + * + *

(C at beginning of class name denotes a control class.) + * + */ +public enum CStatistics implements ICDoc { + /** */ + SINGLETON_INSTANCE; + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#getCommandOnSelect() + */ + @Override + public Command getCommandOnSelect() { + return null; + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#initialize() + */ + @Override + public void initialize() { + } + + /* (non-Javadoc) + * @see forge.gui.framework.ICDoc#update() + */ + @Override + public void update() { + analyze(); + } + + //========== Other methods + @SuppressWarnings("unchecked") + private void analyze() { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + if (ed == null) { return; } + + final ItemPoolView deck = ItemPool.createFrom( + ed.getTableDeck().getCards(), CardPrinted.class); + + int tmp = 0; + int total = deck.countAll(); + + // Hack-ish: avoid /0 cases, but still populate labels :) + if (total == 0) { total = 1; } + + tmp = CardRules.Predicates.Presets.IS_MULTICOLOR + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblMulti().setText(String.valueOf(tmp)); + + tmp = CardRules.Predicates.Presets.IS_CREATURE + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblCreature().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_LAND + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblLand().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_ENCHANTMENT + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblEnchantment().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_ARTIFACT + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblArtifact().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_INSTANT + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblInstant().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_SORCERY + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblSorcery().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_PLANESWALKER + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblPlaneswalker().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = CardRules.Predicates.Presets.IS_COLORLESS + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblColorless().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.BLACK), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblBlack().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.BLUE), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblBlue().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.GREEN), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblGreen().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.RED), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblRed().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + tmp = Predicate.and( + Predicates.isColor(CardColor.WHITE), + Predicates.hasCntColors((byte) 1)) + .aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); + VStatistics.SINGLETON_INSTANCE.getLblWhite().setText( + tmp + " (" + SEditorUtil.calculatePercentage(tmp, total) + "%)"); + + int cmc0 = 0, cmc1 = 0, cmc2 = 0, cmc3 = 0, cmc4 = 0, cmc5 = 0, cmc6 = 0; + int tmc = 0; + + for (final Entry e : deck) { + final CardRules cardRules = e.getKey().getCard(); + final int count = e.getValue(); + final int cmc = cardRules.getManaCost().getCMC(); + + if (cmc == 0) { cmc0 += count; } + else if (cmc == 1) { cmc1 += count; } + else if (cmc == 2) { cmc2 += count; } + else if (cmc == 3) { cmc3 += count; } + else if (cmc == 4) { cmc4 += count; } + else if (cmc == 5) { cmc5 += count; } + else if (cmc >= 6) { cmc6 += count; } + + tmc += (cmc * count); + } + + VStatistics.SINGLETON_INSTANCE.getLblCMC0().setText( + cmc0 + " (" + SEditorUtil.calculatePercentage(cmc0, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC1().setText( + cmc1 + " (" + SEditorUtil.calculatePercentage(cmc1, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC2().setText( + cmc2 + " (" + SEditorUtil.calculatePercentage(cmc2, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC3().setText( + cmc3 + " (" + SEditorUtil.calculatePercentage(cmc3, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC4().setText( + cmc4 + " (" + SEditorUtil.calculatePercentage(cmc4, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC5().setText( + cmc5 + " (" + SEditorUtil.calculatePercentage(cmc5, total) + "%)"); + VStatistics.SINGLETON_INSTANCE.getLblCMC6().setText( + cmc6 + " (" + SEditorUtil.calculatePercentage(cmc6, total) + "%)"); + + double amc = (double) Math.round((double) tmc / (double) total * 100) / 100.0d; + + VStatistics.SINGLETON_INSTANCE.getLblTotal().setText("TOTAL CARDS: " + deck.countAll()); + VStatistics.SINGLETON_INSTANCE.getLblTMC().setText("TOTAL MANA COST: " + tmc); + VStatistics.SINGLETON_INSTANCE.getLblAMC().setText("AVERAGE MANA COST: " + amc); + } +} diff --git a/src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java b/src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java deleted file mode 100644 index 046831f4a48..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CardPanelBase.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import javax.swing.JPanel; - -import forge.item.InventoryItem; - -/** - * Base class for any cardView panel. - * - */ -public abstract class CardPanelBase extends JPanel { - private static final long serialVersionUID = -2230733670423143126L; - - /** - * - * showCard. - * - * @param card - * an InventoryItem - */ - public abstract void showCard(InventoryItem card); - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java b/src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java deleted file mode 100644 index c43ad008062..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CardPanelHeavy.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.awt.event.ActionEvent; -import java.io.File; - -import javax.swing.JButton; -import javax.swing.JOptionPane; - -import net.miginfocom.swing.MigLayout; -import forge.Card; -import forge.CardCharactersticName; -import forge.gui.CardDetailPanel; -import forge.gui.GuiDisplayUtil; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.properties.ForgeProps; -import forge.properties.NewConstants; -import forge.view.arcane.CardPanel; -import forge.view.arcane.ViewPanel; - -/** - * This panel is to be placed in the right part of a deck editor. - */ -public class CardPanelHeavy extends CardPanelBase { - - private static final long serialVersionUID = -7134546689397508597L; - - private final JButton changeStateButton = new JButton(); - - /* - * Removed Oct 25 2011 - Hellfish private JButton changePictureButton = new - * JButton(); private JButton removePictureButton = new JButton(); - */ - - // Controls to show card details - /** The detail. */ - private final CardDetailPanel detail = new CardDetailPanel(null); - - /** The picture. */ - private final CardPanel picture = new CardPanel(null); - - /** The picture view panel. */ - private final ViewPanel pictureViewPanel = new ViewPanel(); - - // fake card to allow picture changes - /** The c card hq. */ - private Card cCardHQ; - - /** Constant previousDirectory. */ - // private static File previousDirectory = null; - - /** - * Instantiates a new card panel heavy. - */ - public CardPanelHeavy() { - this.changeStateButton.setVisible(false); - this.changeStateButton.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - CardPanelHeavy.this.changeStateButtonActionPerformed(e); - } - }); - this.changeStateButton.setFont(new java.awt.Font("Dialog", 0, 10)); - - /* - * Removed Oct 25 2011 - Hellfish - * changePictureButton.setText("Change picture..."); - * changePictureButton.addActionListener(new - * java.awt.event.ActionListener() { public void - * actionPerformed(ActionEvent e) { - * changePictureButton_actionPerformed(e); } }); if - * (!Singletons.getModel().getPreferences().lafFonts) - * changePictureButton.setFont(new java.awt.Font("Dialog", 0, 10)); - * - * removePictureButton.setText("Remove picture..."); - * removePictureButton.addActionListener(new - * java.awt.event.ActionListener() { public void - * actionPerformed(ActionEvent e) { - * removePictureButton_actionPerformed(e); } }); if - * (!Singletons.getModel().getPreferences().lafFonts) - * removePictureButton.setFont(new java.awt.Font("Dialog", 0, 10)); - */ - - this.pictureViewPanel.setCardPanel(this.picture); - - this.setLayout(new MigLayout("fill, ins 0")); - this.add(this.detail, "w 239, h 323, grow, flowy, wrap"); - /* - * Removed Oct 25 2011 - Hellfish this.add(changeStateButton, - * "align 50% 0%, split 3, flowx"); this.add(changePictureButton, - * "align 50% 0%"); this.add(removePictureButton, "align 50% 0%, wrap"); - */ - this.add(this.changeStateButton, "align 50% 0%, flowx, wrap"); - this.add(this.pictureViewPanel, "wmin 239, hmin 323, grow"); - } - - /* - * (non-Javadoc) - * - * @see - * forge.gui.deckeditor.CardPanelBase#showCard(forge.item.InventoryItem) - */ - @Override - public final void showCard(final InventoryItem card) { - final Card card2 = card instanceof CardPrinted ? ((CardPrinted) card).toForgeCard() : null; - this.detail.setCard(card2); - this.setCard(card2); - } - - /** - * Sets the card. - * - * @param c - * the new card - */ - public final void setCard(final Card c) { - if (this.picture.getCard() != null) { - if (this.picture.getCard().isInAlternateState()) { - this.picture.getCard().setState(CardCharactersticName.Original); - } - } - this.picture.setCard(c); - - if (c.isFlip()) { - this.changeStateButton.setVisible(true); - this.changeStateButton.setText("Flip"); - } else if (c.isDoubleFaced()) { - this.changeStateButton.setVisible(true); - this.changeStateButton.setText("Transform"); - } else { - this.changeStateButton.setVisible(false); - } - } - - /** - *

- * changeStateButton_actionPerformed. - *

- * - * @param e - * a {@link java.awt.event.ActionEvent} object. - */ - final void changeStateButtonActionPerformed(final ActionEvent e) { - final Card cur = this.picture.getCard(); - if (cur.isInAlternateState()) { - cur.setState(CardCharactersticName.Original); - } else { - if (cur.isFlip()) { - cur.setState(CardCharactersticName.Flipped); - } - if (cur.isDoubleFaced()) { - cur.setState(CardCharactersticName.Transformed); - } - } - - this.picture.setCard(cur); - this.detail.setCard(cur); - } - - /** - *

- * getImportFilename. - *

- * - * @param e - * the e - * @return a {@link java.io.File} object. - */ - /* - * private File getImportFilename() { final JFileChooser chooser = new - * JFileChooser(CardPanelHeavy.previousDirectory); final ImagePreviewPanel - * preview = new ImagePreviewPanel(); chooser.setAccessory(preview); - * chooser.addPropertyChangeListener(preview); - * chooser.addChoosableFileFilter(this.dckFilter); final int returnVal = - * chooser.showOpenDialog(null); - * - * if (returnVal == JFileChooser.APPROVE_OPTION) { final File file = - * chooser.getSelectedFile(); CardPanelHeavy.previousDirectory = - * file.getParentFile(); return file; } - * - * return null; - * - * } - */ - - /** The dck filter. */ - /* - * private final FileFilter dckFilter = new FileFilter() { - * - * @Override public boolean accept(final File f) { return - * f.getName().endsWith(".jpg") || f.isDirectory(); } - * - * @Override public String getDescription() { return "*.jpg"; } - * - * }; - */ - - /** - *

- * removePictureButton_actionPerformed - *

- * . Removed Oct 25 2011 - Hellfish - * - * @param e - * the e - */ - final void removePictureButtonActionPerformed(final ActionEvent e) { - if (this.cCardHQ != null) { - final String[] options = { "Yes", "No" }; - final int value = JOptionPane.showOptionDialog(null, "Do you want delete " + this.cCardHQ.getName() - + " picture?", "Delete picture", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, - options, options[1]); - if (value == 0) { - final String fileName = GuiDisplayUtil.cleanString(this.cCardHQ.getName()) + ".jpg"; - final File base = ForgeProps.getFile(NewConstants.IMAGE_BASE); - final File f = new File(base, fileName); - f.delete(); - JOptionPane.showMessageDialog(null, "Picture " + this.cCardHQ.getName() + " deleted.", - "Delete picture", JOptionPane.INFORMATION_MESSAGE); - this.setCard(this.cCardHQ); - } - } - } - - /** - * Gets the card. - * - * @return the card - */ - public final Card getCard() { - return this.detail.getCard(); - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java b/src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java deleted file mode 100644 index b6f927819bd..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CardPanelLite.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.JButton; -import javax.swing.JScrollPane; -import javax.swing.JTextPane; - -import net.miginfocom.swing.MigLayout; - -import org.apache.commons.lang3.StringUtils; - -import forge.Card; -import forge.CardCharactersticName; -import forge.Singletons; -import forge.card.CardEdition; -import forge.gui.CardDetailPanel; -import forge.gui.CardPicturePanel; -import forge.item.CardPrinted; -import forge.item.InventoryItem; -import forge.item.OpenablePack; -import forge.item.PreconDeck; - -/** - * This panel is to be placed in the right part of a deck editor. - * - */ -public class CardPanelLite extends CardPanelBase { - - private static final long serialVersionUID = -7134546689397508597L; - - // Controls to show card details - /** The detail. */ - private final CardDetailPanel detail = new CardDetailPanel(null); - private final CardPicturePanel picture = new CardPicturePanel(null); - private final JButton bChangeState = new JButton(); - private final JTextPane description = new JTextPane(); - private final JScrollPane descrScroll; - - /** - * - * Constructor. - */ - public CardPanelLite() { - this.bChangeState.setVisible(false); - this.bChangeState.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - CardPanelLite.this.bChangeStateActionPerformed(e); - } - }); - this.bChangeState.setFont(new java.awt.Font("Dialog", 0, 10)); - - this.descrScroll = new JScrollPane(this.description); - - this.setLayout(new MigLayout("fill, ins 0")); - this.add(this.detail, "w 239, h 303, grow, flowy, wrap"); - this.add(this.descrScroll, "w 239, h 303, grow, flowy, wrap"); - this.add(this.bChangeState, "align 50% 0%, wrap"); - this.add(this.picture, "wmin 239, hmin 323, grow"); - - this.description.setEditable(false); - this.description.setCursor(null); - this.description.setOpaque(false); - this.description.setFocusable(false); - } - - private static Dimension shrinkedComponent = new Dimension(239, 0); - private static Dimension expandedComponent = new Dimension(239, 303); - - /** - * - * ShowCard. - * - * @param card - * an InventoryItem - */ - @Override - public final void showCard(final InventoryItem card) { - this.picture.setCard(card); - final boolean isCard = (card != null) && (card instanceof CardPrinted); - this.detail.setVisible(isCard); - this.description.setVisible(!isCard); - this.descrScroll.setMaximumSize(isCard ? CardPanelLite.shrinkedComponent : CardPanelLite.expandedComponent); - this.detail.setMaximumSize(!isCard ? CardPanelLite.shrinkedComponent : CardPanelLite.expandedComponent); - if (isCard) { - final Card toSet = ((CardPrinted) card).toForgeCard(); - - this.detail.setCard(toSet); - if (toSet.hasAlternateState()) { - this.bChangeState.setVisible(true); - if (toSet.isFlip()) { - this.bChangeState.setText("Flip"); - } else { - this.bChangeState.setText("Transform"); - } - } - } else { - if (card instanceof OpenablePack) { - final OpenablePack booster = (OpenablePack) card; - final CardEdition set = Singletons.getModel().getEditions().getEditionByCodeOrThrow(booster.getEdition()); - final String tpl = "%s %s.%n%nContains %d cards.%n%nBuy it to reveal the cards and add them to your inventory."; - this.description.setText(String.format(tpl, set.getName(), booster.getType(), booster.getTotalCards())); - } else if (card instanceof PreconDeck) { - final PreconDeck deck = (PreconDeck) card; - final String desc = deck.getDescription(); - final String tpl = "%s%n%n%s%n%nThis deck contains the following cards:%n%s"; - final String decklist = StringUtils.join(deck.getDeck().getMain().toItemListString(), "\n"); - this.description.setText(String.format(tpl, deck.getName(), desc, decklist)); - this.description.setCaretPosition(0); - - } - } - } - - /** - * Sets the card. - * - * @param c - * the new card - */ - public final void setCard(final Card c) { - this.picture.setCard(c); - if (c != null) { - this.detail.setCard(c); - - if (c.isFlip()) { - this.bChangeState.setVisible(true); - this.bChangeState.setText("Flip"); - } else if (c.isDoubleFaced()) { - this.bChangeState.setVisible(true); - this.bChangeState.setText("Transform"); - } else { - this.bChangeState.setVisible(false); - } - } - } - - /** - * - * getCard. - * - * @return Card - */ - public final Card getCard() { - return this.detail.getCard(); - } - - private void bChangeStateActionPerformed(final ActionEvent e) { - final Card cur = this.detail.getCard(); - if (cur != null) { - if (cur.isDoubleFaced()) { - if (cur.getCurState() == CardCharactersticName.Transformed) { - cur.setState(CardCharactersticName.Original); - } else { - cur.setState(CardCharactersticName.Transformed); - } - } - - this.setCard(cur); - } - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java b/src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java deleted file mode 100644 index 040481d1e1c..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/CheckBoxWithIcon.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.ImageIcon; -import javax.swing.JCheckBox; - -/** - * Custom check box class for filter icon. - */ -public class CheckBoxWithIcon extends JCheckBox { - /* CHOPPIC */ - /* Custom check box class for filter icons */ - private static final long serialVersionUID = -8099263807219520120L; - - private final String imagePath = "res/images/deckeditor/"; - private final String iconYes; - private final String iconNo; - private final CheckBoxWithIcon cb; - - /** - * Instantiates a new check box with icon. - * - * @param filterName - * the filter name - * @param toolTip - * the tool tip - */ - CheckBoxWithIcon(final String filterName, final String toolTip) { - super("", true); - this.cb = this; - this.iconYes = this.imagePath + "filter_" + filterName + "_y.png"; - this.iconNo = this.imagePath + "filter_" + filterName + "_n.png"; - this.setIcon(new ImageIcon(this.iconYes)); - this.setToolTipText(toolTip); - this.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent actionEvent) { - if (CheckBoxWithIcon.this.cb.isSelected()) { - CheckBoxWithIcon.this.cb.setIcon(new ImageIcon(CheckBoxWithIcon.this.iconYes)); - } else { - CheckBoxWithIcon.this.cb.setIcon(new ImageIcon(CheckBoxWithIcon.this.iconNo)); - } - } - }); - } -} diff --git a/src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java b/src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java deleted file mode 100644 index 2d447c15627..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/DeckAnalysis.java +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.MouseEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JTable; -import javax.swing.ListModel; -import javax.swing.SwingConstants; -import javax.swing.border.BevelBorder; -import javax.swing.event.MouseInputAdapter; -import javax.swing.table.DefaultTableModel; - -import forge.card.CardRules; -import forge.card.CardType; -import forge.item.CardPrinted; -import forge.item.ItemPoolView; -import forge.util.MyRandom; -import net.miginfocom.swing.MigLayout; - -/** - * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI - * Builder, which is free for non-commercial use. If Jigloo is being used - * commercially (ie, by a corporation, company or business for any purpose - * whatever) then you should purchase a license for each developer using Jigloo. - * Please visit www.cloudgarden.com for details. Use of Jigloo implies - * acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN - * PURCHASED FOR THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR - * ANY CORPORATE OR COMMERCIAL PURPOSE. - * - * @author Forge - * @version $Id$ - */ -public class DeckAnalysis extends javax.swing.JDialog { - - /** Constant serialVersionUID=-8475271235196182185L. */ - private static final long serialVersionUID = -8475271235196182185L; - private JPanel jPanel1; - private JLabel jLabelColorless; - private JLabel jLabelMultiColor; - private JLabel jLabelWhite; - private JLabel jLabelSixMana; - private JLabel jLabelFiveMana; - private JLabel jLabelFourMana; - private JLabel jLabelThreeMana; - private JLabel jLabel1; - private JScrollPane jScrollPane1; - private JTable jTable1; - private JPanel jPanel5; - private JButton jButtonRegenerate; - private JLabel jLabel4; - private JSeparator jSeparator4; - private JPanel jPanel4; - private JList jListFirstHand; - private JLabel jLabelTwoMana; - private JLabel jLabelOneMana; - private JLabel jLabelManaCost; - private JSeparator jSeparator3; - private JLabel jLabelZeroMana; - private JPanel jPanel3; - private JLabel jLabelSorcery; - private JLabel jLabelPlaneswalker; - private JLabel jLabelRed; - private JLabel jLabelGreen; - private JLabel jLabelBlue; - private JLabel jLabelBlack; - private JLabel jLabelEnchant; - private JLabel jLabelLandType; - private JLabel jLabelInstant; - private JLabel jLabelCreature; - private JLabel jLabel3; - private JSeparator jSeparator2; - private JLabel jLabelArtifact; - private JPanel jPanel2; - private JLabel jLabelTotal; - private JLabel jLabelLand; - private JSeparator jSeparator1; - private JLabel jLabel2; - private JButton jButtonOk; - private final JDialog parentDialog; - - /** The deck. */ - private final ItemPoolView deck; - - /** - *

- * Constructor for GUI_DeckAnalysis. - *

- * - * @param g - * a {@link javax.swing.JFrame} object. - * @param deckView - * the deck view - */ - public DeckAnalysis(final JDialog g, final ItemPoolView deckView) { - super(g); - this.deck = deckView; - - this.parentDialog = g; - this.initGUI(); - } - - /** - *

- * initGUI. - *

- */ - private void initGUI() { - try { - - this.getContentPane().setLayout(null); - this.setVisible(true); - final int wWidth = 600; - final int wHeight = 600; - this.setPreferredSize(new java.awt.Dimension(wWidth, wHeight)); - - final Dimension screen = this.getToolkit().getScreenSize(); - final int x = (screen.width - wWidth) / 2; - final int y = (screen.height - wHeight) / 2; - this.setBounds(x, y, wWidth, wHeight); - this.setResizable(false); - this.setTitle("Deck Analysis"); - this.pack(); - // this.setIconImage(null); - - this.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(final WindowEvent arg0) { - DeckAnalysis.this.parentDialog.setEnabled(true); - } - - @Override - public void windowOpened(final WindowEvent arg0) { - - int cBlack, cBlue, cGreen, cRed, cWhite, cMulticolor, cColorless, cLand; - int cArtifact, cCreature, cEnchant, cInstant, cLandType, cPlaneswalker, cSorcery; - int mZero, mOne, mTwo, mThree, mFour, mFive, mSixMore; - float tManaCost; - CardRules c; - cBlack = 0; - cBlue = 0; - cGreen = 0; - cRed = 0; - cWhite = 0; - cMulticolor = 0; - cColorless = 0; - cLand = 0; - cArtifact = 0; - cCreature = 0; - cEnchant = 0; - cInstant = 0; - cLandType = 0; - cPlaneswalker = 0; - cSorcery = 0; - mZero = 0; - mOne = 0; - mTwo = 0; - mThree = 0; - mFour = 0; - mFive = 0; - mSixMore = 0; - tManaCost = 0; - - for (final Entry e : DeckAnalysis.this.deck) { - c = e.getKey().getCard(); - final int cnt = e.getValue(); - - if (c.getColor().isMulticolor()) { - cMulticolor = cMulticolor + cnt; - } else { - if (c.getColor().isBlack()) { - cBlack = cBlack + cnt; - } - if (c.getColor().isBlue()) { - cBlue = cBlue + cnt; - } - if (c.getColor().isGreen()) { - cGreen = cGreen + cnt; - } - if (c.getColor().isRed()) { - cRed = cRed + cnt; - } - if (c.getColor().isWhite()) { - cWhite = cWhite + cnt; - } - if (c.getColor().isColorless()) { - if (c.getType().isLand()) { - cLand = cLand + cnt; - } else { - cColorless = cColorless + cnt; - } - } - } - - // count card types - final CardType cType = c.getType(); - if (cType.isArtifact()) { - cArtifact = cArtifact + cnt; - } - if (cType.isCreature()) { - cCreature = cCreature + cnt; - } - if (cType.isEnchantment()) { - cEnchant = cEnchant + cnt; - } - if (cType.isInstant()) { - cInstant = cInstant + cnt; - } - if (cType.isLand()) { - cLandType = cLandType + cnt; - } - if (cType.isPlaneswalker()) { - cPlaneswalker = cPlaneswalker + cnt; - } - if (cType.isSorcery()) { - cSorcery = cSorcery + cnt; - } - - final int cmc = c.getManaCost().getCMC(); - if (cmc == 0) { - mZero = mZero + cnt; - } else if (cmc == 1) { - mOne = mOne + cnt; - } else if (cmc == 2) { - mTwo = mTwo + cnt; - } else if (cmc == 3) { - mThree = mThree + cnt; - } else if (cmc == 4) { - mFour = mFour + cnt; - } else if (cmc == 5) { - mFive = mFive + 1; - } else if (cmc >= 6) { - mSixMore = mSixMore + 1; - } - - tManaCost = tManaCost + (cmc * cnt); - } - final int total = DeckAnalysis.this.deck.countAll(); - BigDecimal aManaCost = new BigDecimal(tManaCost / total); - aManaCost = aManaCost.setScale(2, BigDecimal.ROUND_HALF_UP); - - DeckAnalysis.this.jLabelTotal.setText("Information about deck (total cards: " + total + "):"); - DeckAnalysis.this.jLabelManaCost.setText("Mana cost (ACC:" + aManaCost + ")"); - final Color cr = new Color(100, 100, 100); - - if (cBlack == 0) { - DeckAnalysis.this.jLabelBlack.setForeground(cr); - } - DeckAnalysis.this.jLabelBlack.setText(DeckAnalysis.this.formatStat("Black", cBlack, total)); - if (cBlue == 0) { - DeckAnalysis.this.jLabelBlue.setForeground(cr); - } - DeckAnalysis.this.jLabelBlue.setText(DeckAnalysis.this.formatStat("Blue", cBlue, total)); - if (cGreen == 0) { - DeckAnalysis.this.jLabelGreen.setForeground(cr); - } - DeckAnalysis.this.jLabelGreen.setText(DeckAnalysis.this.formatStat("Green", cGreen, total)); - if (cRed == 0) { - DeckAnalysis.this.jLabelRed.setForeground(cr); - } - DeckAnalysis.this.jLabelRed.setText(DeckAnalysis.this.formatStat("Red", cRed, total)); - if (cWhite == 0) { - DeckAnalysis.this.jLabelWhite.setForeground(cr); - } - DeckAnalysis.this.jLabelWhite.setText(DeckAnalysis.this.formatStat("White", cWhite, total)); - if (cMulticolor == 0) { - DeckAnalysis.this.jLabelMultiColor.setForeground(cr); - } - DeckAnalysis.this.jLabelMultiColor.setText(DeckAnalysis.this.formatStat("Multicolor", cMulticolor, - total)); - if (cColorless == 0) { - DeckAnalysis.this.jLabelColorless.setForeground(cr); - } - DeckAnalysis.this.jLabelColorless.setText(DeckAnalysis.this.formatStat("Colorless", cColorless, - total)); - - if (cLand == 0) { - DeckAnalysis.this.jLabelLand.setForeground(cr); - } - DeckAnalysis.this.jLabelLand.setText(DeckAnalysis.this.formatStat("Land", cLand, total)); - if (cArtifact == 0) { - DeckAnalysis.this.jLabelArtifact.setForeground(cr); - } - DeckAnalysis.this.jLabelArtifact.setText(DeckAnalysis.this.formatStat("Artifact", cArtifact, total)); - if (cCreature == 0) { - DeckAnalysis.this.jLabelCreature.setForeground(cr); - } - DeckAnalysis.this.jLabelCreature.setText(DeckAnalysis.this.formatStat("Creature", cCreature, total)); - if (cEnchant == 0) { - DeckAnalysis.this.jLabelEnchant.setForeground(cr); - } - DeckAnalysis.this.jLabelEnchant.setText(DeckAnalysis.this.formatStat("Enchant", cEnchant, total)); - if (cInstant == 0) { - DeckAnalysis.this.jLabelInstant.setForeground(cr); - } - DeckAnalysis.this.jLabelInstant.setText(DeckAnalysis.this.formatStat("Instant", cInstant, total)); - if (cLandType == 0) { - DeckAnalysis.this.jLabelLandType.setForeground(cr); - } - DeckAnalysis.this.jLabelLandType.setText(DeckAnalysis.this.formatStat("Land", cLandType, total)); - if (cPlaneswalker == 0) { - DeckAnalysis.this.jLabelPlaneswalker.setForeground(cr); - } - DeckAnalysis.this.jLabelPlaneswalker.setText(DeckAnalysis.this.formatStat("Planeswalker", - cPlaneswalker, total)); - - if (cSorcery == 0) { - DeckAnalysis.this.jLabelSorcery.setForeground(cr); - } - DeckAnalysis.this.jLabelSorcery.setText(DeckAnalysis.this.formatStat("Sorcery", cSorcery, total)); - if (mZero == 0) { - DeckAnalysis.this.jLabelZeroMana.setForeground(cr); - } - DeckAnalysis.this.jLabelZeroMana.setText(DeckAnalysis.this.formatStat("Zero mana", mZero, total)); - if (mOne == 0) { - DeckAnalysis.this.jLabelOneMana.setForeground(cr); - } - DeckAnalysis.this.jLabelOneMana.setText(DeckAnalysis.this.formatStat("One mana", mOne, total)); - if (mTwo == 0) { - DeckAnalysis.this.jLabelTwoMana.setForeground(cr); - } - DeckAnalysis.this.jLabelTwoMana.setText(DeckAnalysis.this.formatStat("Two mana", mTwo, total)); - if (mThree == 0) { - DeckAnalysis.this.jLabelThreeMana.setForeground(cr); - } - DeckAnalysis.this.jLabelThreeMana.setText(DeckAnalysis.this.formatStat("Three mana", mThree, total)); - if (mFour == 0) { - DeckAnalysis.this.jLabelFourMana.setForeground(cr); - } - DeckAnalysis.this.jLabelFourMana.setText(DeckAnalysis.this.formatStat("Four mana", mFour, total)); - if (mFive == 0) { - DeckAnalysis.this.jLabelFiveMana.setForeground(cr); - } - DeckAnalysis.this.jLabelFiveMana.setText(DeckAnalysis.this.formatStat("Five mana", mFive, total)); - if (mSixMore == 0) { - DeckAnalysis.this.jLabelSixMana.setForeground(cr); - } - DeckAnalysis.this.jLabelSixMana.setText(DeckAnalysis.this.formatStat("Six and more", mSixMore, - total)); - } - }); - - this.getContentPane().add(this.getJButton1()); - this.getContentPane().add(this.getJLabel1xx()); - this.getContentPane().add(this.getJButtonOk()); - this.getContentPane().add(this.getJPanel1()); - this.getContentPane().add(this.getJPanel2()); - this.getContentPane().add(this.getJPanel3()); - this.getContentPane().add(this.getJPanel4()); - this.getContentPane().add(this.getJPanel5()); - this.getContentPane().add(this.getJLabel1xxxxx()); - - } catch (final Exception e) { - e.printStackTrace(); - } - } - - private String formatStat(final String statName, final int value, final int deckSize) { - return String.format("%s: %d (%f%%)", statName, value, (100f * value) / deckSize); - } - - /** - *

- * Getter for the field jPanel1. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel1() { - if (this.jPanel1 == null) { - this.jPanel1 = new JPanel(); - - this.jPanel1.setLayout(null); - this.jPanel1.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel1.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel1.setBounds(5, 35, 137, 203); - this.jPanel1.add(this.getJLabel1()); - this.jPanel1.add(this.getJSeparator1()); - this.jPanel1.add(this.getJLabel2()); - this.jPanel1.add(this.getJLabel3()); - this.jPanel1.add(this.getJLabel4()); - this.jPanel1.add(this.getJLabel5()); - this.jPanel1.add(this.getJLabel6()); - this.jPanel1.add(this.getJLabel7()); - this.jPanel1.add(this.getJLabel8()); - this.jPanel1.add(this.getJLabel1x()); - } - return this.jPanel1; - } - - /** - *

- * Getter for the field jLabel2. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel2() { - if (this.jLabel2 == null) { - this.jLabel2 = new JLabel(); - this.jLabel2.setText("Color"); - this.jLabel2.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabel2.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabel2.setPreferredSize(new java.awt.Dimension(152, 39)); - this.jLabel2.setLayout(null); - this.jLabel2.setBounds(2, -3, 135, 26); - } - return this.jLabel2; - } - - /** - *

- * Getter for the field jSeparator1. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator1() { - if (this.jSeparator1 == null) { - this.jSeparator1 = new JSeparator(); - this.jSeparator1.setPreferredSize(new java.awt.Dimension(117, 6)); - this.jSeparator1.setLayout(null); - this.jSeparator1.setBounds(1, 20, 136, 5); - } - return this.jSeparator1; - } - - /** - *

- * Getter for the field jButtonOk. - *

- * - * @return a {@link javax.swing.JButton} object. - */ - private JButton getJButtonOk() { - if (this.jButtonOk == null) { - this.jButtonOk = new JButton(); - this.jButtonOk.setLayout(null); - this.jButtonOk.setText("OK"); - this.jButtonOk.setBounds(206, 536, 168, 31); - this.jButtonOk.addMouseListener(new MouseInputAdapter() { - @Override - public void mouseClicked(final MouseEvent e) { - DeckAnalysis.this.parentDialog.setEnabled(true); - DeckAnalysis.this.dispose(); - } - }); - } - return this.jButtonOk; - } - - /** - *

- * Getter for the field jLabel1. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1() { - if (this.jLabelBlack == null) { - this.jLabelBlack = new JLabel(); - this.jLabelBlack.setText("Black:"); - this.jLabelBlack.setPreferredSize(new java.awt.Dimension(105, 12)); - this.jLabelBlack.setLayout(null); - this.jLabelBlack.setBounds(10, 28, 127, 13); - } - return this.jLabelBlack; - } - - /** - *

- * Getter for the field jLabel3. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel3() { - if (this.jLabelBlue == null) { - this.jLabelBlue = new JLabel(); - this.jLabelBlue.setText("Blue:"); - this.jLabelBlue.setLayout(null); - this.jLabelBlue.setBounds(10, 50, 127, 13); - } - return this.jLabelBlue; - } - - /** - *

- * Getter for the field jLabel4. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4() { - if (this.jLabelGreen == null) { - this.jLabelGreen = new JLabel(); - this.jLabelGreen.setText("Green:"); - this.jLabelGreen.setLayout(null); - this.jLabelGreen.setBounds(10, 72, 127, 13); - } - return this.jLabelGreen; - } - - /** - *

- * getJLabel5. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel5() { - if (this.jLabelRed == null) { - this.jLabelRed = new JLabel(); - this.jLabelRed.setText("Red:"); - this.jLabelRed.setLayout(null); - this.jLabelRed.setBounds(10, 94, 127, 14); - } - return this.jLabelRed; - } - - /** - *

- * getJLabel6. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel6() { - if (this.jLabelWhite == null) { - this.jLabelWhite = new JLabel(); - this.jLabelWhite.setText("White:"); - this.jLabelWhite.setLayout(null); - this.jLabelWhite.setBounds(10, 116, 127, 13); - } - return this.jLabelWhite; - } - - /** - *

- * getJLabel7. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel7() { - if (this.jLabelMultiColor == null) { - this.jLabelMultiColor = new JLabel(); - this.jLabelMultiColor.setText("Multicolor:"); - this.jLabelMultiColor.setLayout(null); - this.jLabelMultiColor.setBounds(10, 138, 127, 12); - } - return this.jLabelMultiColor; - } - - /** - *

- * getJLabel8. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel8() { - if (this.jLabelColorless == null) { - this.jLabelColorless = new JLabel(); - this.jLabelColorless.setText("Colorless:"); - this.jLabelColorless.setLayout(null); - this.jLabelColorless.setBounds(10, 160, 128, 11); - } - return this.jLabelColorless; - } - - /** - *

- * getJLabel1x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1x() { - if (this.jLabelLand == null) { - this.jLabelLand = new JLabel(); - this.jLabelLand.setText("Land: "); - this.jLabelLand.setLayout(null); - this.jLabelLand.setBounds(10, 182, 129, 10); - } - return this.jLabelLand; - } - - /** - *

- * getJLabel1xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xx() { - if (this.jLabelTotal == null) { - this.jLabelTotal = new JLabel(); - this.jLabelTotal.setText("Information about deck:"); - this.jLabelTotal.setLayout(null); - this.jLabelTotal.setBounds(5, 0, 454, 35); - } - return this.jLabelTotal; - } - - /** - *

- * Getter for the field jPanel2. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel2() { - if (this.jPanel2 == null) { - this.jPanel2 = new JPanel(); - - this.jPanel2.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel2.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel2.setLayout(null); - this.jPanel2.setBounds(153, 35, 137, 203); - this.jPanel2.add(this.getJLabel1xxx()); - this.jPanel2.add(this.getJSeparator2()); - this.jPanel2.add(this.getJLabel3x()); - this.jPanel2.add(this.getJLabel4x()); - this.jPanel2.add(this.getJLabel5x()); - this.jPanel2.add(this.getJLabel6x()); - this.jPanel2.add(this.getJLabel7x()); - this.jPanel2.add(this.getJLabel8x()); - this.jPanel2.add(this.getJLabel10()); - } - return this.jPanel2; - } - - /** - *

- * getJLabel1xxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xxx() { - if (this.jLabelArtifact == null) { - this.jLabelArtifact = new JLabel(); - this.jLabelArtifact.setText("Artifact:"); - this.jLabelArtifact.setPreferredSize(new java.awt.Dimension(105, 12)); - this.jLabelArtifact.setLayout(null); - this.jLabelArtifact.setBounds(10, 28, 127, 13); - } - return this.jLabelArtifact; - } - - /** - *

- * Getter for the field jSeparator2. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator2() { - if (this.jSeparator2 == null) { - this.jSeparator2 = new JSeparator(); - this.jSeparator2.setPreferredSize(new java.awt.Dimension(117, 6)); - this.jSeparator2.setLayout(null); - this.jSeparator2.setBounds(1, 20, 136, 5); - } - return this.jSeparator2; - } - - /** - *

- * getJLabel3x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel3x() { - if (this.jLabel3 == null) { - this.jLabel3 = new JLabel(); - this.jLabel3.setText("Type"); - this.jLabel3.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabel3.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabel3.setPreferredSize(new java.awt.Dimension(152, 39)); - this.jLabel3.setLayout(null); - this.jLabel3.setBounds(2, -3, 135, 26); - } - return this.jLabel3; - } - - /** - *

- * getJLabel4x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4x() { - if (this.jLabelCreature == null) { - this.jLabelCreature = new JLabel(); - this.jLabelCreature.setText("Creature:"); - this.jLabelCreature.setLayout(null); - this.jLabelCreature.setBounds(10, 53, 127, 13); - } - return this.jLabelCreature; - } - - /** - *

- * getJLabel5x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel5x() { - if (this.jLabelEnchant == null) { - this.jLabelEnchant = new JLabel(); - this.jLabelEnchant.setText("Enchant:"); - this.jLabelEnchant.setLayout(null); - this.jLabelEnchant.setBounds(10, 79, 127, 13); - } - return this.jLabelEnchant; - } - - /** - *

- * getJLabel6x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel6x() { - if (this.jLabelInstant == null) { - this.jLabelInstant = new JLabel(); - this.jLabelInstant.setText("Instant:"); - this.jLabelInstant.setLayout(null); - this.jLabelInstant.setBounds(10, 105, 127, 14); - } - return this.jLabelInstant; - } - - /** - *

- * getJLabel7x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel7x() { - if (this.jLabelLandType == null) { - this.jLabelLandType = new JLabel(); - this.jLabelLandType.setText("Land:"); - this.jLabelLandType.setLayout(null); - this.jLabelLandType.setBounds(10, 130, 127, 13); - } - return this.jLabelLandType; - } - - /** - *

- * getJLabel8x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel8x() { - if (this.jLabelPlaneswalker == null) { - this.jLabelPlaneswalker = new JLabel(); - this.jLabelPlaneswalker.setText("Planeswalker:"); - this.jLabelPlaneswalker.setLayout(null); - this.jLabelPlaneswalker.setBounds(10, 156, 127, 13); - } - return this.jLabelPlaneswalker; - } - - /** - *

- * getJLabel10. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel10() { - if (this.jLabelSorcery == null) { - this.jLabelSorcery = new JLabel(); - this.jLabelSorcery.setText("Sorcery:"); - this.jLabelSorcery.setLayout(null); - this.jLabelSorcery.setBounds(10, 182, 127, 11); - } - return this.jLabelSorcery; - } - - /** - *

- * Getter for the field jPanel3. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel3() { - if (this.jPanel3 == null) { - this.jPanel3 = new JPanel(); - this.jPanel3.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel3.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel3.setLayout(null); - this.jPanel3.setBounds(302, 35, 137, 203); - this.jPanel3.add(this.getJLabel1xxxx()); - this.jPanel3.add(this.getJSeparator3()); - this.jPanel3.add(this.getJLabel4xx()); - this.jPanel3.add(this.getJLabel5xx()); - this.jPanel3.add(this.getJLabel6xx()); - this.jPanel3.add(this.getJLabel7xx()); - this.jPanel3.add(this.getJLabel8xx()); - this.jPanel3.add(this.getJLabel9()); - this.jPanel3.add(this.getJLabel10x()); - } - return this.jPanel3; - } - - /** - *

- * getJLabel1xxxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xxxx() { - if (this.jLabelZeroMana == null) { - this.jLabelZeroMana = new JLabel(); - this.jLabelZeroMana.setText("Zero mana:"); - this.jLabelZeroMana.setPreferredSize(new java.awt.Dimension(105, 12)); - this.jLabelZeroMana.setLayout(null); - this.jLabelZeroMana.setBounds(10, 28, 127, 13); - } - return this.jLabelZeroMana; - } - - /** - *

- * Getter for the field jSeparator3. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator3() { - if (this.jSeparator3 == null) { - this.jSeparator3 = new JSeparator(); - this.jSeparator3.setPreferredSize(new java.awt.Dimension(117, 6)); - this.jSeparator3.setLayout(null); - this.jSeparator3.setBounds(1, 20, 136, 5); - } - return this.jSeparator3; - } - - /** - *

- * getJLabel4xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4xx() { - if (this.jLabelManaCost == null) { - this.jLabelManaCost = new JLabel(); - this.jLabelManaCost.setText("Mana cost"); - this.jLabelManaCost.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabelManaCost.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabelManaCost.setPreferredSize(new java.awt.Dimension(152, 39)); - this.jLabelManaCost.setLayout(null); - this.jLabelManaCost.setBounds(2, -3, 135, 26); - } - return this.jLabelManaCost; - } - - /** - *

- * getJLabel5xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel5xx() { - if (this.jLabelOneMana == null) { - this.jLabelOneMana = new JLabel(); - this.jLabelOneMana.setText("One mana:"); - this.jLabelOneMana.setLayout(null); - this.jLabelOneMana.setBounds(10, 53, 127, 13); - } - return this.jLabelOneMana; - } - - /** - *

- * getJLabel6xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel6xx() { - if (this.jLabelTwoMana == null) { - this.jLabelTwoMana = new JLabel(); - this.jLabelTwoMana.setText("Two mana:"); - this.jLabelTwoMana.setLayout(null); - this.jLabelTwoMana.setBounds(10, 79, 127, 13); - } - return this.jLabelTwoMana; - } - - /** - *

- * getJLabel7xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel7xx() { - if (this.jLabelThreeMana == null) { - this.jLabelThreeMana = new JLabel(); - this.jLabelThreeMana.setText("Three mana:"); - this.jLabelThreeMana.setLayout(null); - this.jLabelThreeMana.setBounds(10, 105, 127, 14); - } - return this.jLabelThreeMana; - } - - /** - *

- * getJLabel8xx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel8xx() { - if (this.jLabelFourMana == null) { - this.jLabelFourMana = new JLabel(); - this.jLabelFourMana.setText("Four mana:"); - this.jLabelFourMana.setLayout(null); - this.jLabelFourMana.setBounds(10, 130, 127, 13); - } - return this.jLabelFourMana; - } - - /** - *

- * getJLabel9. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel9() { - if (this.jLabelFiveMana == null) { - this.jLabelFiveMana = new JLabel(); - this.jLabelFiveMana.setText("Five mana:"); - this.jLabelFiveMana.setLayout(null); - this.jLabelFiveMana.setBounds(10, 156, 127, 13); - } - return this.jLabelFiveMana; - } - - /** - *

- * getJLabel10x. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel10x() { - if (this.jLabelSixMana == null) { - this.jLabelSixMana = new JLabel(); - this.jLabelSixMana.setText("Six and more:"); - this.jLabelSixMana.setLayout(null); - this.jLabelSixMana.setBounds(10, 182, 127, 11); - } - return this.jLabelSixMana; - } - - /** - *

- * getJList1. - *

- * - * @return a {@link javax.swing.JList} object. - */ - private JList getJList1() { - final List rList = this.deck.toFlatList(); - - Collections.shuffle(rList, MyRandom.getRandom()); - Collections.shuffle(rList, MyRandom.getRandom()); - - ListModel jList1Model; - if (this.jListFirstHand == null) { - this.jListFirstHand = new JList(); - } - - if (rList.size() >= 40) { - jList1Model = new DefaultComboBoxModel(new String[] { rList.get(0).getName(), rList.get(1).getName(), - rList.get(2).getName(), rList.get(3).getName(), rList.get(4).getName(), rList.get(5).getName(), - rList.get(6).getName() }); - - } else { - jList1Model = new DefaultComboBoxModel(new String[] { "Few cards." }); - } - - this.jListFirstHand.setModel(jList1Model); - this.jListFirstHand.setLayout(null); - this.jListFirstHand.setBackground(new java.awt.Color(192, 192, 192)); - this.jListFirstHand.setSelectionBackground(new java.awt.Color(192, 192, 192)); - this.jListFirstHand.setSelectionForeground(new java.awt.Color(0, 0, 0)); - this.jListFirstHand.setFixedCellHeight(24); - this.jListFirstHand.setBounds(2, 21, 133, 167); - - return this.jListFirstHand; - } - - /** - *

- * Getter for the field jPanel4. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel4() { - if (this.jPanel4 == null) { - this.jPanel4 = new JPanel(); - this.jPanel4.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel4.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel4.setLayout(null); - this.jPanel4.setBounds(451, 35, 137, 202); - this.jPanel4.add(this.getJSeparator4()); - this.jPanel4.add(this.getJLabel4xxx()); - this.jPanel4.add(this.getJList1()); - this.jPanel4.add(this.getJButton1()); - } else { - this.jPanel4.removeAll(); - final MigLayout jPanel4Layout = new MigLayout(); - this.jPanel4.setBackground(new java.awt.Color(192, 192, 192)); - this.jPanel4.setPreferredSize(new java.awt.Dimension(139, 201)); - this.jPanel4.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel4.setLayout(jPanel4Layout); - this.jPanel4.add(this.getJSeparator4()); - this.jPanel4.add(this.getJLabel4xxx()); - this.jPanel4.add(this.getJList1()); - this.jPanel4.add(this.getJButton1()); - } - return this.jPanel4; - - } - - /** - *

- * Getter for the field jSeparator4. - *

- * - * @return a {@link javax.swing.JSeparator} object. - */ - private JSeparator getJSeparator4() { - if (this.jSeparator4 == null) { - this.jSeparator4 = new JSeparator(); - this.jSeparator4.setPreferredSize(new java.awt.Dimension(138, 8)); - this.jSeparator4.setLayout(null); - this.jSeparator4.setBounds(0, 19, 137, 7); - } - return this.jSeparator4; - } - - /** - *

- * getJLabel4xxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel4xxx() { - if (this.jLabel4 == null) { - this.jLabel4 = new JLabel(); - this.jLabel4.setText("Random start hand"); - this.jLabel4.setHorizontalAlignment(SwingConstants.CENTER); - this.jLabel4.setFont(new java.awt.Font("Segoe UI", 0, 14)); - this.jLabel4.setPreferredSize(new java.awt.Dimension(136, 24)); - this.jLabel4.setLayout(null); - this.jLabel4.setBounds(2, 0, 135, 20); - } - return this.jLabel4; - } - - /** - *

- * getJButton1. - *

- * - * @return a {@link javax.swing.JButton} object. - */ - private JButton getJButton1() { - - if (this.jButtonRegenerate == null) { - if (this.deck.countAll() >= 40) { - this.jButtonRegenerate = new JButton(); - this.jButtonRegenerate.setLayout(null); - this.jButtonRegenerate.setText("Regenerate hand"); - this.jButtonRegenerate.setPreferredSize(new java.awt.Dimension(139, 21)); - this.jButtonRegenerate.setBounds(2, 189, 133, 13); - this.jButtonRegenerate.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(final ActionEvent e) { - DeckAnalysis.this.jButtonRegenerateActionPerformed(e); - } - }); - } else { - this.jButtonRegenerate = new JButton(); - this.jButtonRegenerate.setBounds(2, 189, 133, 13); - this.jButtonRegenerate.setVisible(false); - } - } - return this.jButtonRegenerate; - } - - /** - *

- * jButtonRegenerate_actionPerformed. - *

- * - * @param e - * a {@link java.awt.event.ActionEvent} object. - */ - final void jButtonRegenerateActionPerformed(final ActionEvent e) { - this.getContentPane().removeAll(); - this.getContentPane().add(this.getJPanel5()); - this.getContentPane().add(this.getJLabel1xx()); - this.getContentPane().add(this.getJButtonOk()); - this.getContentPane().add(this.getJPanel1()); - this.getContentPane().add(this.getJPanel2()); - this.getContentPane().add(this.getJPanel3()); - this.getContentPane().add(this.getJPanel4()); - this.getContentPane().add(this.getJPanel5()); - this.getContentPane().add(this.getJLabel1xxxxx()); - this.getContentPane().repaint(); - - } - - /** - *

- * Getter for the field jPanel5. - *

- * - * @return a {@link javax.swing.JPanel} object. - */ - private JPanel getJPanel5() { - if (this.jPanel5 == null) { - this.jPanel5 = new JPanel(); - this.jPanel5.setLayout(null); - this.jPanel5.setBounds(5, 262, 583, 270); - this.jPanel5.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); - this.jPanel5.add(this.getJScrollPane1()); - } - return this.jPanel5; - } - - /** - *

- * Getter for the field jTable1. - *

- * - * @return a {@link javax.swing.JTable} object. - */ - private JTable getJTable1() { - if (this.jTable1 == null) { - final DefaultTableModel dm = new DefaultTableModel(); - dm.setDataVector(new Object[][] { {} }, new Object[] { "Card", "Qty", "1st", "2nd", "3rd", "4th", "5th", - "6th", "7th" }); - - this.jTable1 = new JTable(dm); - final List rList = this.deck.toFlatList(); - final String[] cardsName = new String[rList.size()]; - int cCount; - float fCount; - float firstTurnF, secondTurnF, thirdTurnF, fourthTurnF, fivethTurnF, sixthTurnF, seventhTurnF; - - for (int i = 0; i < rList.size(); i++) { - cardsName[i] = rList.get(i).getName(); - } - Arrays.sort(cardsName); - this.jTable1.setValueAt("Few cards.", 0, 0); - - if (rList.size() >= 40) { - this.jTable1.setValueAt(cardsName[0], 0, 0); - cCount = 1; - for (int i = 1; i < cardsName.length; i++) { - if (cardsName[i].equals(cardsName[i - 1])) { - cCount = cCount + 1; - - } else { - dm.addRow(new Object[][] { {} }); - this.jTable1.setValueAt(cardsName[i], dm.getRowCount() - 1, 0); - this.jTable1.setValueAt(cCount, dm.getRowCount() - 2, 1); - fCount = cCount; - - firstTurnF = fCount / rList.size(); - BigDecimal firstTurn = new BigDecimal(firstTurnF * 100); - firstTurn = firstTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(firstTurn.toString() + " %", dm.getRowCount() - 2, 2); - - secondTurnF = (((1 - firstTurnF) * fCount) / (rList.size() - 1)) + firstTurnF; - BigDecimal secondTurn = new BigDecimal(secondTurnF * 100); - secondTurn = secondTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(secondTurn.toString() + " %", dm.getRowCount() - 2, 3); - - thirdTurnF = (((1 - secondTurnF) * fCount) / (rList.size() - 2)) + secondTurnF; - BigDecimal thirdTurn = new BigDecimal(thirdTurnF * 100); - thirdTurn = thirdTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(thirdTurn.toString() + " %", dm.getRowCount() - 2, 4); - - fourthTurnF = (((1 - thirdTurnF) * fCount) / (rList.size() - 3)) + thirdTurnF; - BigDecimal fourthTurn = new BigDecimal(fourthTurnF * 100); - fourthTurn = fourthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fourthTurn.toString() + " %", dm.getRowCount() - 2, 5); - - fivethTurnF = (((1 - fourthTurnF) * fCount) / (rList.size() - 4)) + fourthTurnF; - BigDecimal fivethTurn = new BigDecimal(fivethTurnF * 100); - fivethTurn = fivethTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fivethTurn.toString() + " %", dm.getRowCount() - 2, 6); - - sixthTurnF = (((1 - fivethTurnF) * fCount) / (rList.size() - 5)) + fivethTurnF; - BigDecimal sixthTurn = new BigDecimal(sixthTurnF * 100); - sixthTurn = sixthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(sixthTurn.toString() + " %", dm.getRowCount() - 2, 7); - - seventhTurnF = (((1 - sixthTurnF) * fCount) / (rList.size() - 6)) + sixthTurnF; - BigDecimal seventhTurn = new BigDecimal(seventhTurnF * 100); - seventhTurn = seventhTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(seventhTurn.toString() + " %", dm.getRowCount() - 2, 8); - - cCount = 1; - } - if (i == (cardsName.length - 1)) { - this.jTable1.setValueAt(cCount, dm.getRowCount() - 1, 1); - fCount = cCount; - - firstTurnF = fCount / rList.size(); - BigDecimal firstTurn = new BigDecimal(firstTurnF * 100); - firstTurn = firstTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(firstTurn.toString() + " %", dm.getRowCount() - 1, 2); - - secondTurnF = (((1 - firstTurnF) * fCount) / (rList.size() - 1)) + firstTurnF; - BigDecimal secondTurn = new BigDecimal(secondTurnF * 100); - secondTurn = secondTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(secondTurn.toString() + " %", dm.getRowCount() - 1, 3); - - thirdTurnF = (((1 - secondTurnF) * fCount) / (rList.size() - 2)) + secondTurnF; - BigDecimal thirdTurn = new BigDecimal(thirdTurnF * 100); - thirdTurn = thirdTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(thirdTurn.toString() + " %", dm.getRowCount() - 1, 4); - - fourthTurnF = (((1 - thirdTurnF) * fCount) / (rList.size() - 3)) + thirdTurnF; - BigDecimal fourthTurn = new BigDecimal(fourthTurnF * 100); - fourthTurn = fourthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fourthTurn.toString() + " %", dm.getRowCount() - 1, 5); - - fivethTurnF = (((1 - fourthTurnF) * fCount) / (rList.size() - 4)) + fourthTurnF; - BigDecimal fivethTurn = new BigDecimal(fivethTurnF * 100); - fivethTurn = fivethTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(fivethTurn.toString() + " %", dm.getRowCount() - 1, 6); - - sixthTurnF = (((1 - fivethTurnF) * fCount) / (rList.size() - 5)) + fivethTurnF; - BigDecimal sixthTurn = new BigDecimal(sixthTurnF * 100); - sixthTurn = sixthTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(sixthTurn.toString() + " %", dm.getRowCount() - 1, 7); - - seventhTurnF = (((1 - sixthTurnF) * fCount) / (rList.size() - 6)) + sixthTurnF; - BigDecimal seventhTurn = new BigDecimal(seventhTurnF * 100); - seventhTurn = seventhTurn.setScale(1, BigDecimal.ROUND_HALF_UP); - this.jTable1.setValueAt(seventhTurn.toString() + " %", dm.getRowCount() - 1, 8); - - } - - } - } - - this.jTable1.getColumn("Qty").setMaxWidth(50); - this.jTable1.getColumn("1st").setMaxWidth(50); - this.jTable1.getColumn("2nd").setMaxWidth(50); - this.jTable1.getColumn("3rd").setMaxWidth(50); - this.jTable1.getColumn("4th").setMaxWidth(50); - this.jTable1.getColumn("5th").setMaxWidth(50); - this.jTable1.getColumn("6th").setMaxWidth(50); - this.jTable1.getColumn("7th").setMaxWidth(50); - this.jTable1.setRowHeight(18); - this.jTable1.setPreferredSize(new java.awt.Dimension(576, (18 * dm.getRowCount()) + 3)); - } - return this.jTable1; - } - - /** - *

- * Getter for the field jScrollPane1. - *

- * - * @return a {@link javax.swing.JScrollPane} object. - */ - private JScrollPane getJScrollPane1() { - if (this.jScrollPane1 == null) { - this.jScrollPane1 = new JScrollPane(); - this.jScrollPane1.setBounds(2, 2, 582, 268); - this.jScrollPane1.setSize(580, 268); - this.jScrollPane1.setViewportView(this.getJTable1()); - } - return this.jScrollPane1; - } - - /** - *

- * getJLabel1xxxxx. - *

- * - * @return a {@link javax.swing.JLabel} object. - */ - private JLabel getJLabel1xxxxx() { - if (this.jLabel1 == null) { - this.jLabel1 = new JLabel(); - this.jLabel1.setText("Draw Probabilities:"); - this.jLabel1.setLayout(null); - this.jLabel1.setBounds(7, 237, 447, 25); - } - return this.jLabel1; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java b/src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java deleted file mode 100644 index e3b45d7977d..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/FilterCheckBoxes.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.swing.JCheckBox; - - -import forge.card.CardRules; -import forge.item.CardPrinted; -import forge.util.closures.Predicate; - -/** - * A structural class for some checkboxes need for a deck editor, contains no - * JPanel to store boxes on Checkboxes are public so the using class should - * place them in some container. - */ -public class FilterCheckBoxes { - - /** The white. */ - private final JCheckBox white; - - /** The blue. */ - private final JCheckBox blue; - - /** The black. */ - private final JCheckBox black; - - /** The red. */ - private final JCheckBox red; - - /** The green. */ - private final JCheckBox green; - - /** The colorless. */ - private final JCheckBox colorless; - - /** The land. */ - private final JCheckBox land; - - /** The creature. */ - private final JCheckBox creature; - - /** The sorcery. */ - private final JCheckBox sorcery; - - /** The instant. */ - private final JCheckBox instant; - - /** The planeswalker. */ - private final JCheckBox planeswalker; - - /** The artifact. */ - private final JCheckBox artifact; - - /** The enchantment. */ - private final JCheckBox enchantment; - - // Very handy for classes using mass operations on an array of checkboxes - /** The all colors. */ - private final List allColors; - - /** The all types. */ - private final List allTypes; - - /** - * Instantiates a new filter check boxes. - * - * @param useGraphicalBoxes - * the use graphical boxes - */ - public FilterCheckBoxes(final boolean useGraphicalBoxes) { - if (useGraphicalBoxes) { - this.white = new CheckBoxWithIcon("white", "White"); - this.blue = new CheckBoxWithIcon("blue", "Blue"); - this.black = new CheckBoxWithIcon("black", "Black"); - this.red = new CheckBoxWithIcon("red", "Red"); - this.green = new CheckBoxWithIcon("green", "Green"); - this.colorless = new CheckBoxWithIcon("colorless", "Colorless"); - - this.land = new CheckBoxWithIcon("land", "Land"); - this.creature = new CheckBoxWithIcon("creature", "Creature"); - this.sorcery = new CheckBoxWithIcon("sorcery", "Sorcery"); - this.instant = new CheckBoxWithIcon("instant", "Instant"); - this.planeswalker = new CheckBoxWithIcon("planeswalker", "Planeswalker"); - this.artifact = new CheckBoxWithIcon("artifact", "Artifact"); - this.enchantment = new CheckBoxWithIcon("enchant", "Enchantment"); - } else { - // We moved the filters and now have room for the full name. - // this.white = new JCheckBox("W", true); - // this.blue = new JCheckBox("U", true); - // this.black = new JCheckBox("B", true); - // this.red = new JCheckBox("R", true); - // this.green = new JCheckBox("G", true); - // this.colorless = new JCheckBox("C", true); - this.white = new JCheckBox("White", true); - this.blue = new JCheckBox("Blue", true); - this.black = new JCheckBox("Black", true); - this.red = new JCheckBox("Red", true); - this.green = new JCheckBox("Green", true); - this.colorless = new JCheckBox("Colorless", true); - - this.land = new JCheckBox("Land", true); - this.creature = new JCheckBox("Creature", true); - this.sorcery = new JCheckBox("Sorcery", true); - this.instant = new JCheckBox("Instant", true); - this.planeswalker = new JCheckBox("Planeswalker", true); - this.artifact = new JCheckBox("Artifact", true); - this.enchantment = new JCheckBox("Enchantment", true); - } - - this.allColors = Arrays.asList(new JCheckBox[] { this.getWhite(), this.getBlue(), this.getBlack(), - this.getRed(), this.getGreen(), this.getColorless() }); - this.allTypes = Arrays.asList(new JCheckBox[] { this.getLand(), this.getCreature(), this.getSorcery(), - this.getInstant(), this.getPlaneswalker(), this.getArtifact(), this.getEnchantment() }); - } - - /** - * Builds the filter. - * - * @return the predicate - */ - public final Predicate buildFilter() { - final List> colors = new ArrayList>(); - if (this.getWhite().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_WHITE); - } - if (this.getBlue().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_BLUE); - } - if (this.getBlack().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_BLACK); - } - if (this.getRed().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_RED); - } - if (this.getGreen().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_GREEN); - } - if (this.getColorless().isSelected()) { - colors.add(CardRules.Predicates.Presets.IS_COLORLESS); - } - final Predicate filterByColor = colors.size() == 6 ? CardRules.Predicates.Presets.CONSTANT_TRUE - : Predicate.or(colors); - - final List> types = new ArrayList>(); - if (this.getLand().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_LAND); - } - if (this.getCreature().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_CREATURE); - } - if (this.getSorcery().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_SORCERY); - } - if (this.getInstant().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_INSTANT); - } - if (this.getPlaneswalker().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_PLANESWALKER); - } - if (this.getArtifact().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_ARTIFACT); - } - if (this.getEnchantment().isSelected()) { - types.add(CardRules.Predicates.Presets.IS_ENCHANTMENT); - } - final Predicate filterByType = types.size() == 7 ? CardRules.Predicates.Presets.CONSTANT_TRUE - : Predicate.or(types); - - return Predicate.brigde(Predicate.and(filterByColor, filterByType), CardPrinted.FN_GET_RULES); - } - - /** - * Gets the all types. - * - * @return the allTypes - */ - public List getAllTypes() { - return this.allTypes; - } - - /** - * Gets the white. - * - * @return the white - */ - public JCheckBox getWhite() { - return this.white; - } - - /** - * Gets the blue. - * - * @return the blue - */ - public JCheckBox getBlue() { - return this.blue; - } - - /** - * Gets the black. - * - * @return the black - */ - public JCheckBox getBlack() { - return this.black; - } - - /** - * Gets the red. - * - * @return the red - */ - public JCheckBox getRed() { - return this.red; - } - - /** - * Gets the colorless. - * - * @return the colorless - */ - public JCheckBox getColorless() { - return this.colorless; - } - - /** - * Gets the green. - * - * @return the green - */ - public JCheckBox getGreen() { - return this.green; - } - - /** - * Gets the land. - * - * @return the land - */ - public JCheckBox getLand() { - return this.land; - } - - /** - * Gets the all colors. - * - * @return the allColors - */ - public List getAllColors() { - return this.allColors; - } - - /** - * Gets the creature. - * - * @return the creature - */ - public JCheckBox getCreature() { - return this.creature; - } - - /** - * Gets the sorcery. - * - * @return the sorcery - */ - public JCheckBox getSorcery() { - return this.sorcery; - } - - /** - * Gets the instant. - * - * @return the instant - */ - public JCheckBox getInstant() { - return this.instant; - } - - /** - * Gets the planeswalker. - * - * @return the planeswalker - */ - public JCheckBox getPlaneswalker() { - return this.planeswalker; - } - - /** - * Gets the artifact. - * - * @return the artifact - */ - public JCheckBox getArtifact() { - return this.artifact; - } - - /** - * Gets the enchantment. - * - * @return the enchantment - */ - public JCheckBox getEnchantment() { - return this.enchantment; - } - -} diff --git a/src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java b/src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java deleted file mode 100644 index b9e1cb29e1c..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/FilterNameTypeSetPanel.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.awt.event.ItemListener; -import java.util.ArrayList; -import java.util.List; - -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JTextField; -import javax.swing.event.DocumentListener; - -import net.miginfocom.swing.MigLayout; - -import org.apache.commons.lang3.StringUtils; - -import forge.Singletons; -import forge.card.CardRules; -import forge.card.CardEdition; -import forge.game.GameFormat; -import forge.item.CardPrinted; -import forge.util.closures.Predicate; -import forge.util.closures.PredicateString.StringOp; - -/** - * A panel that holds Name, Type, Rules text fields aligned horizontally - * together with set filter. - */ -public class FilterNameTypeSetPanel extends JComponent { - - private static final long serialVersionUID = -6409564625432765430L; - - /** The label filter name. */ - private final JLabel labelFilterName = new JLabel(); - - /** The label filter type. */ - private final JLabel labelFilterType = new JLabel(); - - /** The label filter rules. */ - private final JLabel labelFilterRules = new JLabel(); - - /** The txt card name. */ - private final JTextField txtCardName = new JTextField(); - - /** The txt card type. */ - private final JTextField txtCardType = new JTextField(); - - /** The txt card rules. */ - private final JTextField txtCardRules = new JTextField(); - - /** The search set combo. */ - private final JComboBox searchSetCombo = new JComboBox(); - - /** - * Instantiates a new filter name type set panel. - */ - public FilterNameTypeSetPanel() { - this.setLayout(new MigLayout("fill, ins 0")); - - this.labelFilterName.setText("Name:"); - this.labelFilterName.setToolTipText("Card names must include the text in this field"); - this.add(this.labelFilterName, "cell 0 1, split 7"); - this.add(this.txtCardName, "wmin 100, grow"); - - this.labelFilterType.setText("Type:"); - this.labelFilterType.setToolTipText("Card types must include the text in this field"); - this.add(this.labelFilterType, ""); - this.add(this.txtCardType, "wmin 100, grow"); - - this.labelFilterRules.setText("Text:"); - this.labelFilterRules.setToolTipText("Card descriptions must include the text in this field"); - this.add(this.labelFilterRules, ""); - this.add(this.txtCardRules, "wmin 200, grow"); - - this.searchSetCombo.removeAllItems(); - this.searchSetCombo.addItem("(all sets and formats)"); - for (final GameFormat s : Singletons.getModel().getFormats()) { - this.searchSetCombo.addItem(s); - } - for (final CardEdition s : Singletons.getModel().getEditions()) { - this.searchSetCombo.addItem(s); - } - - this.add(this.searchSetCombo, "wmin 150, grow"); - } - - /** - * Sets the listeners. - * - * @param onTextChange - * the on text change - * @param onComboChange - * the on combo change - */ - public final void setListeners(final DocumentListener onTextChange, final ItemListener onComboChange) { - this.txtCardType.getDocument().addDocumentListener(onTextChange); - this.txtCardRules.getDocument().addDocumentListener(onTextChange); - this.txtCardName.getDocument().addDocumentListener(onTextChange); - this.searchSetCombo.addItemListener(onComboChange); - } - - /** - * Builds the filter. - * - * @return the predicate - */ - public final Predicate buildFilter() { - final List> rules = new ArrayList>(4); - if (StringUtils.isNotBlank(this.txtCardName.getText())) { - rules.add(CardPrinted.Predicates.name(StringOp.CONTAINS, this.txtCardName.getText())); - } - - if (StringUtils.isNotBlank(this.txtCardType.getText())) { - rules.add(Predicate.brigde(CardRules.Predicates.joinedType(StringOp.CONTAINS, this.txtCardType.getText()), - CardPrinted.FN_GET_RULES)); - } - - if (StringUtils.isNotBlank(this.txtCardRules.getText())) { - rules.add(Predicate.brigde(CardRules.Predicates.rules(StringOp.CONTAINS, this.txtCardRules.getText()), - CardPrinted.FN_GET_RULES)); - } - - if (this.searchSetCombo.getSelectedIndex() != 0) { - final Object selected = this.searchSetCombo.getSelectedItem(); - if (selected instanceof CardEdition) { - rules.add(CardPrinted.Predicates.printedInSets(((CardEdition) selected).getCode())); - } else if (selected instanceof GameFormat) { - rules.add(((GameFormat) selected).getFilterRules()); - } - } - - switch (rules.size()) { - case 0: - return Predicate.getTrue(CardPrinted.class); - case 1: - return rules.get(0); - case 2: - return Predicate.and(rules.get(0), rules.get(1)); - default: - return Predicate.and(rules); - } - } - - /** - * TODO: Write javadoc for this method. - */ - public final void clearFilters() { - this.txtCardName.setText(""); - this.txtCardType.setText(""); - this.txtCardRules.setText(""); - this.searchSetCombo.setSelectedIndex(0); - } -} diff --git a/src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java b/src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java deleted file mode 100644 index 4db0f5d82ed..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/TableColumnInfo.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.util.Map.Entry; - -import javax.swing.table.TableCellRenderer; - -import forge.util.closures.Lambda1; - - -/** - * Holds single column set up for TableModel. Contains name, width + functions - * to retrieve column's value for compare and for display (they are different, - * in case of sets for instance) - * - * @param - * the generic type - */ - -@SuppressWarnings("rawtypes") -public class TableColumnInfo { - private final String name; - - /** The min width. */ - private int minWidth; - - /** The max width. */ - private int maxWidth; - - /** The nominal width. */ - private int nominalWidth; - - /** The is min max applied. */ - private boolean isMinMaxApplied = true; - - /** The fn sort. */ - private final Lambda1> fnSort; // this will be - // used for - // sorting - - /** The fn display. */ - private final Lambda1> fnDisplay; // this is used - // to display - - private TableCellRenderer cellRenderer = null; - - /** - * Gets the name. - * - * @return the name - */ - public final String getName() { - return this.name; - } - - /** - * Instantiates a new table column info. - * - * @param colName - * the col name - * @param fieldSort - * the field sort - * @param fieldDisplay - * the field display - */ - public TableColumnInfo(final String colName, final Lambda1> fieldSort, - final Lambda1> fieldDisplay) { - this.fnSort = fieldSort; - this.fnDisplay = fieldDisplay; - this.name = colName; - } - - /** - * Instantiates a new table column info. - * - * @param colName - * the col name - * @param width - * the width - * @param fieldSort - * the field sort - * @param fieldDisplay - * the field display - */ - public TableColumnInfo(final String colName, final int width, - final Lambda1> fieldSort, - final Lambda1> fieldDisplay) { - this(colName, fieldSort, fieldDisplay); - this.setMaxWidth(width); - this.setMinWidth(width); - this.setNominalWidth(width); - } - - /** - * Instantiates a new table column info. - * - * @param colName - * the col name - * @param wMin - * the w min - * @param width - * the width - * @param wMax - * the w max - * @param fieldSort - * the field sort - * @param fieldDisplay - * the field display - */ - public TableColumnInfo(final String colName, final int wMin, final int width, final int wMax, - final Lambda1> fieldSort, - final Lambda1> fieldDisplay) { - this(colName, fieldSort, fieldDisplay); - this.setMaxWidth(wMax); - this.setMinWidth(wMin); - this.setNominalWidth(width); - } - - /** - * Sets the cell renderer. - * - * @param renderer - * the new cell renderer - */ - public final void setCellRenderer(final TableCellRenderer renderer) { - this.cellRenderer = renderer; - } - - /** - * Gets the cell renderer. - * - * @return the cell renderer - */ - public final TableCellRenderer getCellRenderer() { - return this.cellRenderer; - } - - /** - * Gets the min width. - * - * @return the minWidth - */ - public int getMinWidth() { - return this.minWidth; - } - - /** - * Sets the min width. - * - * @param minWidth0 - * the minWidth to set - */ - public void setMinWidth(final int minWidth0) { - this.minWidth = minWidth0; - } - - /** - * Gets the max width. - * - * @return the maxWidth - */ - public int getMaxWidth() { - return this.maxWidth; - } - - /** - * Sets the max width. - * - * @param maxWidth0 - * the maxWidth to set - */ - public void setMaxWidth(final int maxWidth0) { - this.maxWidth = maxWidth0; - } - - /** - * Gets the nominal width. - * - * @return the nominalWidth - */ - public int getNominalWidth() { - return this.nominalWidth; - } - - /** - * Sets the nominal width. - * - * @param nominalWidth0 - * the nominalWidth to set - */ - public void setNominalWidth(final int nominalWidth0) { - this.nominalWidth = nominalWidth0; - } - - /** - * Checks if is min max applied. - * - * @return the isMinMaxApplied - */ - public boolean isMinMaxApplied() { - return this.isMinMaxApplied; - } - - /** - * Sets the min max applied. - * - * @param isMinMaxApplied0 - * the isMinMaxApplied to set - */ - public void setMinMaxApplied(final boolean isMinMaxApplied0) { - this.isMinMaxApplied = isMinMaxApplied0; - } - - /** - * Gets the fn sort. - * - * @return the fnSort - */ - public Lambda1> getFnSort() { - return this.fnSort; - } - - /** - * Gets the fn display. - * - * @return the fnDisplay - */ - public Lambda1> getFnDisplay() { - return this.fnDisplay; - } -} diff --git a/src/main/java/forge/gui/deckeditor/elements/TableModel.java b/src/main/java/forge/gui/deckeditor/elements/TableModel.java deleted file mode 100644 index 04f48d0ffee..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/TableModel.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * 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.gui.deckeditor.elements; - -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map.Entry; - -import javax.swing.JTable; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TableModelEvent; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumn; -import javax.swing.table.TableColumnModel; - -import forge.item.InventoryItem; -import forge.item.ItemPool; -import forge.item.ItemPoolView; - -/** - *

- * TableModel class. - *

- * - * @param - * the generic type - * @author Forge - * @version $Id$ - */ -public final class TableModel extends AbstractTableModel { - /** - * - */ - private static final long serialVersionUID = -6896726613116254828L; - - private final class SortOrders { - private class Order { - private final int sortColumn; - private boolean isSortAsc = true; - - public Order(final int col) { - this.sortColumn = col; - } - }; - - private final int maxDepth = 3; - private final List orders = new ArrayList(3); - private TableSorterCascade sorter = null; - private boolean isSorterReady = false; - - private int indexOfColumn(final int column) { - int posColumn = this.orders.size() - 1; - for (; posColumn >= 0; posColumn--) { - if ((this.orders.get(posColumn) != null) && (this.orders.get(posColumn).sortColumn == column)) { - break; - } - } - return posColumn; - } - - // index of column to sort by, desired direction - public void add(final int column, final boolean wantAsc) { - this.add(column); - this.orders.get(0).isSortAsc = wantAsc; - this.isSorterReady = false; - } - - // puts desired direction on top, set "asc"; if already was on top, - // inverts direction; - public void add(final int column) { - final int posColumn = this.indexOfColumn(column); - switch (posColumn) { - case -1: // no such column here - let's add then - this.orders.add(0, new Order(column)); - break; - case 0: // found at top-level, should invert - this.orders.get(0).isSortAsc ^= true; // invert - break; - default: // found somewhere, move down others, set this one onto - // top; - this.orders.remove(posColumn); - this.orders.add(0, new Order(column)); - break; - } - if (this.orders.size() > this.maxDepth) { - this.orders.remove(this.maxDepth); - } - this.isSorterReady = false; - } - - public TableSorterCascade getSorter() { - if (!this.isSorterReady) { - final List> oneColSorters = new ArrayList>(this.maxDepth); - for (final Order order : this.orders) { - oneColSorters.add(new TableSorter(TableModel.this.columns.get(order.sortColumn).getFnSort(), - order.isSortAsc)); - } - this.sorter = new TableSorterCascade(oneColSorters); - } - return this.sorter; - } - } - - private final ItemPool data; - private final CardPanelBase cardDisplay; - private final List> columns; - private final SortOrders sortOrders = new SortOrders(); - - /** - * Instantiates a new table model. - * - * @param cd - * the cd - * @param columnsToShow - * the columns to show - * @param cls - * the cls - */ - public TableModel(final CardPanelBase cd, final List> columnsToShow, final Class cls) { - this.data = new ItemPool(cls); - this.cardDisplay = cd; - this.columns = columnsToShow; - this.columns.get(4).setMinMaxApplied(false); - } - - /** - * Resize cols. - * - * @param table - * the table - */ - public void resizeCols(final JTable table) { - TableColumn tableColumn = null; - for (int i = 0; i < table.getColumnCount(); i++) { - tableColumn = table.getColumnModel().getColumn(i); - final TableColumnInfo colInfo = this.columns.get(i); - - tableColumn.setPreferredWidth(colInfo.getNominalWidth()); - if (colInfo.isMinMaxApplied()) { - tableColumn.setMinWidth(colInfo.getMinWidth()); - tableColumn.setMaxWidth(colInfo.getMaxWidth()); - } - } - } - - /** - * Clear. - */ - public void clear() { - this.data.clear(); - } - - /** - * Gets the cards. - * - * @return the cards - */ - public ItemPoolView getCards() { - return this.data.getView(); - } - - /** - *

- * removeCard. - *

- * - * @param c - * a {@link forge.Card} object. - */ - public void removeCard(final T c) { - final boolean wasThere = this.data.count(c) > 0; - if (wasThere) { - this.data.remove(c); - this.fireTableDataChanged(); - } - } - - /** - * Adds the card. - * - * @param c - * the c - */ - public void addCard(final T c) { - this.data.add(c); - this.fireTableDataChanged(); - } - - /** - * Adds the card. - * - * @param c - * the c - * @param count - * the count - */ - public void addCard(final T c, final int count) { - this.data.add(c, count); - this.fireTableDataChanged(); - } - - /** - * Adds the card. - * - * @param e - * the e - */ - public void addCard(final Entry e) { - this.data.add(e.getKey(), e.getValue()); - this.fireTableDataChanged(); - } - - /** - * Adds the cards. - * - * @param c - * the c - */ - public void addCards(final Iterable> c) { - this.data.addAll(c); - this.fireTableDataChanged(); - } - - /** - * Adds the all cards. - * - * @param c - * the c - */ - public void addAllCards(final Iterable c) { - this.data.addAllFlat(c); - this.fireTableDataChanged(); - } - - /** - * Row to card. - * - * @param row - * the row - * @return the entry - */ - public Entry rowToCard(final int row) { - final List> model = this.data.getOrderedList(); - return (row >= 0) && (row < model.size()) ? model.get(row) : null; - } - - /* - * (non-Javadoc) - * - * @see javax.swing.table.TableModel#getRowCount() - */ - /** - * Gets the row count. - * - * @return int - */ - @Override - public int getRowCount() { - return this.data.countDistinct(); - } - - /* - * (non-Javadoc) - * - * @see javax.swing.table.TableModel#getColumnCount() - */ - /** - * Gets the column count. - * - * @return int - */ - @Override - public int getColumnCount() { - return this.columns.size(); - } - - /** {@inheritDoc} */ - @Override - public String getColumnName(final int n) { - return this.columns.get(n).getName(); - } - - /** {@inheritDoc} */ - @SuppressWarnings("unchecked") - @Override - public Object getValueAt(final int row, final int column) { - return this.columns.get(column).getFnDisplay().apply((Entry) this.rowToCard(row)); - } - - /** - * The listener interface for receiving column events. The class that is - * interested in processing a column event implements this interface, and - * the object created with that class is registered with a component using - * the component's addColumnListener method. When the column event occurs, - * that object's appropriate method is invoked. - * - */ - class ColumnListener extends MouseAdapter { - - /** The table. */ - private final JTable table; - - /** - * Instantiates a new column listener. - * - * @param t - * the t - */ - public ColumnListener(final JTable t) { - this.table = t; - } - - /* - * (non-Javadoc) - * - * @see - * java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent) - */ - /** - * Mouse clicked. - * - * @param e - * MouseEvent - */ - @Override - public void mouseClicked(final MouseEvent e) { - final TableColumnModel colModel = this.table.getColumnModel(); - final int columnModelIndex = colModel.getColumnIndexAtX(e.getX()); - final int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex(); - - if (modelIndex < 0) { - return; - } - - // This will invert if needed - TableModel.this.sortOrders.add(modelIndex); - - for (int i = 0; i < TableModel.this.columns.size(); i++) { - final TableColumn column = colModel.getColumn(i); - column.setHeaderValue(TableModel.this.getColumnName(column.getModelIndex())); - } - this.table.getTableHeader().repaint(); - - TableModel.this.resort(); - this.table.tableChanged(new TableModelEvent(TableModel.this)); - this.table.repaint(); - } - } - - /** - * Show selected card. - * - * @param table - * the table - */ - public void showSelectedCard(final JTable table) { - final int row = table.getSelectedRow(); - if (row != -1) { - final T cp = this.rowToCard(row).getKey(); - this.cardDisplay.showCard(cp); - } - } - - /** - *

- * addListeners. - *

- * - * @param table - * a {@link javax.swing.JTable} object. - */ - public void addListeners(final JTable table) { - // updates card detail, listens to any key strokes - table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - - @Override - public void valueChanged(final ListSelectionEvent arg0) { - TableModel.this.showSelectedCard(table); - } - }); - table.addFocusListener(new FocusListener() { - - @Override - public void focusLost(final FocusEvent e) { - } - - @Override - public void focusGained(final FocusEvent e) { - TableModel.this.showSelectedCard(table); - } - }); - - table.getTableHeader().addMouseListener(new ColumnListener(table)); - - } // addCardListener() - - private class MyComparator implements Comparator> { - /* (non-Javadoc) - * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) - */ - private TableSorterCascade sorter = TableModel.this.sortOrders.getSorter(); - @SuppressWarnings("unchecked") - @Override - public int compare(Entry o1, Entry o2) { - return sorter.compare((Entry) o1, (Entry) o2); - } - } - - /** - * Resort. - */ - public void resort() { - Collections.sort(this.data.getOrderedList(), new MyComparator()); - } - - /** - * Sort. - * - * @param iCol - * the i col - * @param isAsc - * the is asc - */ - public void sort(final int iCol, final boolean isAsc) { - this.sortOrders.add(iCol, isAsc); - this.resort(); - } - -} // CardTableModel diff --git a/src/main/java/forge/gui/deckeditor/elements/package-info.java b/src/main/java/forge/gui/deckeditor/elements/package-info.java deleted file mode 100644 index 00dba87a7f2..00000000000 --- a/src/main/java/forge/gui/deckeditor/elements/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -/** Forge Card Game. */ -package forge.gui.deckeditor.elements; - diff --git a/src/main/java/forge/gui/deckeditor/DeckController.java b/src/main/java/forge/gui/deckeditor/tables/DeckController.java similarity index 83% rename from src/main/java/forge/gui/deckeditor/DeckController.java rename to src/main/java/forge/gui/deckeditor/tables/DeckController.java index 132ca046c2f..197984b0cd7 100644 --- a/src/main/java/forge/gui/deckeditor/DeckController.java +++ b/src/main/java/forge/gui/deckeditor/tables/DeckController.java @@ -15,15 +15,17 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor; +package forge.gui.deckeditor.tables; -import java.awt.Component; import java.util.ArrayList; - import org.apache.commons.lang3.StringUtils; import forge.deck.DeckBase; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CProbabilities; +import forge.gui.deckeditor.controllers.CStatistics; +import forge.gui.deckeditor.views.VCurrentDeck; import forge.util.IStorage; import forge.util.closures.Lambda0; @@ -38,7 +40,7 @@ public class DeckController { private boolean saved; private boolean modelInStore; private final IStorage folder; - private final DeckEditorBase view; + private final ACEditorBase view; private final Lambda0 newModelCreator; /** @@ -48,7 +50,7 @@ public class DeckController { * @param view0 the view0 * @param newModelCreator0 the new model creator0 */ - public DeckController(final IStorage folder0, final DeckEditorBase view0, + public DeckController(final IStorage folder0, final ACEditorBase view0, final Lambda0 newModelCreator0) { this.folder = folder0; this.view = view0; @@ -85,7 +87,12 @@ public class DeckController { public void setModel(final T document, final boolean isStored) { this.modelInStore = isStored; this.model = document; - this.view.updateView(); + this.view.resetTables(); + + VCurrentDeck.SINGLETON_INSTANCE.getTxfTitle().setText(model.getName()); + CStatistics.SINGLETON_INSTANCE.update(); + CProbabilities.SINGLETON_INSTANCE.update(); + this.saved = true; // unless set to false in notify if (!this.isModelInSyncWithFolder()) { this.notifyModelChanged(); @@ -110,7 +117,7 @@ public class DeckController { * * @return the view */ - public DeckEditorBase getView() { + public ACEditorBase getView() { return this.view; } @@ -127,20 +134,6 @@ public class DeckController { // view.setTitle(); } - /* - * (non-Javadoc) - * - * @see forge.gui.deckeditor.IDeckController#getOwnerWindow() - */ - /** - * Gets the owner window. - * - * @return the owner window - */ - public Component getOwnerWindow() { - return this.getView(); - } - /* * (non-Javadoc) * @@ -187,6 +180,7 @@ public class DeckController { if (null == model) { return; } + this.folder.add(this.model); // copy to new instance which will be edited and left if unsaved this.setModel((T) this.model.copyTo(this.model.getName()), true); @@ -258,20 +252,6 @@ public class DeckController { return !this.folder.isUnique(deckName); } - /* (non-Javadoc) - * @see forge.gui.deckeditor.IDeckController#isGoodName(java.lang.String) - */ - - /** - * Checks if is good name. - * - * @param deckName the deck name - * @return true, if is good name - */ - public boolean isGoodName(final String deckName) { - return StringUtils.isNotBlank(deckName) && this.folder.isUnique(deckName); - } - /* * (non-Javadoc) * @@ -314,6 +294,6 @@ public class DeckController { public void newModel() { this.model = this.newModelCreator.apply(); this.saved = true; - this.view.updateView(); + this.view.resetTables(); } } diff --git a/src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java b/src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java new file mode 100644 index 00000000000..de1fcb9b2f0 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/IntegerRenderer.java @@ -0,0 +1,44 @@ +/* + * 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.gui.deckeditor.tables; + +import java.awt.Component; + +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +/** + * A quick converter to avoid -1 being displayed for unapplicable values. + */ +@SuppressWarnings("serial") +public class IntegerRenderer extends DefaultTableCellRenderer { + /* + * (non-Javadoc) + * + * @see + * javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent + * (javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) + */ + @Override + public final Component getTableCellRendererComponent(final JTable table, Object value0, + final boolean isSelected, final boolean hasFocus, final int row, final int column) { + + if ((Integer) value0 == -1) { value0 = "-"; } + return super.getTableCellRendererComponent(table, value0, isSelected, hasFocus, row, column); + } +} diff --git a/src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java b/src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java similarity index 95% rename from src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java rename to src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java index 25a9536c35f..c0f90471380 100644 --- a/src/main/java/forge/gui/deckeditor/elements/ManaCostRenderer.java +++ b/src/main/java/forge/gui/deckeditor/tables/ManaCostRenderer.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.awt.Component; import java.awt.Graphics; diff --git a/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java b/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java new file mode 100644 index 00000000000..cbac7c9b425 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/SColumnUtil.java @@ -0,0 +1,530 @@ +/* + * 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.gui.deckeditor.tables; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +import javax.swing.JTable; +import javax.swing.table.TableColumnModel; + +import forge.Singletons; +import forge.card.CardColor; +import forge.card.CardEdition; +import forge.card.CardManaCost; +import forge.card.CardRarity; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.InventoryItemFromSet; +import forge.util.closures.Lambda1; + +/** + * A collection of methods pertaining to columns in card catalog and + * current deck tables, for use in the deck editor. + *

+ * (S at beginning of class name denotes a static factory.) + * + */ +public final class SColumnUtil { + /** + * Each catalog column identified in the XML file is + * referenced using these names. Its name in the XML + * should match the name in the enum. Underscores + * will be replaced with spaces in the display. + *

+ * Note: To add a new column, put an enum here, and also add in the XML prefs file. + */ + public enum ColumnName { /** */ + CAT_QUANTITY, /** */ + CAT_NAME, /** */ + CAT_COST, /** */ + CAT_COLOR, /** */ + CAT_TYPE, /** */ + CAT_POWER, /** */ + CAT_TOUGHNESS, /** */ + CAT_CMC, /** */ + CAT_RARITY, /** */ + CAT_SET, /** */ + CAT_AI, /** */ + CAT_NEW, /** */ + CAT_PURCHASE_PRICE, /** */ + CAT_DECKS, /** */ + DECK_QUANTITY, /** */ + DECK_NAME, /** */ + DECK_COST, /** */ + DECK_COLOR, /** */ + DECK_TYPE, /** */ + DECK_POWER, /** */ + DECK_TOUGHNESS, /** */ + DECK_CMC, /** */ + DECK_RARITY, /** */ + DECK_SET, /** */ + DECK_AI, /** */ + DECK_NEW, /** */ + DECK_SALE_PRICE; + } + + /** Possible states of data sorting in a column: none, ascending, or descending. */ + public enum SortState { /** */ + NONE, /** */ + ASC, /** */ + DESC + } + + /** @return List> */ + public static List> getCatalogDefaultColumns() { + final List> columns = new ArrayList>(); + + columns.add(SColumnUtil.getColumn(ColumnName.CAT_QUANTITY)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_NAME)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_COST)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_COLOR)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_TYPE)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_POWER)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_TOUGHNESS)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_CMC)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_RARITY)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_SET)); + columns.add(SColumnUtil.getColumn(ColumnName.CAT_AI)); + + return columns; + } + + /** @return List> */ + public static List> getDeckDefaultColumns() { + final List> columns = new ArrayList>(); + + columns.add(SColumnUtil.getColumn(ColumnName.DECK_QUANTITY)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_NAME)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_COST)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_COLOR)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_TYPE)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_POWER)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_TOUGHNESS)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_CMC)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_RARITY)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_SET)); + columns.add(SColumnUtil.getColumn(ColumnName.DECK_AI)); + + return columns; + } + + /** Should be called after column preferences has run, which has created a new column list. */ + public static void attachSortAndDisplayFunctions() { + SColumnUtil.getColumn(ColumnName.CAT_QUANTITY).setSortAndDisplayFunctions( + SColumnUtil.FN_QTY_COMPARE, SColumnUtil.FN_QTY_GET); + SColumnUtil.getColumn(ColumnName.CAT_NAME).setSortAndDisplayFunctions( + SColumnUtil.FN_NAME_COMPARE, SColumnUtil.FN_NAME_GET); + SColumnUtil.getColumn(ColumnName.CAT_COST).setSortAndDisplayFunctions( + SColumnUtil.FN_COST_COMPARE, SColumnUtil.FN_COST_GET); + SColumnUtil.getColumn(ColumnName.CAT_COLOR).setSortAndDisplayFunctions( + SColumnUtil.FN_COLOR_COMPARE, SColumnUtil.FN_COLOR_GET); + SColumnUtil.getColumn(ColumnName.CAT_TYPE).setSortAndDisplayFunctions( + SColumnUtil.FN_TYPE_COMPARE, SColumnUtil.FN_TYPE_GET); + SColumnUtil.getColumn(ColumnName.CAT_POWER).setSortAndDisplayFunctions( + SColumnUtil.FN_POWER_COMPARE, SColumnUtil.FN_POWER_GET); + SColumnUtil.getColumn(ColumnName.CAT_TOUGHNESS).setSortAndDisplayFunctions( + SColumnUtil.FN_TOUGHNESS_COMPARE, SColumnUtil.FN_TOUGHNESS_GET); + SColumnUtil.getColumn(ColumnName.CAT_CMC).setSortAndDisplayFunctions( + SColumnUtil.FN_CMC_COMPARE, SColumnUtil.FN_CMC_GET); + SColumnUtil.getColumn(ColumnName.CAT_RARITY).setSortAndDisplayFunctions( + SColumnUtil.FN_RARITY_COMPARE, SColumnUtil.FN_RARITY_GET); + SColumnUtil.getColumn(ColumnName.CAT_SET).setSortAndDisplayFunctions( + SColumnUtil.FN_SET_COMPARE, SColumnUtil.FN_SET_GET); + SColumnUtil.getColumn(ColumnName.CAT_AI).setSortAndDisplayFunctions( + SColumnUtil.FN_AI_STATUS_COMPARE, SColumnUtil.FN_AI_STATUS_GET); + + SColumnUtil.getColumn(ColumnName.DECK_QUANTITY).setSortAndDisplayFunctions( + SColumnUtil.FN_QTY_COMPARE, SColumnUtil.FN_QTY_GET); + SColumnUtil.getColumn(ColumnName.DECK_NAME).setSortAndDisplayFunctions( + SColumnUtil.FN_NAME_COMPARE, SColumnUtil.FN_NAME_GET); + SColumnUtil.getColumn(ColumnName.DECK_COST).setSortAndDisplayFunctions( + SColumnUtil.FN_COST_COMPARE, SColumnUtil.FN_COST_GET); + SColumnUtil.getColumn(ColumnName.DECK_COLOR).setSortAndDisplayFunctions( + SColumnUtil.FN_COLOR_COMPARE, SColumnUtil.FN_COLOR_GET); + SColumnUtil.getColumn(ColumnName.DECK_TYPE).setSortAndDisplayFunctions( + SColumnUtil.FN_TYPE_COMPARE, SColumnUtil.FN_TYPE_GET); + SColumnUtil.getColumn(ColumnName.DECK_POWER).setSortAndDisplayFunctions( + SColumnUtil.FN_POWER_COMPARE, SColumnUtil.FN_POWER_GET); + SColumnUtil.getColumn(ColumnName.DECK_TOUGHNESS).setSortAndDisplayFunctions( + SColumnUtil.FN_TOUGHNESS_COMPARE, SColumnUtil.FN_TOUGHNESS_GET); + SColumnUtil.getColumn(ColumnName.DECK_CMC).setSortAndDisplayFunctions( + SColumnUtil.FN_CMC_COMPARE, SColumnUtil.FN_CMC_GET); + SColumnUtil.getColumn(ColumnName.DECK_RARITY).setSortAndDisplayFunctions( + SColumnUtil.FN_RARITY_COMPARE, SColumnUtil.FN_RARITY_GET); + SColumnUtil.getColumn(ColumnName.DECK_SET).setSortAndDisplayFunctions( + SColumnUtil.FN_SET_COMPARE, SColumnUtil.FN_SET_GET); + SColumnUtil.getColumn(ColumnName.DECK_AI).setSortAndDisplayFunctions( + SColumnUtil.FN_AI_STATUS_COMPARE, SColumnUtil.FN_AI_STATUS_GET); + + SColumnUtil.getColumn(ColumnName.CAT_COST).setCellRenderer(new ManaCostRenderer()); + SColumnUtil.getColumn(ColumnName.CAT_POWER).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.CAT_TOUGHNESS).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.CAT_CMC).setCellRenderer(new IntegerRenderer()); + + SColumnUtil.getColumn(ColumnName.DECK_COST).setCellRenderer(new ManaCostRenderer()); + SColumnUtil.getColumn(ColumnName.DECK_POWER).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.DECK_TOUGHNESS).setCellRenderer(new IntegerRenderer()); + SColumnUtil.getColumn(ColumnName.DECK_CMC).setCellRenderer(new IntegerRenderer()); + } + + /** + * Hides/shows a table column. + * + * @param col0 TableColumnInfo + * @param extends InventoryItem + * @param extends DeckBase + */ + @SuppressWarnings("unchecked") + public static + void toggleColumn(final TableColumnInfo col0) { + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final JTable tbl = (col0.getEnumValue().substring(0, 4).equals("DECK")) + ? ed.getTableDeck().getTable() + : ed.getTableCatalog().getTable(); + + final TableColumnModel colmodel = tbl.getColumnModel(); + + if (col0.isShowing()) { + col0.setShowing(false); + colmodel.removeColumn(col0); + } + else { + col0.setShowing(true); + colmodel.addColumn(col0); + if (col0.getModelIndex() < colmodel.getColumnCount()) { + colmodel.moveColumn(colmodel.getColumnIndex(col0.getIdentifier()), col0.getModelIndex()); + } + } + } + + /** + * Retrieve a custom column (uses identical method in SEditorIO). + * + * @param id0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return TableColumnInfo + */ + public static TableColumnInfo getColumn(final ColumnName id0) { + return SEditorIO.getColumn(id0); + } + + /** + * Convenience method to get a column's index in the view (that is, + * in the TableColumnModel). + * + * @param id0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return int + * @param extends InventoryItem + * @param extends InventoryItem + */ + @SuppressWarnings("unchecked") + public static + int getColumnViewIndex(final ColumnName id0) { + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final JTable tbl = (id0.toString().substring(0, 4).equals("DECK")) + ? ed.getTableDeck().getTable() + : ed.getTableCatalog().getTable(); + + int index = -1; + + try { + index = tbl.getColumnModel().getColumnIndex(SColumnUtil.getColumn(id0).getIdentifier()); + } + catch (final Exception e) { } + + return index; + } + + /** + * Convenience method to get a column's index in the model (that is, + * in the TableModel, NOT the TableColumnModel). + * + * @param id0   {@link forge.gui.deckeditor.SEditorUtil.CatalogColumnName} + * @return int + * @param extends InventoryItem + * @param extends InventoryItem + */ + @SuppressWarnings("unchecked") + public static + int getColumnModelIndex(final ColumnName id0) { + + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final JTable tbl = (id0.toString().substring(0, 4) == "DECK") + ? ed.getTableDeck().getTable() + : ed.getTableCatalog().getTable(); + + return tbl.getColumn(SColumnUtil.getColumn(id0).getIdentifier()).getModelIndex(); + } + + //========== Display functions + + private static final Pattern AE_FINDER = Pattern.compile("AE", Pattern.LITERAL); + + private static CardManaCost toManaCost(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getManaCost() : CardManaCost.EMPTY; + } + + private static CardColor toColor(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getColor() : CardColor.getNullColor(); + } + + private static Integer toPower(final InventoryItem i) { + Integer result = -1; + if (i instanceof CardPrinted) { + result = ((CardPrinted) i).getCard().getIntPower(); + if (result == null) { + result = Integer.valueOf(((CardPrinted) i).getCard().getLoyalty()); + if (result == null) { result = -1; } + } + } + return result; + } + + private static Integer toToughness(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getIntToughness() : -1; + } + + private static Integer toCMC(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getManaCost().getCMC() : -1; + } + + private static CardRarity toRarity(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getRarity() : CardRarity.Unknown; + } + + private static CardEdition toSetCmp(final InventoryItem i) { + return i instanceof InventoryItemFromSet ? Singletons.getModel().getEditions() + .get(((InventoryItemFromSet) i).getEdition()) : CardEdition.UNKNOWN; + } + + private static String toSetStr(final InventoryItem i) { + return i instanceof InventoryItemFromSet ? ((InventoryItemFromSet) i).getEdition() : "n/a"; + } + + private static Integer toAiCmp(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatusComparable() : Integer.valueOf(-1); + } + + private static String toAiStr(final InventoryItem i) { + return i instanceof CardPrinted ? ((CardPrinted) i).getCard().getAiStatus() : "n/a"; + } + + //========== + + /** Lamda sort fnQtyCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_QTY_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return from.getValue(); + } + }; + + /** Lamda sort fnQtyGet. */ + private static final Lambda1> FN_QTY_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return from.getValue(); + } + }; + + /** Lamda sort fnNameCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_NAME_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return from.getKey().getName(); + } + }; + + /** Lamda sort fnNameGet. */ + private static final Lambda1> FN_NAME_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + final String name = from.getKey().getName(); + return name.contains("AE") ? SColumnUtil.AE_FINDER.matcher(name).replaceAll("\u00C6") : name; + } + }; + + /** Lamda sort fnCostCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_COST_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toManaCost(from.getKey()); + } + }; + + /** Lamda sort fnCostGet. */ + private static final Lambda1> FN_COST_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toManaCost(from.getKey()); + } + }; + + /** Lamda sort fnColorCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_COLOR_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toColor(from.getKey()); + } + }; + + /** Lamda sort fnColorGet. */ + private static final Lambda1> FN_COLOR_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toColor(from.getKey()); + } + }; + + /** Lamda sort fnTypeCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_TYPE_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return from.getKey().getType(); + } + }; + + /** Lamda sort fnTypeGet. */ + private static final Lambda1> FN_TYPE_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return from.getKey().getType(); + } + }; + + /** Lamda sort fnPowerCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_POWER_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toPower(from.getKey()); + } + }; + + /** Lamda sort fnPowerGet. */ + private static final Lambda1> FN_POWER_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toPower(from.getKey()); + } + }; + + /** Lamda sort fnToughnessCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_TOUGHNESS_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toToughness(from.getKey()); + } + }; + + /** Lamda sort fnToughnessGet. */ + private static final Lambda1> FN_TOUGHNESS_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toToughness(from.getKey()); + } + }; + + /** Lamda sort fnCMCCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_CMC_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toCMC(from.getKey()); + } + }; + + /** Lamda sort fnCMCGet. */ + private static final Lambda1> FN_CMC_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toCMC(from.getKey()); + } + }; + + /** Lamda sort fnRarityCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_RARITY_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toRarity(from.getKey()); + } + }; + + /** Lamda sort fnRarityGet. */ + private static final Lambda1> FN_RARITY_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toRarity(from.getKey()); + } + }; + + /** Lamda sort fnSetCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_SET_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toSetCmp(from.getKey()); + } + }; + + /** Lamda sort fnSetGet. */ + private static final Lambda1> FN_SET_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toSetStr(from.getKey()); + } + }; + + /** Lamda sort fnAiStatusCompare. */ + @SuppressWarnings("rawtypes") + private static final Lambda1> FN_AI_STATUS_COMPARE = new Lambda1>() { + @Override + public Comparable apply(final Entry from) { + return SColumnUtil.toAiCmp(from.getKey()); + } + }; + + /** Lamda sort fnAiStatusGet. */ + private static final Lambda1> FN_AI_STATUS_GET = new Lambda1>() { + @Override + public Object apply(final Entry from) { + return SColumnUtil.toAiStr(from.getKey()); + } + }; +} diff --git a/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java b/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java new file mode 100644 index 00000000000..2af9cb02aff --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/TableColumnInfo.java @@ -0,0 +1,142 @@ +/* + * 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.gui.deckeditor.tables; + +import java.util.Map.Entry; + +import javax.swing.table.TableColumn; + +import forge.gui.deckeditor.tables.SColumnUtil.SortState; +import forge.util.closures.Lambda1; + +/** + * A column object in a TableModel in the card editor. + * Requires a sorting function and a display function + * (to extract information as appropriate for table row data). + * + * @param a generic type + */ + +@SuppressWarnings({ "rawtypes", "serial" }) +public class TableColumnInfo extends TableColumn { + private SortState sortstate = SortState.NONE; + private int sortPriority = 0; + private boolean show = true; + private String enumval; + + private Lambda1> fnSort; + private Lambda1> fnDisplay; + + /** */ + public TableColumnInfo() { + super(); + } + + /** + * Unique identifier in SColumnUtil.ColumnName enum. + * + * @return {@link java.lang.String} + */ + public String getEnumValue() { + return enumval; + } + + /** + * Unique identifier in SColumnUtil.ColumnName enum. + * + * @param val0   {@link java.lang.String} + */ + public void setEnumValue(final String val0) { + this.enumval = val0; + } + + /** + * Position in sort cascade, 0 for no priority. + * + * @return int + */ + public int getSortPriority() { + return sortPriority; + } + + /** + * Position in sort cascade, 0 for no priority. + * + * @param position0   int + */ + public void setSortPriority(final int position0) { + this.sortPriority = position0; + } + + /** @return {@link forge.gui.deckeditor.tables.TableModel.SortState} */ + public SortState getSortState() { + return this.sortstate; + } + + /** @param state0   {@link forge.gui.deckeditor.tables.TableColumnInfo.SortState} */ + public void setSortState(final SortState state0) { + this.sortstate = state0; + } + + /** @return boolean */ + public boolean isShowing() { + return this.show; + } + + /** @param boolean0   show/hide this column */ + public void setShowing(final boolean boolean0) { + this.show = boolean0; + } + + /** + * Lambda closure used to sort this column. + * + * @return the fnSort + */ + public Lambda1> getFnSort() { + if (fnSort.equals(null)) { + throw new NullPointerException("A sort function hasn't been set for " + + "Column " + TableColumnInfo.this.getIdentifier()); + } + return this.fnSort; + } + + /** + * Gets the fn display. + * + * @return the fnDisplay + */ + public Lambda1> getFnDisplay() { + if (fnSort.equals(null)) { + throw new NullPointerException("A display function hasn't been set for " + + "Column " + TableColumnInfo.this.getIdentifier()); + } + return this.fnDisplay; + } + + /** + * Lambda closure used to sort this column, and fn display. + * + * @param lambda0 the fnSort + * @param lambda1 the fnDisplay + */ + public void setSortAndDisplayFunctions(final Lambda1> lambda0, final Lambda1> lambda1) { + this.fnSort = lambda0; + this.fnDisplay = lambda1; + } +} diff --git a/src/main/java/forge/gui/deckeditor/tables/TableModel.java b/src/main/java/forge/gui/deckeditor/tables/TableModel.java new file mode 100644 index 00000000000..e9f171a9f10 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/TableModel.java @@ -0,0 +1,373 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 +import forge.gui.deckeditor.views.VDeckEditorUI; +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.gui.deckeditor.tables; + +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.List; +import java.util.Map.Entry; + +import javax.swing.JTable; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.event.TableModelEvent; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumn; +import javax.swing.table.TableColumnModel; + +import org.apache.commons.lang3.ArrayUtils; + +import forge.Card; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.SEditorIO; +import forge.gui.deckeditor.tables.SColumnUtil.ColumnName; +import forge.gui.deckeditor.tables.SColumnUtil.SortState; +import forge.item.CardPrinted; +import forge.item.InventoryItem; +import forge.item.ItemPool; +import forge.item.ItemPoolView; + +/** + *

+ * TableModel class. + *

+ * + * @param + * the generic type + * @author Forge + * @version $Id$ + */ +@SuppressWarnings("serial") +public final class TableModel extends AbstractTableModel { + private final ItemPool data; + private final JTable table; + private final CascadeManager cascadeManager = new CascadeManager(); + private final int maxSortDepth = 3; + + /** + * Instantiates a new table model, using a JTable, + * a column set, and a data set of generic type . + * + * @param table0   {@link javax.swing.JTable} + * @param class0   Generic type + */ + public TableModel(final JTable table0, final Class class0) { + this.table = table0; + this.data = new ItemPool(class0); + } + + /** */ + @SuppressWarnings("unchecked") + public void setup() { + final Enumeration e = table.getColumnModel().getColumns(); + final TableColumn[] sortcols = new TableColumn[table.getColumnCount()]; + + // Assemble priority sort. + while (e.hasMoreElements()) { + final TableColumnInfo col = (TableColumnInfo) e.nextElement(); + + if (col.getSortPriority() > 0) { + sortcols[col.getSortPriority()] = col; + } + } + + final boolean isDeckTable = ((TableColumnInfo) table.getColumnModel() + .getColumn(0)).getEnumValue().substring(0, 4).equals("DECK") + ? true : false; + + if (sortcols[1] == null) { + if (isDeckTable) { + cascadeManager.add((TableColumnInfo) SColumnUtil.getColumn(ColumnName.DECK_NAME)); + } + else { + cascadeManager.add((TableColumnInfo) SColumnUtil.getColumn(ColumnName.CAT_NAME)); + } + } + else { + ArrayUtils.reverse(sortcols); + for (int i = 1; i < sortcols.length; i++) { + if (sortcols[i] != null) { + cascadeManager.add((TableColumnInfo) sortcols[i]); + } + } + } + } + + /** + * Clears all data in the model. + */ + public void clear() { + this.data.clear(); + } + + /** + * Gets all cards in the model. + * + * @return the cards + */ + public ItemPoolView getCards() { + return this.data.getView(); + } + + /** + * Removes a card from the model. + * + * @param card0   {@link forge.Card} object + */ + public void removeCard(final T card0) { + final boolean wasThere = this.data.count(card0) > 0; + if (wasThere) { + this.data.remove(card0); + this.fireTableDataChanged(); + } + } + + /** + * Adds a card to the model. + * + * @param card0   {@link forge.Card} object. + */ + public void addCard(final T card0) { + this.data.add(card0); + this.fireTableDataChanged(); + } + + /** + * Adds multiple copies of multiple cards to the model. + * + * @param cards0   {@link java.lang.Iterable}> + */ + public void addCards(final Iterable> cards0) { + this.data.addAll(cards0); + this.fireTableDataChanged(); + } + + /** + * Row to card. + * + * @param row + * the row + * @return the entry + */ + public Entry rowToCard(final int row) { + final List> model = this.data.getOrderedList(); + return (row >= 0) && (row < model.size()) ? model.get(row) : null; + } + + /** + * Show selected card. + * + * @param table + * the table + */ + public void showSelectedCard(final JTable table) { + final int row = table.getSelectedRow(); + if (row != -1) { + final T cp = this.rowToCard(row).getKey(); + + final Card card2 = cp instanceof CardPrinted ? ((CardPrinted) cp).toForgeCard() : null; + + CDeckEditorUI.SINGLETON_INSTANCE.setCard(card2); + } + } + + /** + *

+ * addListeners. + *

+ */ + public void addListeners() { + // updates card detail, listens to any key strokes + table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + + @Override + public void valueChanged(final ListSelectionEvent arg0) { + TableModel.this.showSelectedCard(table); + } + }); + table.addFocusListener(new FocusListener() { + + @Override + public void focusLost(final FocusEvent e) { + } + + @Override + public void focusGained(final FocusEvent e) { + TableModel.this.showSelectedCard(table); + } + }); + + table.getTableHeader().addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(final MouseEvent e) { + headerClicked(e); + } + + @Override + public void mouseReleased(MouseEvent e) { + SEditorIO.savePreferences(); + } + }); + } // addCardListener() + + /** + * Resort. + */ + public void refreshSort() { + if (this.data.getOrderedList().size() == 0) { return; } + + Collections.sort(this.data.getOrderedList(), new MyComparator()); + } + + @SuppressWarnings("unchecked") + private void headerClicked(final MouseEvent e) { + final TableColumnModel colModel = TableModel.this.table.getColumnModel(); + final int columnModelIndex = colModel.getColumnIndexAtX(e.getX()); + final int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex(); + + if (modelIndex < 0) { + return; + } + + // This will invert if needed + TableModel.this.cascadeManager.add((TableColumnInfo) this.table.getColumnModel().getColumn(modelIndex)); + TableModel.this.refreshSort(); + TableModel.this.table.tableChanged(new TableModelEvent(TableModel.this)); + TableModel.this.table.repaint(); + TableModel.this.table.setRowSelectionInterval(0, 0); + SEditorIO.savePreferences(); + } + + //========== Overridden from AbstractTableModel + /** {@inheritDoc} */ + @Override + public int findColumn(final String name0) { + return table.getColumnModel().getColumnIndex(name0); + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getColumnCount() + */ + @Override + public int getColumnCount() { + return table.getColumnCount(); + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getRowCount() + */ + @Override + public int getRowCount() { + return this.data.countDistinct(); + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getValueAt(int, int) + */ + @Override + @SuppressWarnings("unchecked") + public Object getValueAt(int iRow, int iCol) { + return ((TableColumnInfo) table.getColumnModel().getColumn(table.convertColumnIndexToView(iCol))).getFnDisplay().apply((Entry) this.rowToCard(iRow)); + } + + //========= Custom class handling + + /** + * Manages sorting orders for multiple depths of sorting. + */ + private final class CascadeManager { + private final List> colsToSort = new ArrayList>(3); + private TableSorterCascade sorter = null; + + // Adds a column to sort cascade list. + // If column is first in the cascade, inverts direction of sort. + // Otherwise, sorts in ascending direction. + @SuppressWarnings("unchecked") + public void add(final TableColumnInfo col0) { + // Found at top level, should invert + if (colsToSort.size() > 0 && colsToSort.get(0).equals(col0)) { + this.colsToSort.get(0).setSortState( + this.colsToSort.get(0).getSortState() == SortState.ASC + ? SortState.DESC : SortState.ASC); + this.colsToSort.get(0).setSortPriority(1); + } + // Found somewhere: move down others, this one to top. + else if (colsToSort.contains(col0)) { + col0.setSortState(SortState.ASC); + this.colsToSort.remove(col0); + this.colsToSort.add(0, (TableColumnInfo) col0); + } + // No column in list; add directly. + else { + col0.setSortState(SortState.ASC); + this.colsToSort.add(0, (TableColumnInfo) col0); + this.colsToSort.get(0).setSortPriority(1); + } + + // Decrement sort priority on remaining columns + for (int i = 1; i < maxSortDepth; i++) { + if (colsToSort.size() == i) { break; } + + if (colsToSort.get(i).getSortPriority() != 0) { + colsToSort.get(i).setSortPriority(i + 1); + } + } + + // Unset and remove boundary columns. + if (this.colsToSort.size() > maxSortDepth) { + this.colsToSort.get(maxSortDepth).setSortState(SortState.NONE); + this.colsToSort.get(maxSortDepth).setSortPriority(0); + this.colsToSort.remove(maxSortDepth); + } + } + + public TableSorterCascade getSorter() { + final List> oneColSorters + = new ArrayList>(maxSortDepth); + + for (final TableColumnInfo col : this.colsToSort) { + oneColSorters.add(new TableSorter( + col.getFnSort(), + col.getSortState().equals(SortState.ASC) ? true : false)); + } + + this.sorter = new TableSorterCascade(oneColSorters); + return this.sorter; + } + } + + private class MyComparator implements Comparator> { + /* (non-Javadoc) + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + @SuppressWarnings("unchecked") + @Override + public int compare(Entry o1, Entry o2) { + return TableModel.this.cascadeManager.getSorter().compare( + (Entry) o1, (Entry) o2); + } + } +} // CardTableModel diff --git a/src/main/java/forge/gui/deckeditor/elements/TableSorter.java b/src/main/java/forge/gui/deckeditor/tables/TableSorter.java similarity index 98% rename from src/main/java/forge/gui/deckeditor/elements/TableSorter.java rename to src/main/java/forge/gui/deckeditor/tables/TableSorter.java index 9504a987fee..620ee1ddccf 100644 --- a/src/main/java/forge/gui/deckeditor/elements/TableSorter.java +++ b/src/main/java/forge/gui/deckeditor/tables/TableSorter.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.util.Comparator; import java.util.Map.Entry; diff --git a/src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java b/src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java similarity index 95% rename from src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java rename to src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java index 9165df95145..83614cd00eb 100644 --- a/src/main/java/forge/gui/deckeditor/elements/TableSorterCascade.java +++ b/src/main/java/forge/gui/deckeditor/tables/TableSorterCascade.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.util.Comparator; import java.util.List; diff --git a/src/main/java/forge/gui/deckeditor/elements/TableView.java b/src/main/java/forge/gui/deckeditor/tables/TableView.java similarity index 52% rename from src/main/java/forge/gui/deckeditor/elements/TableView.java rename to src/main/java/forge/gui/deckeditor/tables/TableView.java index bb588a1d2d5..32fbd4043cc 100644 --- a/src/main/java/forge/gui/deckeditor/elements/TableView.java +++ b/src/main/java/forge/gui/deckeditor/tables/TableView.java @@ -15,24 +15,23 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge.gui.deckeditor.elements; +package forge.gui.deckeditor.tables; import java.awt.Color; +import java.util.ArrayList; import java.util.List; -import javax.swing.BorderFactory; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JScrollPane; import javax.swing.JTable; -import javax.swing.border.TitledBorder; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; -import javax.swing.table.TableCellRenderer; +import javax.swing.table.DefaultTableColumnModel; +import javax.swing.table.TableColumn; - -import forge.Constant; import forge.card.CardRules; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.views.ITableContainer; +import forge.gui.toolbox.FSkin; +import forge.item.CardPrinted; import forge.item.InventoryItem; import forge.item.ItemPool; import forge.item.ItemPoolView; @@ -45,44 +44,14 @@ import forge.util.closures.Predicate; * the generic type */ public final class TableView { - - /** The pool. */ private ItemPool pool; - - /** The model. */ private TableModel model; - - /** The table. */ private final JTable table = new JTable(); - - /** The j scroll pane. */ - private final JScrollPane jScrollPane = new JScrollPane(); - - /** The stats label. */ - private final JLabel statsLabel = new JLabel(); - - /** The filter. */ private Predicate filter = null; - - /** The is tracking stats. */ - private boolean isTrackingStats = false; - - /** The want unique. */ private boolean wantUnique = false; private final Class genericType; - // need this to allow users place its contents - /** - * - * getTableDecorated. - * - * @return JComponent - */ - public JComponent getTableDecorated() { - return this.jScrollPane; - } - /** * * getTable. @@ -93,149 +62,104 @@ public final class TableView { return this.table; } - /** - * - * getLabel. - * - * @return JComponent - */ - public JComponent getLabel() { - return this.statsLabel; - } - /** * TableWithCards. * - * @param title - * a String - * @param showStats - * a boolean * @param cls * the cls */ - public TableView(final String title, final boolean showStats, final Class cls) { - this(title, showStats, false, cls); + public TableView(final Class cls) { + this(false, cls); } /** * TableWithCards Constructor. * - * @param title - * a String - * @param showStats - * a boolean * @param forceUnique * a boolean - * @param cls - * the cls + * @param type0 the cls */ - public TableView(final String title, final boolean showStats, final boolean forceUnique, final Class cls) { - // components - this.genericType = cls; - - final Color gray = new Color(148, 145, 140); - final TitledBorder titledBorder = new TitledBorder(BorderFactory.createEtchedBorder(Color.white, gray), title); - - final String tableToolTip = "Click on the column name (like name or color) to sort the cards"; - this.jScrollPane.setBorder(titledBorder); - this.jScrollPane.setToolTipText(tableToolTip); - this.jScrollPane.getViewport().add(this.table, null); - - this.statsLabel.setFont(new java.awt.Font("Dialog", 0, 13)); - this.statsLabel.setText("Total: 0, Creatures: 0, Land: 0"); - - // class data - this.isTrackingStats = showStats; + public TableView(final boolean forceUnique, final Class type0) { + this.genericType = type0; this.wantUnique = forceUnique; + + table.setFont(FSkin.getFont(12)); + table.setBorder(null); + table.getTableHeader().setBorder(null); + table.setRowHeight(18); } /** + * Applies a TableModel and a model listener to this instance's JTable. * - * setup. - * - * @param columns - * a List> - * @param cardView - * a CardPanelBase + * @param view0   the {@link javax.gui.deckeditor.views.ITableCOntainer} + * @param cols0   List> of additional columns for this */ - public void setup(final List> columns, final CardPanelBase cardView) { - this.model = new TableModel(cardView, columns, this.genericType); - this.model.addListeners(this.table); - this.table.setModel(this.model); - this.model.resizeCols(this.table); + @SuppressWarnings("unchecked") + public void setup(final ITableContainer view0, final List> cols0) { + final DefaultTableColumnModel colmodel = new DefaultTableColumnModel(); - for (int idx = columns.size() - 1; idx >= 0; idx--) { - final TableCellRenderer renderer = columns.get(idx).getCellRenderer(); - if (null != renderer) { - this.table.getColumnModel().getColumn(idx).setCellRenderer(renderer); + // Add columns whose indices are inside the view indices, as long as there's not one there already. + final TableColumn[] knownCols = new TableColumn[cols0.size()]; + final List unknownCols = new ArrayList(); + + for (final TableColumn c : cols0) { + if (!((TableColumnInfo) c).isShowing()) { continue; } + if (c.getModelIndex() < knownCols.length && knownCols[c.getModelIndex()] == null) { + knownCols[c.getModelIndex()] = c; + } + else { + unknownCols.add(c); } } - if (this.isTrackingStats) { - // get stats from deck - this.model.addTableModelListener(new TableModelListener() { - @Override - public void tableChanged(final TableModelEvent ev) { - final ItemPoolView deck = TableView.this.model.getCards(); - TableView.this.statsLabel.setText(TableView.getStats(deck)); + // Columns outside the bounds of the view indices must be + // resolved by inserting into empty slots. + for (final TableColumn c : unknownCols) { + for (int i = 0; i < knownCols.length; i++) { + if (knownCols[i] == null) { + knownCols[i] = c; + break; } - }); - } - } - - // This should not be here, but still found no better place - /** - * getStats. - * - * @param - * the generic type - * @param deck - * an ItemPoolView - * @return String - */ - public static String getStats(final ItemPoolView deck) { - final int total = deck.countAll(); - final int creature = CardRules.Predicates.Presets.IS_CREATURE.aggregate(deck, deck.getFnToCard(), - deck.getFnToCount()); - final int land = CardRules.Predicates.Presets.IS_LAND.aggregate(deck, deck.getFnToCard(), deck.getFnToCount()); - - final StringBuffer show = new StringBuffer(); - show.append("Total - ").append(total).append(", Creatures - ").append(creature).append(", Land - ") - .append(land); - final String[] color = Constant.Color.ONLY_COLORS; - final List> predicates = CardRules.Predicates.Presets.COLORS; - for (int i = 0; i < color.length; ++i) { - show.append(String.format(", %s - %d", color[i], predicates.get(i).count(deck, deck.getFnToCard()))); + } } - return show.toString(); - } // getStats() + // Put columns into model in preferred order (much easier than moving dynamically). + for (final TableColumn c : knownCols) { + if (c == null) { continue; } + c.setMinWidth(15); + c.setPreferredWidth(c.getPreferredWidth()); + c.setMaxWidth(350); + colmodel.addColumn(c); + } - /** - * - * sort. - * - * @param iCol - * an int - * @return TableWithCards - */ - public TableView sort(final int iCol) { - return this.sort(iCol, true); - } + this.model = new TableModel(this.table, this.genericType); + this.model.addListeners(); + this.table.setModel(this.model); + this.table.setColumnModel(colmodel); - /** - * - * sort. - * - * @param iCol - * an int - * @param isAsc - * a boolean - * @return TableWithCards - */ - public TableView sort(final int iCol, final boolean isAsc) { - this.model.sort(iCol, isAsc); - return this; + this.model.setup(); + this.model.refreshSort(); + + this.table.getTableHeader().setBackground(new Color(200, 200, 200)); + + // Update stats each time table changes + this.model.addTableModelListener(new TableModelListener() { + @Override + public void tableChanged(final TableModelEvent ev) { + final List deck = TableView.this.model.getCards().toFlatList(); + final ItemPool filteredDeck = new ItemPool((Class) CardPrinted.class); + + // Filter out non-card items (booster packs, etc.) + for (T item : deck) { + if (item instanceof CardPrinted) { + filteredDeck.add(item); + } + } + + SEditorUtil.setStats(filteredDeck, view0); + } + }); } /** @@ -388,7 +312,7 @@ public final class TableView { this.model.addCards(this.pool); } - this.model.resort(); + this.model.refreshSort(); } /** diff --git a/src/main/java/forge/gui/deckeditor/tables/package-info.java b/src/main/java/forge/gui/deckeditor/tables/package-info.java new file mode 100644 index 00000000000..5eccba35a34 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/tables/package-info.java @@ -0,0 +1,3 @@ +/** Forge Card Game. */ +package forge.gui.deckeditor.tables; + diff --git a/src/main/java/forge/gui/deckeditor/views/ITableContainer.java b/src/main/java/forge/gui/deckeditor/views/ITableContainer.java new file mode 100644 index 00000000000..f96d1ba5923 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/ITableContainer.java @@ -0,0 +1,65 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JLabel; +import javax.swing.JTable; + +/** + * Dictates methods needed for a class to act as a container for + * a TableView deck editing component. + * + *

(I at beginning of class name denotes an interface.) + * + */ +public interface ITableContainer { + /** + * Sets the table used for displaying cards in this + * deck editor container. + * + * @param tbl0   {@link forge.gui.deckeditor.tables.TableView} + */ + void setTableView(JTable tbl0); + + // Various card count total labels + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblTotal(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblBlack(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblBlue(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblGreen(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblRed(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblWhite(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblColorless(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblArtifact(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblEnchantment(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblCreature(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblSorcery(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblInstant(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblPlaneswalker(); + + /** @return {@link javax.swing.JLabel} */ + JLabel getLblLand(); +} diff --git a/src/main/java/forge/gui/deckeditor/views/VAllDecks.java b/src/main/java/forge/gui/deckeditor/views/VAllDecks.java new file mode 100644 index 00000000000..b09ee29308e --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VAllDecks.java @@ -0,0 +1,110 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JLabel; +import javax.swing.JScrollPane; + +import net.miginfocom.swing.MigLayout; +import forge.game.GameType; +import forge.gui.deckeditor.controllers.CAllDecks; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.DeckLister; +import forge.gui.toolbox.FLabel; + +/** + * Assembles Swing components of all deck viewer in deck editor. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VAllDecks implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("All Decks"); + + private final DeckLister lstDecks = new DeckLister(GameType.Constructed); + private JScrollPane scroller = new JScrollPane(lstDecks); + + private final JLabel btnImport = new FLabel.Builder() + .fontSize(14) + .text("Import Deck").tooltip("Attempt to import a deck from a non-Forge format") + .opaque(true).hoverable(true).build(); + + //========== Constructor + private VAllDecks() { + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_ALLDECKS; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CAllDecks.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap, ax center")); + + parentCell.getBody().add(btnImport, "w 120px!, h 30px!, gap 0 0 5px 5px"); + + //parentCell.getBody().add(scroller, "w 96%!, h 96%!, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JPanel} */ + public DeckLister getLstDecks() { + return lstDecks; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnImport() { + return btnImport; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java b/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java new file mode 100644 index 00000000000..4f7c879d519 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VCardCatalog.java @@ -0,0 +1,315 @@ +package forge.gui.deckeditor.views; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.controllers.CCardCatalog; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; + +/** + * Assembles Swing components of card catalog in deck editor. + * + *

(V at beginning of class name denotes a view class.) + * + */ +public enum VCardCatalog implements IVDoc, ITableContainer { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Card Catalog"); + + // Total and color count labels + private final JPanel pnlStats = new JPanel(); + private final JLabel lblTotal = buildLabel(SEditorUtil.ICO_TOTAL); + private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK); + private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE); + private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN); + private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED); + private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE); + private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS); + + // Card type labels + private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT); + private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE); + private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT); + private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT); + private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND); + private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER); + private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY); + + private final JLabel lblTitle = new FLabel.Builder() + .fontSize(14).build(); + + private final JPanel pnlHeader = new JPanel(new MigLayout("insets 0, gap 0")); + + private final JPanel pnlAddButtons = + new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); + + private final JLabel btnAdd = new FLabel.Builder() + .fontSize(14) + .text("Add card") + .tooltip("Add selected card to current deck (or double click the row)") + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PLUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private final JLabel btnAdd4 = new FLabel.Builder() + .fontSize(14) + .text("Add 4 of card") + .tooltip("Add up to 4 of selected card to current deck") + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_PLUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private JTable tblCards = null; + private final JScrollPane scroller = new JScrollPane(); + + //========== Constructor + /** */ + private VCardCatalog() { + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + + lblTotal.setToolTipText("Total Card Count"); + lblBlack.setToolTipText("Black Card Count"); + lblBlue.setToolTipText("Blue Card Count"); + lblGreen.setToolTipText("Green Card Count"); + lblRed.setToolTipText("Red Card Count"); + lblWhite.setToolTipText("White Card Count"); + lblColorless.setToolTipText("Total Card Count"); + lblArtifact.setToolTipText("Artifact Card Count"); + lblCreature.setToolTipText("Creature Card Count"); + lblColorless.setToolTipText("Colorless Card Count"); + lblEnchantment.setToolTipText("Enchantment Card Count"); + lblInstant.setToolTipText("Instant Card Count"); + lblLand.setToolTipText("Land Card Count"); + lblPlaneswalker.setToolTipText("Planeswalker Card Count"); + lblSorcery.setToolTipText("Sorcery Card Count"); + + pnlStats.setOpaque(false); + pnlStats.setLayout(new MigLayout("insets 0, gap 5px, ax center, wrap 7")); + + final String constraints = "w 55px!, h 20px!"; + pnlStats.add(lblTotal, constraints); + pnlStats.add(lblBlack, constraints); + pnlStats.add(lblBlue, constraints); + pnlStats.add(lblGreen, constraints); + pnlStats.add(lblRed, constraints); + pnlStats.add(lblWhite, constraints); + pnlStats.add(lblColorless, constraints); + + pnlStats.add(lblArtifact, constraints); + pnlStats.add(lblCreature, constraints); + pnlStats.add(lblEnchantment, constraints); + pnlStats.add(lblInstant, constraints); + pnlStats.add(lblLand, constraints); + pnlStats.add(lblPlaneswalker, constraints); + pnlStats.add(lblSorcery, constraints); + + pnlAddButtons.setOpaque(false); + pnlAddButtons.add(btnAdd, "w 42%!, h 30px!, gap 0 0 5px 5px"); + pnlAddButtons.add(btnAdd4, "w 42%!, h 30px!, gap 5% 5% 5px 5px"); + + pnlHeader.setOpaque(false); + pnlHeader.add(lblTitle, "w 100%!, h 100%!"); + } + + //========== Overridden from IVDoc + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_CATALOG; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CCardCatalog.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3")); + parentCell.getBody().add(pnlHeader, "w 98%!, h 30px!, gap 1% 0 1% 10px"); + parentCell.getBody().add(pnlStats, "w 96%, h 50px!, gap 2% 0 1% 1%"); + parentCell.getBody().add(pnlAddButtons, "w 96%!, gap 2% 0 0 0"); + parentCell.getBody().add(scroller, "w 98%!, h 100% - 35px, gap 1% 0 1% 1%"); + } + + //========== Overridden from ITableContainer + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#setTableView() + */ + @Override + public void setTableView(final JTable tbl0) { + this.tblCards = tbl0; + scroller.setViewportView(tblCards); + } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblTotal() + */ + @Override + public JLabel getLblTotal() { return lblTotal; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlack() + */ + @Override + public JLabel getLblBlack() { return lblBlack; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlue() + */ + @Override + public JLabel getLblBlue() { return lblBlue; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblGreen() + */ + @Override + public JLabel getLblGreen() { return lblGreen; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblRed() + */ + @Override + public JLabel getLblRed() { return lblRed; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblWhite() + */ + @Override + public JLabel getLblWhite() { return lblWhite; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblColorless() + */ + @Override + public JLabel getLblColorless() { return lblColorless; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblArtifact() + */ + @Override + public JLabel getLblArtifact() { return lblArtifact; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblEnchantment() + */ + @Override + public JLabel getLblEnchantment() { return lblEnchantment; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblCreature() + */ + @Override + public JLabel getLblCreature() { return lblCreature; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblSorcery() + */ + @Override + public JLabel getLblSorcery() { return lblSorcery; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblInstant() + */ + @Override + public JLabel getLblInstant() { return lblInstant; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblPlaneswalker() + */ + @Override + public JLabel getLblPlaneswalker() { return lblPlaneswalker; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblLand() + */ + @Override + public JLabel getLblLand() { return lblLand; } + + //========== Accessor/mutator methods + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblTitle() { + return lblTitle; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnAdd() { + return btnAdd; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnAdd4() { + return btnAdd4; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlHeader() { + return pnlHeader; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStats() { + return pnlStats; + } + + //========== Other methods + + private JLabel buildLabel(final ImageIcon icon0) { + final JLabel lbl = new FLabel.Builder().text("0") + .icon(icon0).iconScaleAuto(false) + .fontSize(11) + .build(); + + return lbl; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java b/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java new file mode 100644 index 00000000000..1c3e7c4c73a --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VCurrentDeck.java @@ -0,0 +1,406 @@ +package forge.gui.deckeditor.views; + +import java.awt.Insets; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.SwingConstants; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.controllers.CCurrentDeck; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; +import forge.gui.toolbox.FTextField; + + +/** + * Assembles Swing components of current deck being edited in deck editor. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VCurrentDeck implements IVDoc, ITableContainer { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Current Deck"); + + // Other fields + + private final JLabel btnSave = new FLabel.Builder() + .fontSize(14) + .tooltip("Save (in default directory)") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVE)) + .text(" ").hoverable(true).build(); + + private final JLabel btnExport = new FLabel.Builder() + .fontSize(14) + .tooltip("Save As") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_SAVEAS)) + .text(" ").hoverable(true).build(); + + private final JLabel btnImport = new FLabel.Builder() + .fontSize(14) + .tooltip("Load") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_OPEN)) + .text(" ").hoverable(true).build(); + + private final JLabel btnNew = new FLabel.Builder() + .fontSize(14) + .tooltip("New Deck") + .iconInBackground(true) + .iconAlignX(SwingConstants.CENTER).iconAlpha(1.0f) + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_NEW)) + .text(" ").hoverable(true).build(); + + private final JPanel pnlRemoveButtons = + new JPanel(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); + + private final JLabel btnRemove = new FLabel.Builder() + .fontSize(14) + .text("Remove card") + .tooltip("Remove selected card to current deck (or double click the row)") + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private final JLabel btnRemove4 = new FLabel.Builder() + .fontSize(14) + .text("Remove 4 of card") + .tooltip("Remove up to 4 of selected card to current deck") + .icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_MINUS)) + .iconScaleAuto(false).hoverable(true).build(); + + private final JTextField txfTitle = new FTextField(); + + private final JPanel pnlRemove = new JPanel(); + private final JPanel pnlHeader = new JPanel(); + + private final JLabel lblTitle = new FLabel.Builder().text("Title") + .fontSize(14).build(); + + private final JPanel pnlStats = new JPanel(); + private final JLabel lblTotal = buildLabel(SEditorUtil.ICO_TOTAL); + private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK); + private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE); + private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN); + private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED); + private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE); + private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS); + + private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT); + private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE); + private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT); + private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT); + private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND); + private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER); + private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY); + + private JTable tblCards = null; + private final JScrollPane scroller = new JScrollPane(tblCards); + + //========== Constructor + + private VCurrentDeck() { + // Title text area + txfTitle.setText("[New Deck]"); + txfTitle.setMargin(new Insets(5, 5, 5, 5)); + txfTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + txfTitle.setOpaque(true); + txfTitle.setEditable(true); + txfTitle.setFocusable(true); + txfTitle.setOpaque(true); + txfTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + // Header area + pnlHeader.setOpaque(false); + pnlHeader.setLayout(new MigLayout("insets 0, gap 0, ax center, hidemode 3")); + + pnlHeader.add(lblTitle, "w 80px!, h 30px!, gap 5px 5px 0 0"); + pnlHeader.add(txfTitle, "pushx, growx, gap 0 5px 0 0"); + pnlHeader.add(btnSave, "w 26px!, h 26px!, gap 0 5px 0 0"); + pnlHeader.add(btnNew, "w 26px!, h 26px!, gap 0 5px 0 0"); + + pnlHeader.add(btnImport, "w 26px!, h 26px!, gap 0 5px 0 0"); + pnlHeader.add(btnExport, "w 26px!, h 26px!, gap 0 20px 0 0"); + + pnlRemove.setOpaque(false); + pnlRemove.setLayout(new MigLayout("insets 0, gap 0, ax center")); + pnlRemove.add(btnRemove, "w 40%!, h 100%!, gap 5% 5% 0 0"); + pnlRemove.add(btnRemove4, "w 40%!, h 100%!"); + + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + + lblTotal.setToolTipText("Total Card Count"); + lblBlack.setToolTipText("Black Card Count"); + lblBlue.setToolTipText("Blue Card Count"); + lblGreen.setToolTipText("Green Card Count"); + lblRed.setToolTipText("Red Card Count"); + lblWhite.setToolTipText("White Card Count"); + lblColorless.setToolTipText("Total Card Count"); + lblArtifact.setToolTipText("Artifact Card Count"); + lblCreature.setToolTipText("Creature Card Count"); + lblColorless.setToolTipText("Colorless Card Count"); + lblEnchantment.setToolTipText("Enchantment Card Count"); + lblInstant.setToolTipText("Instant Card Count"); + lblLand.setToolTipText("Land Card Count"); + lblPlaneswalker.setToolTipText("Planeswalker Card Count"); + lblSorcery.setToolTipText("Sorcery Card Count"); + + pnlStats.setOpaque(false); + pnlStats.setLayout(new MigLayout("insets 0, gap 5px, ax center, wrap 7")); + + final String constraints = "w 55px!, h 20px!"; + pnlStats.add(lblTotal, constraints); + pnlStats.add(lblBlack, constraints); + pnlStats.add(lblBlue, constraints); + pnlStats.add(lblGreen, constraints); + pnlStats.add(lblRed, constraints); + pnlStats.add(lblWhite, constraints); + pnlStats.add(lblColorless, constraints); + + pnlStats.add(lblArtifact, constraints); + pnlStats.add(lblCreature, constraints); + pnlStats.add(lblEnchantment, constraints); + pnlStats.add(lblInstant, constraints); + pnlStats.add(lblLand, constraints); + pnlStats.add(lblPlaneswalker, constraints); + pnlStats.add(lblSorcery, constraints); + + pnlRemoveButtons.setOpaque(false); + pnlRemoveButtons.add(btnRemove, "w 42%!, h 30px!, gap 0 0 5px 5px"); + pnlRemoveButtons.add(btnRemove4, "w 42%!, h 30px!, gap 5% 5% 5px 5px"); + } + + //========== Overridden from IVDoc + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_CURRENTDECK; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CCurrentDeck.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + final JPanel pnl = parentCell.getBody(); + pnl.setLayout(new MigLayout("insets 0, gap 0, wrap, hidemode 3")); + + parentCell.getBody().add(pnlHeader, "w 98%!, h 30px!, gap 1% 0 1% 10px"); + parentCell.getBody().add(pnlStats, "w 96%, h 50px!, gap 2% 0 1% 1%"); + parentCell.getBody().add(pnlRemoveButtons, "w 96%!, gap 2% 0 0 0"); + parentCell.getBody().add(scroller, "w 98%!, h 100% - 35px, gap 1% 0 1% 1%"); + } + + //========== Retrieval methods + + //========== Custom class handling + + //========== Overridden from ITableContainer + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#setTableView() + */ + @Override + public void setTableView(final JTable tbl0) { + this.tblCards = tbl0; + scroller.setViewportView(tblCards); + } + + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblTotal() + */ + @Override + public JLabel getLblTotal() { return lblTotal; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlack() + */ + @Override + public JLabel getLblBlack() { return lblBlack; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblBlue() + */ + @Override + public JLabel getLblBlue() { return lblBlue; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblGreen() + */ + @Override + public JLabel getLblGreen() { return lblGreen; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblRed() + */ + @Override + public JLabel getLblRed() { return lblRed; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblWhite() + */ + @Override + public JLabel getLblWhite() { return lblWhite; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblColorless() + */ + @Override + public JLabel getLblColorless() { return lblColorless; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblArtifact() + */ + @Override + public JLabel getLblArtifact() { return lblArtifact; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblEnchantment() + */ + @Override + public JLabel getLblEnchantment() { return lblEnchantment; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblCreature() + */ + @Override + public JLabel getLblCreature() { return lblCreature; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblSorcery() + */ + @Override + public JLabel getLblSorcery() { return lblSorcery; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblInstant() + */ + @Override + public JLabel getLblInstant() { return lblInstant; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblPlaneswalker() + */ + @Override + public JLabel getLblPlaneswalker() { return lblPlaneswalker; } + + /* (non-Javadoc) + * @see forge.gui.deckeditor.views.ITableContainer#getLblLand() + */ + @Override + public JLabel getLblLand() { return lblLand; } + + //========== Retrieval + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRemove() { + return btnRemove; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRemove4() { + return btnRemove4; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnSave() { + return btnSave; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnSaveAs() { + return btnExport; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnOpen() { + return btnImport; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnNew() { + return btnNew; + } + + /** @return {@link javax.swing.JTextField} */ + public JTextField getTxfTitle() { + return txfTitle; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlHeader() { + return pnlHeader; + } + + /** @return {@link javax.swing.JPanel} */ + public JPanel getPnlStats() { + return pnlStats; + } + + //========== Other methods + + private JLabel buildLabel(final ImageIcon icon0) { + final JLabel lbl = new FLabel.Builder().text("0") + .icon(icon0).iconScaleAuto(false) + .fontSize(11) + .build(); + + return lbl; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VDeckgen.java b/src/main/java/forge/gui/deckeditor/views/VDeckgen.java new file mode 100644 index 00000000000..55e89715cca --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VDeckgen.java @@ -0,0 +1,128 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JLabel; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.controllers.CDeckgen; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VDeckgen implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Deck Generation"); + + // Deckgen buttons + private final JLabel btnRandCardpool = new FLabel.Builder() + .tooltip("Generate random constructed cardpool in current deck area") + .text("Random Cardpool").fontSize(14) + .opaque(true).hoverable(true).build(); + + private final JLabel btnRandDeck2 = new FLabel.Builder() + .tooltip("Generate 2 color constructed deck in current deck area") + .text("Constructed (2 color)").fontSize(14) + .opaque(true).hoverable(true).build(); + + private final JLabel btnRandDeck3 = new FLabel.Builder() + .tooltip("Generate 3 color constructed deck in current deck area") + .text("Constructed (3 color)").fontSize(14) + .opaque(true).hoverable(true).build(); + + private final JLabel btnRandDeck5 = new FLabel.Builder() + .tooltip("Generate 5 color constructed deck in current deck area") + .text("Constructed (5 color)").fontSize(14) + .opaque(true).hoverable(true).build(); + + //========== Constructor + private VDeckgen() { + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_DECKGEN; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CDeckgen.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap, ax center")); + + final String constraints = "w 80%!, h 30px!, gap 0 0 10px 0"; + parentCell.getBody().add(btnRandCardpool, constraints); + parentCell.getBody().add(btnRandDeck2, constraints); + parentCell.getBody().add(btnRandDeck3, constraints); + parentCell.getBody().add(btnRandDeck5, constraints); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandCardpool() { + return btnRandCardpool; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandDeck2() { + return btnRandDeck2; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandDeck3() { + return btnRandDeck3; + } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getBtnRandDeck5() { + return btnRandDeck5; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java b/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java new file mode 100644 index 00000000000..ee0d54e576a --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VEditorPreferences.java @@ -0,0 +1,225 @@ +package forge.gui.deckeditor.views; + +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.border.MatteBorder; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.controllers.CEditorPreferences; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FCheckBox; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VEditorPreferences implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Preferences"); + + private JLabel lblStats = new FLabel.Builder() + .text("Stat Bars").tooltip("Toggle statistics bars") + .fontSize(12).build(); + + private JLabel lblCatalog = new FLabel.Builder() + .text("Card Catalog Columns").tooltip("Toggle columns in card catalog panel") + .fontSize(12).build(); + + private JLabel lblDeck = new FLabel.Builder() + .text("Current Deck Columns").tooltip("Toggle columns in current deck panel") + .fontSize(12).build(); + + private JCheckBox chbCatalogColor = new FCheckBox("Color"); + private JCheckBox chbCatalogRarity = new FCheckBox("Rarity"); + private JCheckBox chbCatalogCMC = new FCheckBox("CMC"); + private JCheckBox chbCatalogSet = new FCheckBox("Set"); + private JCheckBox chbCatalogAI = new FCheckBox("AI"); + + private JCheckBox chbDeckColor = new FCheckBox("Color"); + private JCheckBox chbDeckRarity = new FCheckBox("Rarity"); + private JCheckBox chbDeckCMC = new FCheckBox("CMC"); + private JCheckBox chbDeckSet = new FCheckBox("Set"); + private JCheckBox chbDeckAI = new FCheckBox("AI"); + + private JCheckBox chbDeckStats = new FCheckBox("Show stats in current deck"); + private JCheckBox chbCatalogStats = new FCheckBox("Show stats in card catalog"); + + private JPanel pnl = new JPanel(new MigLayout("insets 0, gap 0, wrap 2, ax center")); + private JScrollPane scroller = new JScrollPane(pnl); + + //========== Constructor + private VEditorPreferences() { + lblStats.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblCatalog.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblDeck.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + + chbCatalogColor.setFont(FSkin.getFont(12)); + chbCatalogRarity.setFont(FSkin.getFont(12)); + chbCatalogCMC.setFont(FSkin.getFont(12)); + chbCatalogSet.setFont(FSkin.getFont(12)); + chbCatalogAI.setFont(FSkin.getFont(12)); + + chbDeckColor.setFont(FSkin.getFont(12)); + chbDeckRarity.setFont(FSkin.getFont(12)); + chbDeckCMC.setFont(FSkin.getFont(12)); + chbDeckSet.setFont(FSkin.getFont(12)); + chbDeckAI.setFont(FSkin.getFont(12)); + + chbDeckStats.setFont(FSkin.getFont(12)); + chbCatalogStats.setFont(FSkin.getFont(12)); + chbDeckStats.setSelected(true); + chbCatalogStats.setSelected(true); + + pnl.add(lblStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1"); + pnl.add(chbCatalogStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1"); + pnl.add(chbDeckStats, "h 25px!, gap 5px 5px 5px 5px, ax center, span 2 1"); + + final String constraints = "w 75px, h 25px!, gap 5px 5px 5px 5px, ax center"; + pnl.add(lblCatalog, constraints + ", span 2 1"); + pnl.add(chbCatalogColor, constraints); + pnl.add(chbCatalogRarity, constraints); + pnl.add(chbCatalogCMC, constraints); + pnl.add(chbCatalogSet, constraints); + pnl.add(chbCatalogAI, constraints + ", wrap"); + + pnl.add(lblDeck, constraints + ", span 2 1"); + pnl.add(chbDeckColor, constraints); + pnl.add(chbDeckRarity, constraints); + pnl.add(chbDeckCMC, constraints); + pnl.add(chbDeckSet, constraints); + pnl.add(chbDeckAI, constraints); + + pnl.setOpaque(false); + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_PREFERENCES; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CEditorPreferences.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap")); + parentCell.getBody().add(scroller, "w 96%!, h 96%, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogColor() { + return chbCatalogColor; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogRarity() { + return chbCatalogRarity; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogCMC() { + return chbCatalogCMC; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogSet() { + return chbCatalogSet; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogAI() { + return chbCatalogAI; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckColor() { + return chbDeckColor; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckRarity() { + return chbDeckRarity; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckCMC() { + return chbDeckCMC; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckSet() { + return chbDeckSet; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckAI() { + return chbDeckAI; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbDeckStats() { + return chbDeckStats; + } + + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getChbCatalogStats() { + return chbCatalogStats; + } + //========== Other methods + +} diff --git a/src/main/java/forge/gui/deckeditor/views/VFilters.java b/src/main/java/forge/gui/deckeditor/views/VFilters.java new file mode 100644 index 00000000000..365ace3b37e --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VFilters.java @@ -0,0 +1,306 @@ +package forge.gui.deckeditor.views; + +import java.awt.Insets; + +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.border.MatteBorder; + +import net.miginfocom.swing.MigLayout; +import forge.Singletons; +import forge.card.CardEdition; +import forge.game.GameFormat; +import forge.gui.deckeditor.SFilterUtil; +import forge.gui.deckeditor.controllers.CFilters; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; +import forge.gui.toolbox.FTextField; + +/** + * Assembles Swing components of deck editor filter tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VFilters implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Filters"); + + // Text filter components + private final JTextField txfContains = new FTextField(); + private final JTextField txfWithout = new FTextField(); + private final JLabel lblContains = new FLabel.Builder() + .text("Contains:").fontSize(14).build(); + private final JLabel lblWithout = new FLabel.Builder() + .text("Without:").fontSize(14).build(); + + // Interval filter components + private final JComboBox cbxSets = new JComboBox(); + private final JComboBox cbxPLow = new JComboBox(); + private final JComboBox cbxPHigh = new JComboBox(); + private final JComboBox cbxTLow = new JComboBox(); + private final JComboBox cbxTHigh = new JComboBox(); + private final JComboBox cbxCMCLow = new JComboBox(); + private final JComboBox cbxCMCHigh = new JComboBox(); + + private final JLabel lblP = new FLabel.Builder() + .fontSize(12).text(" <= Power <= ").build(); + + private final JLabel lblT = new FLabel.Builder() + .fontSize(12).text(" <= Toughness <= ").build(); + + private final JLabel lblCMC = new FLabel.Builder() + .fontSize(12).text(" <= CMC <= ").build(); + + // Title labels + private final JLabel lblProperties = new FLabel.Builder() + .text("Properties").tooltip("Filter by color, type, set, or format. Click to toggle.") + .hoverable(true).fontSize(14).build(); + + private final JLabel lblText = new FLabel.Builder() + .text("Card Text").tooltip("Filter by card name, type, and text, space delimited. Click to reset.") + .hoverable(true).fontSize(14).build(); + + private final JLabel lblIntervals = new FLabel.Builder() + .text("Intervals").tooltip("Filter by power, toughness, or converted mana cost. Click to reset.") + .hoverable(true).fontSize(14).build(); + + // Container components + private final JPanel pnlText = new JPanel(new MigLayout( + "insets 0, gap 0, wrap 2, ax center")); + private final JPanel pnlIntervals = new JPanel(new MigLayout( + "insets 0, gap 0, wrap 3, ax center")); + + private JPanel pnlContainer = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + private JScrollPane scroller = new JScrollPane(pnlContainer); + + //========== Constructor + private VFilters() { + String constraints = ""; + + // Sets/formats combo box + cbxSets.addItem("All sets and formats"); + for (final GameFormat s : Singletons.getModel().getFormats()) { + cbxSets.addItem(s); + } + for (final CardEdition s : Singletons.getModel().getEditions()) { + cbxSets.addItem(s); + } + + // Color/type searches + lblProperties.setBorder(new MatteBorder(0, 0, 1, 0, + FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblText.setBorder(new MatteBorder(0, 0, 1, 0, + FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblIntervals.setBorder(new MatteBorder(0, 0, 1, 0, + FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + + // Text search + txfContains.setMargin(new Insets(5, 5, 5, 5)); + txfContains.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + txfContains.setOpaque(true); + txfContains.setEditable(true); + txfContains.setFocusable(true); + txfContains.setOpaque(true); + txfContains.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + txfWithout.setMargin(new Insets(5, 5, 5, 5)); + txfWithout.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + txfWithout.setOpaque(true); + txfWithout.setEditable(true); + txfWithout.setFocusable(true); + txfWithout.setOpaque(true); + txfWithout.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + + pnlText.setOpaque(false); + pnlText.add(lblText, "w 210px!, span 2 1, h 25px!"); + pnlText.add(lblContains, "w 80px!, h 30px!"); + pnlText.add(txfContains, "pushx, growx, gap 5px 5px 2px 2px, h 30px!"); + pnlText.add(lblWithout, "w 80px!, h 30px!"); + pnlText.add(txfWithout, "pushx, growx, gap 5px 5px 2px 2px, h 30px!"); + + cbxPLow.addItem("*"); + cbxTLow.addItem("*"); + cbxCMCLow.addItem("*"); + + // Interval search + for (int i = 0; i < 10; i++) { + cbxPLow.addItem(i); + cbxTLow.addItem(i); + cbxCMCLow.addItem(i); + cbxPHigh.addItem(i); + cbxTHigh.addItem(i); + cbxCMCHigh.addItem(i); + } + + cbxPHigh.addItem("10+"); + cbxTHigh.addItem("10+"); + cbxCMCHigh.addItem("10+"); + + cbxPLow.setSelectedItem("*"); + cbxTLow.setSelectedItem("*"); + cbxCMCLow.setSelectedItem("*"); + cbxPHigh.setSelectedItem("10+"); + cbxTHigh.setSelectedItem("10+"); + cbxCMCHigh.setSelectedItem("10+"); + + constraints = "w 60px!, h 25px!, gap 0 0 0 0"; + pnlIntervals.add(cbxPLow, constraints); + pnlIntervals.add(lblP, "w 100px!, h 25px!"); + pnlIntervals.add(cbxPHigh, constraints); + + pnlIntervals.add(cbxTLow, constraints); + pnlIntervals.add(lblT, "w 100px!, h 25px!"); + pnlIntervals.add(cbxTHigh, constraints); + + pnlIntervals.add(cbxCMCLow, constraints); + pnlIntervals.add(lblCMC, "w 100px!, h 25px!"); + pnlIntervals.add(cbxCMCHigh, constraints); + + pnlIntervals.setOpaque(false); + + // Core layout + final String constraints2 = "w 90%!, gap 5% 0 1% 0"; + pnlContainer.add(lblProperties, "w 90%!, h 25px!, gap 5% 0 1% 0"); + pnlContainer.add(SFilterUtil.populateColorFilters(), constraints2); + pnlContainer.add(SFilterUtil.populateTypeFilters(), constraints2); + pnlContainer.add(cbxSets, constraints2 + ", h 25px!"); + + pnlContainer.add(lblText, "w 90%!, h 25px!, gap 5% 0 15px 0"); + pnlContainer.add(pnlText, constraints2); + + pnlContainer.add(lblIntervals, "w 90%!, h 25px!, gap 5% 0 15px 0"); + pnlContainer.add(pnlIntervals, constraints2); + + pnlContainer.setOpaque(false); + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_FILTERS; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CFilters.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0, wrap")); + parentCell.getBody().add(scroller, "w 96%!, h 96%, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {javax.swing.JLabel} */ + public JLabel getBtnToggle() { + return lblProperties; + } + + /** @return {javax.swing.JLabel} */ + public JLabel getBtnResetText() { + return lblText; + } + + /** @return {javax.swing.JLabel} */ + public JLabel getBtnResetIntervals() { + return lblIntervals; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxSets() { + return cbxSets; + } + + /** @return {javax.swing.JTextField} */ + public JTextField getTxfContains() { + return txfContains; + } + + /** @return {javax.swing.JTextField} */ + public JTextField getTxfWithout() { + return txfWithout; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxPLow() { + return cbxPLow; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxPHigh() { + return cbxPHigh; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxTLow() { + return cbxTLow; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxTHigh() { + return cbxTHigh; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxCMCLow() { + return cbxCMCLow; + } + + /** @return {javax.swing.JComboBox} */ + public JComboBox getCbxCMCHigh() { + return cbxCMCHigh; + } + //========== Custom class handling + +} diff --git a/src/main/java/forge/gui/deckeditor/views/VProbabilities.java b/src/main/java/forge/gui/deckeditor/views/VProbabilities.java new file mode 100644 index 00000000000..3ba2d6c5952 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VProbabilities.java @@ -0,0 +1,198 @@ +package forge.gui.deckeditor.views; + +import java.awt.Font; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingConstants; +import javax.swing.border.MatteBorder; + +import net.miginfocom.swing.MigLayout; +import forge.deck.DeckBase; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CProbabilities; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; +import forge.item.CardPrinted; +import forge.item.InventoryItem; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VProbabilities implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Draw Order"); + + // Title labels + private final JLabel lblReshuffle = new FLabel.Builder() + .hoverable(true).text("RE-SHUFFLE").tooltip("See a new sample shuffle") + .fontSize(12).build(); + private final JLabel lblSampleHand = new FLabel.Builder().fontStyle(Font.BOLD) + .fontSize(14).text("SAMPLE HAND").build(); + private final JLabel lblRemainingDraws = new FLabel.Builder().fontStyle(Font.BOLD) + .fontSize(14).text("REMAINING DRAWS").build(); + private final JLabel lblExplanation = new FLabel.Builder() + .fontSize(11).text("XX % = frequency that card will appear at that position").build(); + + // Layout containers + private final JPanel pnlContent = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + private final JScrollPane scroller = new JScrollPane(pnlContent); + private final JPanel pnlHand = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + private final JPanel pnlLibrary = new JPanel(new MigLayout("insets 0, gap 0, wrap")); + + //========== Constructor + private VProbabilities() { + pnlContent.setOpaque(false); + pnlHand.setOpaque(false); + pnlLibrary.setOpaque(false); + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + scroller.getVerticalScrollBar().setUnitIncrement(16); + + // Sample hand + lblExplanation.setBorder(new MatteBorder(0, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + lblRemainingDraws.setBorder(new MatteBorder(1, 0, 1, 0, FSkin.getColor(FSkin.Colors.CLR_BORDERS))); + + // Core layout + final String constraints = "w 96%!, h 25px!, gap 2% 0 0 0"; + + pnlContent.add(lblReshuffle, constraints); + pnlContent.add(lblSampleHand, constraints); + pnlContent.add(lblExplanation, constraints); + pnlContent.add(pnlHand, "w 96%!, gap 2% 0 0 0"); + pnlContent.add(lblRemainingDraws, constraints); + pnlContent.add(pnlLibrary, "w 96%!, gap 2% 0 0 0"); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_PROBABILITIES; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CProbabilities.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0")); + parentCell.getBody().add(scroller, "w 96%!, h 96%!, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblReshuffle() { + return lblReshuffle; + } + + //========== Other methods + /** @param shuffledVals   A map of card names and their positional probability. */ + public void rebuildLabels(final List shuffledVals) { + pnlHand.removeAll(); + pnlLibrary.removeAll(); + + JLabel lbl; + final String constraints = "w 96%, h 25px!, gap 2% 0 0 0"; + + for (int i = 0; i < shuffledVals.size(); i++) { + lbl = (i % 2 == 1 ? buildLabel(true) : buildLabel(false)); + lbl.setText(shuffledVals.get(i)); + + if (i < 7) { pnlHand.add(lbl, constraints); } + else { pnlLibrary.add(lbl, constraints); } + } + + pnlHand.validate(); + pnlLibrary.validate(); + } + + private JLabel buildLabel(final boolean zebra) { + final JLabel lbl = new FLabel.Builder().text("--") + .fontAlign(SwingConstants.CENTER).fontSize(13) + .build(); + + lbl.addMouseListener(new MouseAdapter() { + @Override + @SuppressWarnings("unchecked") + public void mouseEntered(final MouseEvent e) { + final ACEditorBase ed = (ACEditorBase) + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController(); + + final List cards = (List) ed.getTableDeck().getCards().toFlatList(); + final String name1 = lbl.getText(); + String name2; + + for (CardPrinted c : cards) { + name2 = c.getName(); + if (name2.length() > name1.length()) { continue; } + + if (name2.equals(name1.substring(0, name2.length()))) { + CDeckEditorUI.SINGLETON_INSTANCE.setCard(c.toForgeCard()); + break; + } + } + } + }); + + if (zebra) { + lbl.setOpaque(true); + lbl.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + } + + return lbl; + } +} diff --git a/src/main/java/forge/gui/deckeditor/views/VStatistics.java b/src/main/java/forge/gui/deckeditor/views/VStatistics.java new file mode 100644 index 00000000000..531e68dd8b2 --- /dev/null +++ b/src/main/java/forge/gui/deckeditor/views/VStatistics.java @@ -0,0 +1,267 @@ +package forge.gui.deckeditor.views; + +import java.awt.Font; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.SEditorUtil; +import forge.gui.deckeditor.controllers.CStatistics; +import forge.gui.framework.DragCell; +import forge.gui.framework.DragTab; +import forge.gui.framework.EDocID; +import forge.gui.framework.ICDoc; +import forge.gui.framework.IVDoc; +import forge.gui.toolbox.FLabel; +import forge.gui.toolbox.FSkin; + +/** + * Assembles Swing components of deck editor analysis tab. + * + *

(V at beginning of class name denotes a view class.) + */ +public enum VStatistics implements IVDoc { + /** */ + SINGLETON_INSTANCE; + + // Fields used with interface IVDoc + private DragCell parentCell; + private final DragTab tab = new DragTab("Statistics"); + + // Global stats + private JLabel lblTotal = new FLabel.Builder() + .text("Total cards: 0").tooltip("TOTAL CARDS") + .fontStyle(Font.BOLD).fontSize(11).fontStyle(Font.BOLD).build(); + private JLabel lblTMC = new FLabel.Builder() + .text("Total mana cost: 0").tooltip("TOTAL MANA COST") + .fontStyle(Font.BOLD).fontSize(11).fontStyle(Font.BOLD).build(); + private JLabel lblAMC = new FLabel.Builder() + .text("Average mana cost: 0.00").tooltip("AVERAGE MANA COST") + .fontStyle(Font.BOLD).fontSize(11).fontStyle(Font.BOLD).build(); + + // Total and color count labels + private final JPanel pnlStats = new JPanel(); + private final JLabel lblMulti = buildLabel(SEditorUtil.ICO_MULTI, true); + private final JLabel lblBlack = buildLabel(SEditorUtil.ICO_BLACK, false); + private final JLabel lblBlue = buildLabel(SEditorUtil.ICO_BLUE, true); + private final JLabel lblGreen = buildLabel(SEditorUtil.ICO_GREEN, false); + private final JLabel lblRed = buildLabel(SEditorUtil.ICO_RED, true); + private final JLabel lblWhite = buildLabel(SEditorUtil.ICO_WHITE, false); + private final JLabel lblColorless = buildLabel(SEditorUtil.ICO_COLORLESS, true); + + // Card type labels + private final JLabel lblArtifact = buildLabel(SEditorUtil.ICO_ARTIFACT, true); + private final JLabel lblCreature = buildLabel(SEditorUtil.ICO_CREATURE, false); + private final JLabel lblEnchantment = buildLabel(SEditorUtil.ICO_ENCHANTMENT, true); + private final JLabel lblInstant = buildLabel(SEditorUtil.ICO_INSTANT, false); + private final JLabel lblLand = buildLabel(SEditorUtil.ICO_LAND, true); + private final JLabel lblPlaneswalker = buildLabel(SEditorUtil.ICO_PLANESWALKER, false); + private final JLabel lblSorcery = buildLabel(SEditorUtil.ICO_SORCERY, true); + + // CMC labels + private final JLabel lblCMC0 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_0, 16, 16)), true); + private final JLabel lblCMC1 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_1, 16, 16)), false); + private final JLabel lblCMC2 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_2, 16, 16)), true); + private final JLabel lblCMC3 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_3, 16, 16)), false); + private final JLabel lblCMC4 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_4, 16, 16)), true); + private final JLabel lblCMC5 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_5, 16, 16)), false); + private final JLabel lblCMC6 = buildLabel( + new ImageIcon(FSkin.getImage(FSkin.ColorlessManaImages.IMG_6, 16, 16)), true); + + // Layout containers + private final JScrollPane scroller = new JScrollPane(pnlStats); + + //========== Constructor + private VStatistics() { + scroller.setOpaque(false); + scroller.getViewport().setOpaque(false); + scroller.setBorder(null); + scroller.getViewport().setBorder(null); + scroller.getVerticalScrollBar().setUnitIncrement(16); + + // Color stats + lblMulti.setToolTipText("Total Card Count"); + lblBlack.setToolTipText("Black Card Count"); + lblBlue.setToolTipText("Blue Card Count"); + lblGreen.setToolTipText("Green Card Count"); + lblRed.setToolTipText("Red Card Count"); + lblWhite.setToolTipText("White Card Count"); + lblColorless.setToolTipText("Total Card Count"); + + // Type stats + lblArtifact.setToolTipText("Artifact Card Count"); + lblCreature.setToolTipText("Creature Card Count"); + lblColorless.setToolTipText("Colorless Card Count"); + lblEnchantment.setToolTipText("Enchantment Card Count"); + lblInstant.setToolTipText("Instant Card Count"); + lblLand.setToolTipText("Land Card Count"); + lblPlaneswalker.setToolTipText("Planeswalker Card Count"); + lblSorcery.setToolTipText("Sorcery Card Count"); + + // Stats container + pnlStats.setOpaque(false); + pnlStats.setLayout(new MigLayout("insets 0, gap 0, ax center, wrap 3")); + + pnlStats.add(lblTotal, "w 96%!, h 20px!, span 3 1, gap 2% 0 0 0"); + pnlStats.add(lblTMC, "w 96%!, h 20px!, span 3 1, gap 2% 0 0 0"); + pnlStats.add(lblAMC, "w 96%!, h 20px!, span 3 1, gap 2% 0 0 0"); + + // Add labels to container + final String constraints = "w 32%!, h 35px!"; + pnlStats.add(lblMulti, constraints); + pnlStats.add(lblArtifact, constraints); + pnlStats.add(lblCMC0, constraints); + + pnlStats.add(lblBlack, constraints); + pnlStats.add(lblCreature, constraints); + pnlStats.add(lblCMC1, constraints); + + pnlStats.add(lblBlue, constraints); + pnlStats.add(lblEnchantment, constraints); + pnlStats.add(lblCMC2, constraints); + + pnlStats.add(lblGreen, constraints); + pnlStats.add(lblInstant, constraints); + pnlStats.add(lblCMC3, constraints); + + pnlStats.add(lblRed, constraints); + pnlStats.add(lblLand, constraints); + pnlStats.add(lblCMC4, constraints); + + pnlStats.add(lblWhite, constraints); + pnlStats.add(lblPlaneswalker, constraints); + pnlStats.add(lblCMC5, constraints); + + pnlStats.add(lblColorless, constraints); + pnlStats.add(lblSorcery, constraints); + pnlStats.add(lblCMC6, constraints); + } + + //========== Overridden methods + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getDocumentID() + */ + @Override + public EDocID getDocumentID() { + return EDocID.EDITOR_STATISTICS; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getTabLabel() + */ + @Override + public DragTab getTabLabel() { + return tab; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getControl() + */ + @Override + public ICDoc getControl() { + return CStatistics.SINGLETON_INSTANCE; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#setParentCell(forge.gui.framework.DragCell) + */ + @Override + public void setParentCell(final DragCell cell0) { + this.parentCell = cell0; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#getParentCell() + */ + @Override + public DragCell getParentCell() { + return this.parentCell; + } + + /* (non-Javadoc) + * @see forge.gui.framework.IVDoc#populate() + */ + @Override + public void populate() { + parentCell.getBody().setLayout(new MigLayout("insets 0, gap 0")); + parentCell.getBody().add(scroller, "w 96%!, h 96%!, gap 2% 0 2% 0"); + } + + //========== Retrieval methods + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblMulti() { return lblMulti; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblBlack() { return lblBlack; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblBlue() { return lblBlue; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblGreen() { return lblGreen; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblRed() { return lblRed; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblWhite() { return lblWhite; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblColorless() { return lblColorless; } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblArtifact() { return lblArtifact; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblEnchantment() { return lblEnchantment; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCreature() { return lblCreature; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblSorcery() { return lblSorcery; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblInstant() { return lblInstant; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblPlaneswalker() { return lblPlaneswalker; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblLand() { return lblLand; } + + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC0() { return lblCMC0; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC1() { return lblCMC1; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC2() { return lblCMC2; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC3() { return lblCMC3; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC4() { return lblCMC4; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC5() { return lblCMC5; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblCMC6() { return lblCMC6; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblTotal() { return lblTotal; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblTMC() { return lblTMC; } + /** @return {@link javax.swing.JLabel} */ + public JLabel getLblAMC() { return lblAMC; } + + //========== Other methods + + private JLabel buildLabel(final ImageIcon icon0, final boolean zebra) { + final JLabel lbl = new FLabel.Builder().text("0") + .icon(icon0).iconScaleAuto(false) + .fontSize(11).build(); + + if (zebra) { + lbl.setOpaque(true); + lbl.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); + } + + return lbl; + } +} diff --git a/src/main/java/forge/gui/framework/DragCell.java b/src/main/java/forge/gui/framework/DragCell.java index 504e98aa5cc..8b788a47e70 100644 --- a/src/main/java/forge/gui/framework/DragCell.java +++ b/src/main/java/forge/gui/framework/DragCell.java @@ -147,7 +147,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsX() { - return (int) this.getLocationOnScreen().getX(); + int i = 0; + + try { i = (int) this.getLocationOnScreen().getX(); } + catch (final Exception e) { } + + return i; } /** @@ -155,7 +160,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsX2() { - return this.getAbsX() + this.getW(); + int i = 0; + + try { i = this.getAbsX() + this.getW(); } + catch (final Exception e) { } + + return i; } /** @@ -163,7 +173,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsY() { - return (int) this.getLocationOnScreen().getY(); + int i = 0; + + try { i = (int) this.getLocationOnScreen().getY(); } + catch (final Exception e) { } + + return i; } /** @@ -171,7 +186,12 @@ public final class DragCell extends JPanel implements ILocalRepaint { * @return int */ public int getAbsY2() { - return this.getAbsY() + this.getH(); + int i = 0; + + try { i = this.getAbsY() + this.getH(); } + catch (final Exception e) { } + + return i; } /** diff --git a/src/main/java/forge/gui/framework/EDocID.java b/src/main/java/forge/gui/framework/EDocID.java index 3e68ad6de2e..8907752d0fa 100644 --- a/src/main/java/forge/gui/framework/EDocID.java +++ b/src/main/java/forge/gui/framework/EDocID.java @@ -3,6 +3,14 @@ */ package forge.gui.framework; +import forge.gui.deckeditor.views.VAllDecks; +import forge.gui.deckeditor.views.VCardCatalog; +import forge.gui.deckeditor.views.VCurrentDeck; +import forge.gui.deckeditor.views.VDeckgen; +import forge.gui.deckeditor.views.VEditorPreferences; +import forge.gui.deckeditor.views.VFilters; +import forge.gui.deckeditor.views.VProbabilities; +import forge.gui.deckeditor.views.VStatistics; import forge.gui.match.views.VAntes; import forge.gui.match.views.VCombat; import forge.gui.match.views.VDetail; @@ -25,6 +33,15 @@ public enum EDocID { /** */ CARD_DETAIL (VDetail.SINGLETON_INSTANCE), /** */ CARD_ANTES (VAntes.SINGLETON_INSTANCE), /** */ + EDITOR_FILTERS (VFilters.SINGLETON_INSTANCE), /** */ + EDITOR_PREFERENCES (VEditorPreferences.SINGLETON_INSTANCE), /** */ + EDITOR_ALLDECKS (VAllDecks.SINGLETON_INSTANCE), /** */ + EDITOR_STATISTICS (VStatistics.SINGLETON_INSTANCE), /** */ + EDITOR_PROBABILITIES (VProbabilities.SINGLETON_INSTANCE), /** */ + EDITOR_CATALOG (VCardCatalog.SINGLETON_INSTANCE), /** */ + EDITOR_CURRENTDECK (VCurrentDeck.SINGLETON_INSTANCE), /** */ + EDITOR_DECKGEN (VDeckgen.SINGLETON_INSTANCE), /** */ + REPORT_MESSAGE (VMessage.SINGLETON_INSTANCE), /** */ REPORT_STACK (VStack.SINGLETON_INSTANCE), /** */ REPORT_COMBAT (VCombat.SINGLETON_INSTANCE), /** */ @@ -37,14 +54,10 @@ public enum EDocID { /** */ // Non-user battlefields (AI or teammate), use setDoc to register. FIELD_0 (null), /** */ FIELD_1 (null), /** */ - FIELD_2 (null), /** */ - FIELD_3 (null), /** */ // Non-user hands (AI or teammate), use setDoc to register. HAND_0 (null), /** */ - HAND_1 (null), /** */ - HAND_2 (null), /** */ - HAND_3 (null); /** */ + HAND_1 (null); // End enum declarations, start enum methods. private IVDoc vDoc; @@ -61,7 +74,7 @@ public enum EDocID { /** */ /** @return {@link forge.gui.framework.IVDoc} */ public IVDoc getDoc() { - if (vDoc == null) { throw new NullPointerException("No document found!"); } + if (vDoc == null) { throw new NullPointerException("No document found for " + this.name() + "."); } return vDoc; } } diff --git a/src/main/java/forge/gui/framework/ICDoc.java b/src/main/java/forge/gui/framework/ICDoc.java index 9dc42a9c282..162f1b4b932 100644 --- a/src/main/java/forge/gui/framework/ICDoc.java +++ b/src/main/java/forge/gui/framework/ICDoc.java @@ -20,10 +20,10 @@ public interface ICDoc { Command getCommandOnSelect(); /** - * Call this method after the view singleton has been fully realized + * This method is called once, after the view singleton has been fully realized * for the first time. It should execute operations which should only - * be done once, but require non-null view components.

- * + * be done once, but require non-null view components. + *

* This method should only be called once, in FView, after singletons are populated. */ void initialize(); diff --git a/src/main/java/forge/gui/framework/IVTopLevelUI.java b/src/main/java/forge/gui/framework/IVTopLevelUI.java index 651de1ef11b..076750cd2f3 100644 --- a/src/main/java/forge/gui/framework/IVTopLevelUI.java +++ b/src/main/java/forge/gui/framework/IVTopLevelUI.java @@ -10,14 +10,18 @@ package forge.gui.framework; */ public interface IVTopLevelUI { /** Called during the preload sequence, this method caches - * all of the children singletons and instances. */ + * all of the view singletons and component instances, + * before any operations are performed on them. + *

+ * Although this is sometimes empty, it's important, since in many cases + * non-lazy components must be prepared before each panel is populated. + */ void instantiate(); /** * Removes all children and (re)populates top level content, * independent of constructor. Expected to provide * a completely fresh layout on the component. - * */ void populate(); } diff --git a/src/main/java/forge/gui/framework/SIOUtil.java b/src/main/java/forge/gui/framework/SLayoutIO.java similarity index 73% rename from src/main/java/forge/gui/framework/SIOUtil.java rename to src/main/java/forge/gui/framework/SLayoutIO.java index caf5cf34482..90ce1a1a892 100644 --- a/src/main/java/forge/gui/framework/SIOUtil.java +++ b/src/main/java/forge/gui/framework/SLayoutIO.java @@ -18,6 +18,8 @@ import javax.xml.stream.events.Attribute; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; +import forge.control.FControl; +import forge.properties.NewConstants; import forge.view.FView; @@ -26,7 +28,7 @@ import forge.view.FView; * *

(S at beginning of class name denotes a static factory.) */ -public final class SIOUtil { +public final class SLayoutIO { /** Each cell must save these elements of its display. */ private enum Property { x, @@ -36,15 +38,22 @@ public final class SIOUtil { doc }; - /** */ - public static final String FILE_DEFAULT = "res/layouts/match_default.xml"; - public static final String FILE_PREFERRED = "res/layouts/match_preferred.xml"; + private static String fileDefault = null; + private static String filePreferred = null; private static final XMLEventFactory EF = XMLEventFactory.newInstance(); private static final XMLEvent NEWLINE = EF.createDTD("\n"); private static final XMLEvent TAB = EF.createDTD("\t"); + /** + * Gets preferred layout file corresponding to current state of UI. + * @return {@link java.lang.String} + */ + public static String getFilePreferred() { + return filePreferred; + } + /** Publicly-accessible save method, to neatly handle exception handling. - * @param f0 file to save layout to, if null, saves to FILE_PREFERRED + * @param f0 file to save layout to, if null, saves to filePreferred * * */ @@ -52,9 +61,9 @@ public final class SIOUtil { if (SwingUtilities.isEventDispatchThread()) { throw new IllegalThreadStateException("This operation should be independent of the EDT."); } - - try { save(f0); } - catch (final Exception e) { e.printStackTrace(); } + + try { save(f0); } + catch (final Exception e) { e.printStackTrace(); } } @@ -63,24 +72,21 @@ public final class SIOUtil { * @param f0   {@link java.io.File} */ public static void loadLayout(final File f0) { - if (SwingUtilities.isEventDispatchThread()) { - throw new IllegalThreadStateException("This operation should be independent of the EDT."); - } - try { load(f0); } catch (final Exception e) { e.printStackTrace(); } } private static void save(final File f0) throws Exception { - final String fWriteTo; - if (f0==null) { - fWriteTo = FILE_PREFERRED; + SLayoutIO.setFilesForState(); + + if (f0 == null) { + fWriteTo = filePreferred; } else { fWriteTo = f0.getPath(); - } - + } + final XMLOutputFactory out = XMLOutputFactory.newInstance(); final XMLEventWriter writer = out.createXMLEventWriter(new FileOutputStream(fWriteTo)); final List cells = FView.SINGLETON_INSTANCE.getDragCells(); @@ -125,16 +131,17 @@ public final class SIOUtil { private static void load(final File f) throws Exception { final FView view = FView.SINGLETON_INSTANCE; final XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + SLayoutIO.setFilesForState(); final XMLEventReader reader; if (f != null && f.exists()) { reader = inputFactory.createXMLEventReader(new FileInputStream(f)); } - else if (new File(FILE_PREFERRED).exists()) { - reader = inputFactory.createXMLEventReader(new FileInputStream(FILE_PREFERRED)); + else if (new File(filePreferred).exists()) { + reader = inputFactory.createXMLEventReader(new FileInputStream(filePreferred)); } else { - reader = inputFactory.createXMLEventReader(new FileInputStream(FILE_DEFAULT)); + reader = inputFactory.createXMLEventReader(new FileInputStream(fileDefault)); } view.removeAllDragCells(); @@ -149,7 +156,6 @@ public final class SIOUtil { event = reader.nextEvent(); if (event.isStartElement()) { - //&& event.asStartElement().getName().getLocalPart().equals("cell")) { element = event.asStartElement(); if (element.getName().getLocalPart().equals("cell")) { @@ -195,4 +201,37 @@ public final class SIOUtil { writer0.add(EF.createEndElement("", "", name0.toString())); writer0.add(NEWLINE); } + + /** + * Updates preferred / default layout addresses particular to each UI state. + * Always called before a load or a save, to ensure file addresses are correct. + */ + private static void setFilesForState() { + final String dir = NewConstants.LAYOUT_DIR; + + switch(FControl.SINGLETON_INSTANCE.getState()) { + case FControl.HOME_SCREEN: + fileDefault = dir + "home_default.xml"; + filePreferred = dir + "home_preferred.xml"; + break; + case FControl.MATCH_SCREEN: + fileDefault = dir + "match_default.xml"; + filePreferred = dir + "match_preferred.xml"; + break; + case FControl.DECK_EDITOR_CONSTRUCTED: + case FControl.DECK_EDITOR_LIMITED: + case FControl.DECK_EDITOR_QUEST: + case FControl.DRAFTING_PROCESS: + case FControl.QUEST_CARD_SHOP: + fileDefault = dir + "editor_default.xml"; + filePreferred = dir + "editor_preferred.xml"; + break; + case FControl.QUEST_BAZAAR: + fileDefault = dir + "bazaar_default.xml"; + filePreferred = dir + "bazaar_preferred.xml"; + break; + default: + throw new IllegalStateException("Layout load failed; UI state unknown."); + } + } } diff --git a/src/main/java/forge/gui/framework/SRearrangingUtil.java b/src/main/java/forge/gui/framework/SRearrangingUtil.java index 22f8732deea..50d6a23f484 100644 --- a/src/main/java/forge/gui/framework/SRearrangingUtil.java +++ b/src/main/java/forge/gui/framework/SRearrangingUtil.java @@ -307,7 +307,7 @@ public final class SRearrangingUtil { updateBorders(); final Thread t = new Thread() { @Override - public void run() { SIOUtil.saveLayout(null); } }; + public void run() { SLayoutIO.saveLayout(null); } }; t.start(); } @@ -439,6 +439,19 @@ public final class SRearrangingUtil { throw new UnsupportedOperationException("Gap was not filled."); } + /** + * Fills a gap left by a source cell. + *

+ * Cell will not be removed, but its coordinates will be filled + * by its neighbors. + * + * @param sourceCell0   {@link forge.gui.framework.DragCell} + */ + public static void fillGap(final DragCell sourceCell0) { + cellSrc = sourceCell0; + fillGap(); + } + /** Hides outer borders for components on edges, * preventing illegal resizing (and misleading cursor). */ public static void updateBorders() { diff --git a/src/main/java/forge/gui/framework/SResizingUtil.java b/src/main/java/forge/gui/framework/SResizingUtil.java index d59630a7524..e7262465ab5 100644 --- a/src/main/java/forge/gui/framework/SResizingUtil.java +++ b/src/main/java/forge/gui/framework/SResizingUtil.java @@ -14,6 +14,7 @@ import java.util.List; import javax.swing.JPanel; +import forge.gui.toolbox.FOverlay; import forge.view.FView; /** @@ -90,6 +91,7 @@ public final class SResizingUtil { final JPanel pnlContent = FView.SINGLETON_INSTANCE.getPnlContent(); final JPanel pnlInsets = FView.SINGLETON_INSTANCE.getPnlInsets(); + FOverlay.SINGLETON_INSTANCE.getPanel().setBounds(FView.SINGLETON_INSTANCE.getFrame().getContentPane().getBounds()); pnlInsets.setBounds(FView.SINGLETON_INSTANCE.getFrame().getContentPane().getBounds()); pnlInsets.validate(); @@ -332,7 +334,7 @@ public final class SResizingUtil { /** */ public static void endResize() { final Thread t = new Thread() { @Override - public void run() { SIOUtil.saveLayout(null); } }; + public void run() { SLayoutIO.saveLayout(null); } }; t.start(); } diff --git a/src/main/java/forge/gui/home/VHomeUI.java b/src/main/java/forge/gui/home/VHomeUI.java index 6429ae72cf6..1417f68c612 100644 --- a/src/main/java/forge/gui/home/VHomeUI.java +++ b/src/main/java/forge/gui/home/VHomeUI.java @@ -142,7 +142,7 @@ public enum VHomeUI implements IVTopLevelUI { scrMenu.setBorder(null); pnlLeft.setLayout(new MigLayout("insets 0, gap 0, align center, wrap")); - pnlLeft.add(new FLabel.Builder().icon(FSkin.getIcon(FSkin.ForgeIcons.ICO_LOGO)) + pnlLeft.add(new FLabel.Builder().icon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_LOGO)) .iconScaleFactor(1.0f).build(), "w 150px!, h 150px!, align center"); pnlLeft.add(scrMenu, "pushy, growy, w 98%!, gap 1% 0 1% 0"); @@ -202,16 +202,7 @@ public enum VHomeUI implements IVTopLevelUI { pnlParent.addComponentListener(new ComponentAdapter() { @Override public void componentResized(final ComponentEvent e) { - final int w = pnlParent.getWidth(); - final int h = pnlParent.getHeight(); - pnlRight.setBounds(new Rectangle( - 2 * insets + leftWidthPx, insets, - w - leftWidthPx - 3 * insets, h - 2 * insets)); - pnlLeft.setBounds(new Rectangle( - insets, insets, - leftWidthPx, h - 2 * insets - )); - pnlParent.revalidate(); + updateLayout(); } }); } @@ -247,7 +238,7 @@ public enum VHomeUI implements IVTopLevelUI { /** Custom title label styling. */ @SuppressWarnings("serial") private JLabel makeTitleLabel(final EMenuGroup e0) { - final FLabel lbl = new FLabel.Builder().fontScaleAuto(false).fontSize(16) + final FLabel lbl = new FLabel.Builder().fontSize(16) .hoverable(true).fontAlign(SwingConstants.LEFT).build(); lbl.setBorder(BorderFactory.createCompoundBorder( @@ -266,7 +257,7 @@ public enum VHomeUI implements IVTopLevelUI { private FLabel makeItemLabel(final IVSubmenu item) { final ForgePreferences prefs = Singletons.getModel().getPreferences(); - final FLabel lbl = new FLabel.Builder().fontScaleAuto(false).fontSize(15) + final FLabel lbl = new FLabel.Builder().fontSize(15) .hoverable(true).selectable(true).text(item.getMenuTitle()) .fontAlign(SwingConstants.LEFT).build(); @@ -313,4 +304,18 @@ public enum VHomeUI implements IVTopLevelUI { public JPanel getPanel() { return pnlParent; } + + /** Updates the null layout percentage dimensions. */ + public void updateLayout() { + final int w = pnlParent.getWidth(); + final int h = pnlParent.getHeight(); + pnlRight.setBounds(new Rectangle( + 2 * insets + leftWidthPx, insets, + w - leftWidthPx - 3 * insets, h - 2 * insets)); + pnlLeft.setBounds(new Rectangle( + insets, insets, + leftWidthPx, h - 2 * insets + )); + pnlParent.revalidate(); + } } diff --git a/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java index d6998d03836..46534ed609f 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuChallenges.java @@ -13,7 +13,7 @@ import forge.Command; import forge.gui.home.EMenuItem; import forge.gui.home.ICSubmenu; import forge.gui.home.VHomeUI; -import forge.gui.home.quest.SubmenuQuestUtil.SelectablePanel; +import forge.gui.home.quest.SSubmenuQuestUtil.SelectablePanel; import forge.gui.toolbox.FLabel; import forge.quest.QuestController; import forge.quest.QuestEventChallenge; @@ -59,15 +59,15 @@ public enum CSubmenuChallenges implements ICSubmenu { view.getBtnSpellShop().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showSpellShop(); } }); + public void execute() { SSubmenuQuestUtil.showSpellShop(); } }); view.getBtnBazaar().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showBazaar(); } }); + public void execute() { SSubmenuQuestUtil.showBazaar(); } }); view.getBtnStart().addActionListener( new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { SubmenuQuestUtil.startGame(); } }); + public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); ((FLabel) view.getLblZep()).setCommand( new Command() { @@ -111,7 +111,7 @@ public enum CSubmenuChallenges implements ICSubmenu { */ @Override public void update() { - SubmenuQuestUtil.updateStatsAndPet(); + SSubmenuQuestUtil.updateStatsAndPet(); final VSubmenuChallenges view = VSubmenuChallenges.SINGLETON_INSTANCE; final QuestController qCtrl = AllZone.getQuest(); diff --git a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java index e4d0e083ab4..925bc9dc0a2 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuDuels.java @@ -9,7 +9,7 @@ import forge.Command; import forge.gui.home.EMenuItem; import forge.gui.home.ICSubmenu; import forge.gui.home.VHomeUI; -import forge.gui.home.quest.SubmenuQuestUtil.SelectablePanel; +import forge.gui.home.quest.SSubmenuQuestUtil.SelectablePanel; import forge.quest.QuestController; import forge.quest.QuestEventDuel; import forge.quest.bazaar.QuestPetController; @@ -52,15 +52,15 @@ public enum CSubmenuDuels implements ICSubmenu { view.getBtnSpellShop().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showSpellShop(); } }); + public void execute() { SSubmenuQuestUtil.showSpellShop(); } }); view.getBtnBazaar().setCommand( new Command() { @Override - public void execute() { SubmenuQuestUtil.showBazaar(); } }); + public void execute() { SSubmenuQuestUtil.showBazaar(); } }); view.getBtnStart().addActionListener( new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { SubmenuQuestUtil.startGame(); } }); + public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); view.getBtnCurrentDeck().setCommand( new Command() { @Override @@ -94,7 +94,7 @@ public enum CSubmenuDuels implements ICSubmenu { */ @Override public void update() { - SubmenuQuestUtil.updateStatsAndPet(); + SSubmenuQuestUtil.updateStatsAndPet(); final VSubmenuDuels view = VSubmenuDuels.SINGLETON_INSTANCE; diff --git a/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java index 78cf30dfbea..6566217b4ff 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuQuestData.java @@ -189,7 +189,7 @@ public enum CSubmenuQuestData implements ICSubmenu { AllZone.getQuest().getName() + ".dat"); Singletons.getModel().getQuestPreferences().save(); - SubmenuQuestUtil.updateStatsAndPet(); + SSubmenuQuestUtil.updateStatsAndPet(); CSubmenuDuels.SINGLETON_INSTANCE.update(); CSubmenuChallenges.SINGLETON_INSTANCE.update(); diff --git a/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java b/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java index 90915a50dbc..81c5afb7db2 100644 --- a/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java +++ b/src/main/java/forge/gui/home/quest/CSubmenuQuestDecks.java @@ -5,9 +5,10 @@ import java.util.ArrayList; import forge.AllZone; import forge.Command; import forge.Singletons; +import forge.control.FControl; import forge.deck.Deck; -import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DeckEditorQuest; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorQuest; import forge.gui.home.EMenuItem; import forge.gui.home.ICSubmenu; import forge.gui.home.VHomeUI; @@ -26,15 +27,6 @@ public enum CSubmenuQuestDecks implements ICSubmenu { private Deck currentDeck; - private final Command cmdDeckExit = new Command() { - @Override - public void execute() { - AllZone.getQuest().save(); - SOverlayUtils.hideOverlay(); - update(); - } - }; - private final Command cmdDeckSelect = new Command() { @Override public void execute() { @@ -76,11 +68,8 @@ public enum CSubmenuQuestDecks implements ICSubmenu { VSubmenuQuestDecks.SINGLETON_INSTANCE.getBtnNewDeck().setCommand(new Command() { @Override public void execute() { - final DeckEditorQuest editor = - new DeckEditorQuest(Singletons.getView().getFrame(), AllZone.getQuest()); - editor.show(cmdDeckExit); - SOverlayUtils.showOverlay(); - editor.setVisible(true); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(new CEditorQuest(AllZone.getQuest())); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_QUEST); } }); } @@ -116,7 +105,6 @@ public enum CSubmenuQuestDecks implements ICSubmenu { view.getLstDecks().setSelectCommand(cmdDeckSelect); view.getLstDecks().setDeleteCommand(cmdDeckDelete); - view.getLstDecks().setExitCommand(cmdDeckExit); if (view.getLstDecks().getSelectedDeck() != null) { Singletons.getModel().getQuestPreferences().setPreference(QPref.CURRENT_DECK, view.getLstDecks().getSelectedDeck().getName()); diff --git a/src/main/java/forge/gui/home/quest/QuestFileLister.java b/src/main/java/forge/gui/home/quest/QuestFileLister.java index f565ef95933..11a09fea708 100644 --- a/src/main/java/forge/gui/home/quest/QuestFileLister.java +++ b/src/main/java/forge/gui/home/quest/QuestFileLister.java @@ -60,10 +60,10 @@ public class QuestFileLister extends JPanel { this.setOpaque(false); this.setLayout(new MigLayout("insets 0, gap 0, wrap")); - icoDelete = FSkin.getIcon(FSkin.ForgeIcons.ICO_DELETE); - icoDeleteOver = FSkin.getIcon(FSkin.ForgeIcons.ICO_DELETE_OVER); - icoEdit = FSkin.getIcon(FSkin.ForgeIcons.ICO_EDIT); - icoEditOver = FSkin.getIcon(FSkin.ForgeIcons.ICO_EDIT_OVER); + icoDelete = FSkin.getIcon(FSkin.InterfaceIcons.ICO_DELETE); + icoDeleteOver = FSkin.getIcon(FSkin.InterfaceIcons.ICO_DELETE_OVER); + icoEdit = FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT); + icoEditOver = FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT_OVER); } /** @param qd0   {@link forge.quest.data.QuestData}[] */ diff --git a/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java similarity index 93% rename from src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java rename to src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java index 45337c82ad6..a3aafd5c502 100644 --- a/src/main/java/forge/gui/home/quest/SubmenuQuestUtil.java +++ b/src/main/java/forge/gui/home/quest/SSubmenuQuestUtil.java @@ -20,7 +20,8 @@ import forge.deck.Deck; import forge.game.GameNew; import forge.game.GameType; import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.QuestCardShop; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorQuestCardShop; import forge.gui.toolbox.FLabel; import forge.gui.toolbox.FPanel; import forge.gui.toolbox.FSkin; @@ -41,8 +42,10 @@ import forge.quest.data.QuestPreferences.QPref; /** * Utilities for the quest submenu, all over the MVC spectrum. * If a piece of code can be reused, it's dumped here. + * + *

(S at beginning of class name denotes a static factory.) */ -public class SubmenuQuestUtil { +public class SSubmenuQuestUtil { private static SelectablePanel selectedOpponent; /** @@ -140,7 +143,7 @@ public class SubmenuQuestUtil { view.getLblLosses().setText("Losses: " + qA.getLost()); view.updateCurrentDeckStatus(); - final int num = SubmenuQuestUtil.nextChallengeInWins(); + final int num = SSubmenuQuestUtil.nextChallengeInWins(); if (num == 0) { view.getLblNextChallengeInWins().setText("Next challenge available now."); } @@ -186,19 +189,10 @@ public class SubmenuQuestUtil { } /** */ - @SuppressWarnings("serial") public static void showSpellShop() { - final Command exit = new Command() { - @Override - public void execute() { - AllZone.getQuest().save(); - updateStatsAndPet(); - } - }; - - final QuestCardShop g = new QuestCardShop(Singletons.getView().getFrame(), AllZone.getQuest()); - g.show(exit); - g.setVisible(true); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController( + new CEditorQuestCardShop(AllZone.getQuest())); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_QUEST); } /** */ @@ -223,7 +217,7 @@ public class SubmenuQuestUtil { final SwingWorker worker = new SwingWorker() { @Override public Object doInBackground() { - Constant.Runtime.HUMAN_DECK[0] = SubmenuQuestUtil.getCurrentDeck(); + Constant.Runtime.HUMAN_DECK[0] = SSubmenuQuestUtil.getCurrentDeck(); Constant.Runtime.COMPUTER_DECK[0] = event.getEventDeck(); Constant.Runtime.setGameType(GameType.Quest); @@ -255,7 +249,7 @@ public class SubmenuQuestUtil { event.getIconFilename()); } // End isFantasy else { - GameNew.newGame(SubmenuQuestUtil.getCurrentDeck(), event.getEventDeck()); + GameNew.newGame(SSubmenuQuestUtil.getCurrentDeck(), event.getEventDeck()); } return null; } @@ -297,7 +291,7 @@ public class SubmenuQuestUtil { VSubmenuChallenges.SINGLETON_INSTANCE.getBtnStart().setEnabled(true); } - selectedOpponent = SubmenuQuestUtil.SelectablePanel.this; + selectedOpponent = SSubmenuQuestUtil.SelectablePanel.this; } }); @@ -307,7 +301,7 @@ public class SubmenuQuestUtil { final FLabel lblIcon = new FLabel.Builder().iconScaleFactor(1).build(); if (!file.exists()) { - lblIcon.setIcon(FSkin.getIcon(FSkin.ForgeIcons.ICO_UNKNOWN)); + lblIcon.setIcon(FSkin.getIcon(FSkin.InterfaceIcons.ICO_UNKNOWN)); } else { lblIcon.setIcon(new ImageIcon(file.toString())); diff --git a/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java index 51088dbbec5..75de618b577 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuChallenges.java @@ -43,36 +43,36 @@ public enum VSubmenuChallenges implements IVSubmenu, IStatsAndPet { private final JCheckBox cbPlant = new FCheckBox("Summon Plant"); private final JLabel lblZep = new FLabel.Builder().text("Launch
Zeppelin") .hoverable(true).icon(FSkin.getIcon(FSkin.QuestIcons.ICO_ZEP)) - .fontScaleAuto(false).fontSize(16).build(); + .fontSize(16).build(); private final FLabel lblLife = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_LIFE)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblCredits = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COINSTACK)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblWins = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_PLUS)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblLosses = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_MINUS)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblWinStreak = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_PLUSPLUS)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblTitle = new FLabel.Builder() .text("Title Hasn't Been Set Yet").fontAlign(SwingConstants.CENTER) - .fontScaleAuto(false).fontSize(16).build(); + .fontSize(16).build(); private final FLabel lblNextChallengeInWins = new FLabel.Builder() - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel btnCurrentDeck = new FLabel.Builder() - .fontScaleAuto(false).fontSize(15).opaque(true).hoverable(true).build(); + .fontSize(15).opaque(true).hoverable(true).build(); private final FLabel btnBazaar = new FLabel.Builder() .opaque(true).hoverable(true).text("Bazaar") - .fontScaleAuto(false).fontSize(14).tooltip("Peruse the Bazaar").build(); + .fontSize(14).tooltip("Peruse the Bazaar").build(); private final FLabel btnSpellShop = new FLabel.Builder() .opaque(true).hoverable(true).text("Spell Shop") - .fontScaleAuto(false).fontSize(14).tooltip("Travel to the Spell Shop").build(); + .fontSize(14).tooltip("Travel to the Spell Shop").build(); /* (non-Javadoc) * @see forge.view.home.IViewSubmenu#getPanel() @@ -144,14 +144,14 @@ public enum VSubmenuChallenges implements IVSubmenu, IStatsAndPet { @Override public void updateCurrentDeckStatus() { final JLabel btnCurrentDeck = VSubmenuChallenges.SINGLETON_INSTANCE.getBtnCurrentDeck(); - if (SubmenuQuestUtil.getCurrentDeck() == null) { + if (SSubmenuQuestUtil.getCurrentDeck() == null) { btnCurrentDeck.setBackground(Color.red.darker()); btnCurrentDeck.setText(" Build, then select a deck in the \"Decks\" submenu. "); } else { btnCurrentDeck.setBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); btnCurrentDeck.setText("Current deck: " - + SubmenuQuestUtil.getCurrentDeck().getName()); + + SSubmenuQuestUtil.getCurrentDeck().getName()); } } diff --git a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java index 978cbfd39f8..6d248118ea8 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuDuels.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuDuels.java @@ -42,36 +42,36 @@ public enum VSubmenuDuels implements IVSubmenu, IStatsAndPet { private final JComboBox cbxPet = new JComboBox(); private final JCheckBox cbPlant = new FCheckBox("Summon Plant"); private final JLabel lblZep = new FLabel.Builder().text("Launch Zeppelin") - .fontScaleAuto(false).fontSize(14).build(); + .fontSize(14).build(); private final FLabel lblLife = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_LIFE)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblCredits = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COINSTACK)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblWins = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_PLUS)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblLosses = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_MINUS)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblWinStreak = new FLabel.Builder() .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_PLUSPLUS)) - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel lblTitle = new FLabel.Builder() .text("Title Hasn't Been Set Yet").fontAlign(SwingConstants.CENTER) - .fontScaleAuto(false).fontSize(16).build(); + .fontSize(16).build(); private final FLabel lblNextChallengeInWins = new FLabel.Builder() - .fontScaleAuto(false).fontSize(15).build(); + .fontSize(15).build(); private final FLabel btnCurrentDeck = new FLabel.Builder() - .fontScaleAuto(false).fontSize(15).opaque(true).hoverable(true).build(); + .fontSize(15).opaque(true).hoverable(true).build(); private final FLabel btnBazaar = new FLabel.Builder() .opaque(true).hoverable(true).text("Bazaar") - .fontScaleAuto(false).fontSize(14).tooltip("Peruse the Bazaar").build(); + .fontSize(14).tooltip("Peruse the Bazaar").build(); private final FLabel btnSpellShop = new FLabel.Builder() .opaque(true).hoverable(true).text("Spell Shop") - .fontScaleAuto(false).fontSize(14).tooltip("Travel to the Spell Shop").build(); + .fontSize(14).tooltip("Travel to the Spell Shop").build(); /* (non-Javadoc) * @see forge.view.home.IViewSubmenu#getPanel() @@ -144,14 +144,14 @@ public enum VSubmenuDuels implements IVSubmenu, IStatsAndPet { @Override public void updateCurrentDeckStatus() { final JLabel btnCurrentDeck = VSubmenuDuels.SINGLETON_INSTANCE.getBtnCurrentDeck(); - if (SubmenuQuestUtil.getCurrentDeck() == null) { + if (SSubmenuQuestUtil.getCurrentDeck() == null) { btnCurrentDeck.setBackground(Color.red.darker()); btnCurrentDeck.setText(" Build, then select a deck in the \"Decks\" submenu. "); } else { btnCurrentDeck.setBackground(FSkin.getColor(FSkin.Colors.CLR_INACTIVE)); btnCurrentDeck.setText("Current deck: " - + SubmenuQuestUtil.getCurrentDeck().getName()); + + SSubmenuQuestUtil.getCurrentDeck().getName()); } } diff --git a/src/main/java/forge/gui/home/quest/VSubmenuQuestData.java b/src/main/java/forge/gui/home/quest/VSubmenuQuestData.java index e312819671f..9fe885e9515 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuQuestData.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuQuestData.java @@ -74,7 +74,7 @@ public enum VSubmenuQuestData implements IVSubmenu { pnlTitleLoad.setLayout(new MigLayout("insets 0, align center")); pnlTitleLoad.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); pnlTitleLoad.add(new FLabel.Builder().text("Load a previous Quest") - .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + .fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); final FScrollPane scr = new FScrollPane(lstQuests); scr.setBorder(null); @@ -85,7 +85,7 @@ public enum VSubmenuQuestData implements IVSubmenu { pnlTitleNew.setLayout(new MigLayout("insets 0, align center")); pnlTitleNew.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); pnlTitleNew.add(new FLabel.Builder().text("Start a new Quest") - .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + .fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); final ButtonGroup group1 = new ButtonGroup(); group1.add(radEasy); @@ -171,7 +171,7 @@ public enum VSubmenuQuestData implements IVSubmenu { pnlViewport.add(new FLabel.Builder().text("Old quest data? Put into " + "res/quest/data, and restart Forge.") - .fontAlign(SwingConstants.CENTER).fontScaleAuto(false).fontSize(12) + .fontAlign(SwingConstants.CENTER).fontSize(12) .build(), "w 96%!, h 18px!, gap 2% 0 0 4px"); pnlViewport.add(scr, "w 96%!, pushy, growy, gap 2% 0 0 30px"); diff --git a/src/main/java/forge/gui/home/quest/VSubmenuQuestDecks.java b/src/main/java/forge/gui/home/quest/VSubmenuQuestDecks.java index 47c2c1642e2..beb63fffd87 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuQuestDecks.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuQuestDecks.java @@ -26,7 +26,7 @@ public enum VSubmenuQuestDecks implements IVSubmenu { private final JPanel pnl = new JPanel(); private final DeckLister lstDecks = new DeckLister(GameType.Quest); private final FLabel btnNewDeck = new FLabel.Builder().opaque(true) - .hoverable(true).text("Build a New Deck").fontScaleAuto(false).fontSize(18).build(); + .hoverable(true).text("Build a New Deck").fontSize(18).build(); /* (non-Javadoc) * @see forge.view.home.IViewSubmenu#populate() diff --git a/src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java b/src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java index 916edb9758d..337d0a1f2d9 100644 --- a/src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java +++ b/src/main/java/forge/gui/home/quest/VSubmenuQuestPrefs.java @@ -78,7 +78,7 @@ public enum VSubmenuQuestPrefs implements IVSubmenu { pnlTitleRewards.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); pnlTitleRewards.add(new FLabel.Builder().text("Rewards") .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COIN)) - .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + .fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); pnlContent.add(pnlTitleRewards, "w 96%!, h 36px!, gap 2% 0 10px 20px"); pnlContent.add(pnlRewards, "w 96%!, gap 2% 0 10px 20px"); @@ -90,7 +90,7 @@ public enum VSubmenuQuestPrefs implements IVSubmenu { pnlTitleBooster.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); pnlTitleBooster.add(new FLabel.Builder().text("Booster Pack Ratios") .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_BOOK)) - .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + .fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); pnlContent.add(pnlTitleBooster, "w 96%!, h 36px!, gap 2% 0 10px 10px"); pnlContent.add(pnlBooster, "w 96%!, gap 2% 0 10px 20px"); populateBooster(); @@ -101,7 +101,7 @@ public enum VSubmenuQuestPrefs implements IVSubmenu { pnlTitleDifficulty.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); pnlTitleDifficulty.add(new FLabel.Builder().text("Difficulty Adjustments") .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_NOTES)) - .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + .fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); pnlContent.add(pnlTitleDifficulty, "w 96%!, h 36px!, gap 2% 0 10px 10px"); pnlContent.add(pnlDifficulty, "w 96%!, gap 2% 0 10px 20px"); populateDifficulty(); @@ -112,7 +112,7 @@ public enum VSubmenuQuestPrefs implements IVSubmenu { pnlTitleShop.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); pnlTitleShop.add(new FLabel.Builder().text("Shop Preferences") .icon(FSkin.getIcon(FSkin.QuestIcons.ICO_COIN)) - .fontScaleAuto(false).fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); + .fontSize(16).build(), "h 95%!, gap 0 0 2.5% 0"); pnlContent.add(pnlTitleShop, "w 96%!, h 36px!, gap 2% 0 10px 10px"); pnlContent.add(pnlShop, "w 96%!, gap 2% 0 10px 20px"); populateShop(); diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java index a10b9e10460..4122a4bd4e7 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java @@ -13,6 +13,7 @@ import javax.swing.SwingWorker; import forge.Command; import forge.Constant; import forge.Singletons; +import forge.control.FControl; import forge.deck.Deck; import forge.deck.DeckGroup; import forge.game.GameNew; @@ -21,7 +22,8 @@ import forge.game.limited.BoosterDraft; import forge.game.limited.CardPoolLimitation; import forge.gui.GuiUtils; import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DraftingProcess; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorDraftingProcess; import forge.gui.home.ICSubmenu; import forge.gui.toolbox.FSkin; @@ -77,14 +79,6 @@ public enum CSubmenuDraft implements ICSubmenu { "Walter", "Wilfred", "William", "Winston" }; - private final Command cmdDeckExit = new Command() { - @Override - public void execute() { - update(); - SOverlayUtils.hideOverlay(); - } - }; - private final Command cmdDeckSelect = new Command() { @Override public void execute() { @@ -102,7 +96,6 @@ public enum CSubmenuDraft implements ICSubmenu { view.populate(); CSubmenuDraft.SINGLETON_INSTANCE.update(); - view.getLstHumanDecks().setExitCommand(cmdDeckExit); view.getLstHumanDecks().setSelectCommand(cmdDeckSelect); view.getBtnBuildDeck().addMouseListener( @@ -220,9 +213,7 @@ public enum CSubmenuDraft implements ICSubmenu { /** */ private void setupDraft() { - SOverlayUtils.showOverlay(); - - final DraftingProcess draft = new DraftingProcess(Singletons.getView().getFrame()); + final CEditorDraftingProcess draft = new CEditorDraftingProcess(); // Determine what kind of booster draft to run final ArrayList draftTypes = new ArrayList(); @@ -244,6 +235,9 @@ public enum CSubmenuDraft implements ICSubmenu { else if (o.toString().equals(draftTypes.get(2))) { draft.showGui(new BoosterDraft(CardPoolLimitation.Custom)); } + + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(draft); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); } private String[] generateNames() { diff --git a/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java b/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java index 0e6cfe5b4a0..0d6f6640025 100644 --- a/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java +++ b/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java @@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Command; import forge.Constant; import forge.Singletons; +import forge.control.FControl; import forge.deck.Deck; import forge.deck.DeckBase; import forge.deck.DeckGroup; @@ -23,8 +24,9 @@ import forge.game.GameNew; import forge.game.limited.SealedDeck; import forge.gui.GuiUtils; import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DeckEditorBase; -import forge.gui.deckeditor.DeckEditorLimited; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CEditorLimited; import forge.gui.home.ICSubmenu; import forge.gui.toolbox.FSkin; import forge.item.CardPrinted; @@ -46,14 +48,6 @@ public enum CSubmenuSealed implements ICSubmenu { private Map aiDecks; - private final Command cmdExit = new Command() { - @Override - public void execute() { - update(); - SOverlayUtils.hideOverlay(); - } - }; - private final Command cmdDeckSelect = new Command() { @Override public void execute() { @@ -71,7 +65,6 @@ public enum CSubmenuSealed implements ICSubmenu { view.populate(); CSubmenuSealed.SINGLETON_INSTANCE.update(); - VSubmenuSealed.SINGLETON_INSTANCE.getLstDecks().setExitCommand(cmdExit); VSubmenuSealed.SINGLETON_INSTANCE.getLstDecks().setSelectCommand(cmdDeckSelect); VSubmenuSealed.SINGLETON_INSTANCE.getBtnBuildDeck().addMouseListener( @@ -225,15 +218,13 @@ public enum CSubmenuSealed implements ICSubmenu { final DeckGroup sealed = new DeckGroup(sDeckName); sealed.setHumanDeck(deck); sealed.addAiDeck(sd.buildAIDeck(sDeck.toForgeCardList())); - Singletons.getModel().getDecks().getSealed().add(sealed); + Singletons.getModel().getDecks().getSealed().add(sealed); - final DeckEditorBase editor = (DeckEditorBase) new DeckEditorLimited( - Singletons.getView().getFrame(), + final ACEditorBase editor = (ACEditorBase) new CEditorLimited( Singletons.getModel().getDecks().getSealed()); - editor.show(cmdExit); - editor.getController().setModel((T) sealed); - editor.setAlwaysOnTop(true); - editor.setVisible(true); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(editor); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); + editor.getDeckController().setModel((T) sealed); } } diff --git a/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java b/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java index 6a5a20ebeb9..33259fe8f36 100644 --- a/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java +++ b/src/main/java/forge/gui/home/sanctioned/VSubmenuConstructed.java @@ -60,10 +60,10 @@ public enum VSubmenuConstructed implements IVSubmenu { JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); private final FLabel btnHumanRandom = new FLabel.Builder().text("Random").fontSize(14).opaque(true) - .hoverable(true).fontScaleAuto(false).build(); + .hoverable(true).build(); private final FLabel btnAIRandom = new FLabel.Builder().text("Random").fontSize(14).opaque(true) - .hoverable(true).fontScaleAuto(false).build(); + .hoverable(true).build(); private VSubmenuConstructed() { // Radio button group: Human @@ -147,7 +147,7 @@ public enum VSubmenuConstructed implements IVSubmenu { // Add radio buttons: Human pnlRadiosHuman.setOpaque(false); pnlRadiosHuman.add(new FLabel.Builder().text("Select your deck:") - .fontStyle(Font.BOLD).fontScaleAuto(false).fontSize(16) + .fontStyle(Font.BOLD).fontSize(16) .fontAlign(SwingConstants.LEFT).build(), strRadioConstraints); pnlRadiosHuman.add(radColorsHuman, strRadioConstraints); pnlRadiosHuman.add(radThemesHuman, strRadioConstraints); @@ -157,7 +157,7 @@ public enum VSubmenuConstructed implements IVSubmenu { // Add radio buttons: AI pnlRadiosAI.setOpaque(false); pnlRadiosAI.add(new FLabel.Builder().text("Select an AI deck:") - .fontStyle(Font.BOLD).fontScaleAuto(false).fontSize(16) + .fontStyle(Font.BOLD).fontSize(16) .fontAlign(SwingConstants.LEFT).build(), strRadioConstraints); pnlRadiosAI.add(radColorsAI, strRadioConstraints); pnlRadiosAI.add(radThemesAI, strRadioConstraints); diff --git a/src/main/java/forge/gui/home/sanctioned/VSubmenuDraft.java b/src/main/java/forge/gui/home/sanctioned/VSubmenuDraft.java index ce834fef82c..4ebfef71a24 100644 --- a/src/main/java/forge/gui/home/sanctioned/VSubmenuDraft.java +++ b/src/main/java/forge/gui/home/sanctioned/VSubmenuDraft.java @@ -46,10 +46,10 @@ public enum VSubmenuDraft implements IVSubmenu { private final DeckLister lstHumanDecks = new DeckLister(GameType.Draft); private final JList lstAI = new FList(); private final JLabel btnBuildDeck = new FLabel.Builder() - .fontScaleAuto(false).fontSize(16) + .fontSize(16) .opaque(true).hoverable(true).text("Start A New Draft").build(); private final JLabel btnDirections = new FLabel.Builder() - .fontScaleAuto(false).fontSize(16) + .fontSize(16) .text("Click For Directions").fontAlign(SwingConstants.CENTER).build(); /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/sanctioned/VSubmenuSealed.java b/src/main/java/forge/gui/home/sanctioned/VSubmenuSealed.java index 28ccdaba898..fe31a1737f2 100644 --- a/src/main/java/forge/gui/home/sanctioned/VSubmenuSealed.java +++ b/src/main/java/forge/gui/home/sanctioned/VSubmenuSealed.java @@ -42,10 +42,10 @@ public enum VSubmenuSealed implements IVSubmenu { private final StartButton btnStart = new StartButton(); private final DeckLister lstDecks = new DeckLister(GameType.Sealed); private final JLabel btnBuildDeck = new FLabel.Builder() - .fontScaleAuto(false).fontSize(16) + .fontSize(16) .opaque(true).hoverable(true).text("Build a Sealed Deck").build(); private final JLabel btnDirections = new FLabel.Builder() - .fontScaleAuto(false).fontSize(16) + .fontSize(16) .text("Click For Directions").fontAlign(SwingConstants.CENTER).build(); /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java b/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java index 72785fee352..bacb6a72e7f 100644 --- a/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java +++ b/src/main/java/forge/gui/home/settings/VSubmenuPreferences.java @@ -55,7 +55,7 @@ public enum VSubmenuPreferences implements IVSubmenu { .hoverable(true).text("Reset to defaults").build(); private final FLabel lblTitleSkin = new FLabel.Builder() - .text("Choose Skin").fontScaleAuto(false).fontStyle(Font.BOLD).fontSize(14).build(); + .text("Choose Skin").fontStyle(Font.BOLD).fontSize(14).build(); private final JList lstChooseSkin = new FList(); private final FLabel lblChooseSkin = new FLabel.Builder().fontSize(12).fontStyle(Font.ITALIC) diff --git a/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java b/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java index 0e3c35af824..492a0e9d8b8 100644 --- a/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java +++ b/src/main/java/forge/gui/home/utilities/CSubmenuDeckEditor.java @@ -1,10 +1,9 @@ package forge.gui.home.utilities; import forge.Command; -import forge.Singletons; -import forge.deck.DeckBase; -import forge.gui.deckeditor.DeckEditorBase; -import forge.gui.deckeditor.DeckEditorConstructed; +import forge.control.FControl; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.CEditorConstructed; import forge.gui.home.ICSubmenu; /** @@ -44,13 +43,9 @@ public enum CSubmenuDeckEditor implements ICSubmenu { /** * Shows constructed mode editor. - * @param extends DeckBase */ - @SuppressWarnings("unchecked") - private void showDeckEditor() { - DeckEditorBase editor = - (DeckEditorBase) new DeckEditorConstructed(Singletons.getView().getFrame()); - editor.show(null); - editor.setVisible(true); + private void showDeckEditor() { + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(new CEditorConstructed()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_CONSTRUCTED); } } diff --git a/src/main/java/forge/gui/home/utilities/VSubmenuDeckEditor.java b/src/main/java/forge/gui/home/utilities/VSubmenuDeckEditor.java index 5f630154716..c1f62460d39 100644 --- a/src/main/java/forge/gui/home/utilities/VSubmenuDeckEditor.java +++ b/src/main/java/forge/gui/home/utilities/VSubmenuDeckEditor.java @@ -32,7 +32,7 @@ public enum VSubmenuDeckEditor implements IVSubmenu { pnl.add(new FLabel.Builder().text("Open Deck Editor").opaque(true) .hoverable(true).cmdClick(CSubmenuDeckEditor.SINGLETON_INSTANCE.getMenuCommand()) - .fontScaleAuto(false).fontSize(16).build(), "w 200px!, h 40px!"); + .fontSize(16).build(), "w 200px!, h 40px!"); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/utilities/VSubmenuExit.java b/src/main/java/forge/gui/home/utilities/VSubmenuExit.java index 4134fc8342b..c0c7e90c089 100644 --- a/src/main/java/forge/gui/home/utilities/VSubmenuExit.java +++ b/src/main/java/forge/gui/home/utilities/VSubmenuExit.java @@ -32,7 +32,7 @@ public enum VSubmenuExit implements IVSubmenu { pnl.add(new FLabel.Builder().text("Open Deck Editor").opaque(true) .hoverable(true).cmdClick(CSubmenuDeckEditor.SINGLETON_INSTANCE.getMenuCommand()) - .fontScaleAuto(false).fontSize(16).build(), "w 200px!, h 40px!"); + .fontSize(16).build(), "w 200px!, h 40px!"); } /* (non-Javadoc) diff --git a/src/main/java/forge/gui/home/utilities/VSubmenuUtilities.java b/src/main/java/forge/gui/home/utilities/VSubmenuUtilities.java index fe2fda22479..db0f6299d72 100644 --- a/src/main/java/forge/gui/home/utilities/VSubmenuUtilities.java +++ b/src/main/java/forge/gui/home/utilities/VSubmenuUtilities.java @@ -45,21 +45,21 @@ public enum VSubmenuUtilities implements IVSubmenu { private final JPanel pnl = new JPanel(); private final FLabel btnDownloadSetPics = new FLabel.Builder().opaque(true).hoverable(true) - .text("Download LQ Set Pictures").fontScaleFactor(0.5).build(); + .text("Download LQ Set Pictures").fontSize(14).build(); private final FLabel btnDownloadPics = new FLabel.Builder().opaque(true).hoverable(true) - .text("Download LQ Card Pictures").fontScaleFactor(0.5).build(); + .text("Download LQ Card Pictures").fontSize(14).build(); private final FLabel btnDownloadQuestImages = new FLabel.Builder().opaque(true).hoverable(true) - .text("Download Quest Images").fontScaleFactor(0.5).build(); + .text("Download Quest Images").fontSize(14).build(); private final FLabel btnReportBug = new FLabel.Builder().opaque(true).hoverable(true) - .text("Report a Bug").fontScaleFactor(0.5).build(); + .text("Report a Bug").fontSize(14).build(); private final FLabel btnImportPictures = new FLabel.Builder().opaque(true).hoverable(true) - .text("Import Pictures").fontScaleFactor(0.5).build(); + .text("Import Pictures").fontSize(14).build(); private final FLabel btnHowToPlay = new FLabel.Builder().opaque(true) - .hoverable(true).fontScaleFactor(0.5).text("How To Play").build(); + .hoverable(true).fontSize(14).text("How To Play").build(); private final FLabel btnDownloadPrices = new FLabel.Builder().opaque(true).hoverable(true) - .text("Download Card Prices").fontScaleFactor(0.5).build(); + .text("Download Card Prices").fontSize(14).build(); private final FLabel btnLicensing = new FLabel.Builder().opaque(true) - .hoverable(true).fontScaleFactor(0.5).text("License Details").build(); + .hoverable(true).fontSize(14).text("License Details").build(); /* (non-Javadoc) * @see forge.view.home.IViewSubmenu#populate() diff --git a/src/main/java/forge/gui/match/VMatchUI.java b/src/main/java/forge/gui/match/VMatchUI.java index 95ee255085c..054eadd5aad 100644 --- a/src/main/java/forge/gui/match/VMatchUI.java +++ b/src/main/java/forge/gui/match/VMatchUI.java @@ -4,20 +4,21 @@ import java.util.ArrayList; import java.util.List; import javax.swing.JButton; +import javax.swing.SwingUtilities; import forge.AllZone; +import forge.Singletons; import forge.gui.framework.DragCell; import forge.gui.framework.EDocID; import forge.gui.framework.IVDoc; import forge.gui.framework.IVTopLevelUI; -import forge.gui.framework.SIOUtil; -import forge.gui.framework.SResizingUtil; +import forge.gui.framework.SLayoutIO; +import forge.gui.framework.SRearrangingUtil; import forge.gui.match.nonsingleton.VField; import forge.gui.match.nonsingleton.VHand; -import forge.gui.match.views.VDetail; import forge.gui.match.views.VDev; import forge.gui.match.views.VMessage; -import forge.gui.match.views.VPicture; +import forge.properties.ForgePreferences.FPref; import forge.view.FView; /** @@ -34,96 +35,40 @@ public enum VMatchUI implements IVTopLevelUI { // Instantiate non-singleton tab instances private final IVDoc field0 = new VField(EDocID.FIELD_0, AllZone.getComputerPlayer()); private final IVDoc field1 = new VField(EDocID.FIELD_1, AllZone.getHumanPlayer()); - private final IVDoc field2 = new VField(EDocID.FIELD_2, AllZone.getComputerPlayer()); - private final IVDoc field3 = new VField(EDocID.FIELD_3, AllZone.getComputerPlayer()); private final IVDoc hand0 = new VHand(EDocID.HAND_0, AllZone.getComputerPlayer()); private final IVDoc hand1 = new VHand(EDocID.HAND_1, AllZone.getHumanPlayer()); - private final IVDoc hand2 = new VHand(EDocID.HAND_2, AllZone.getComputerPlayer()); - private final IVDoc hand3 = new VHand(EDocID.HAND_3, AllZone.getComputerPlayer()); - // Instantiate singleton tab instances - private final IVDoc stack = EDocID.REPORT_STACK.getDoc(); - private final IVDoc combat = EDocID.REPORT_COMBAT.getDoc(); - private final IVDoc log = EDocID.REPORT_LOG.getDoc(); - private final IVDoc players = EDocID.REPORT_PLAYERS.getDoc(); - private final IVDoc message = EDocID.REPORT_MESSAGE.getDoc(); - - private final IVDoc dock = EDocID.BUTTON_DOCK.getDoc(); - private final IVDoc detail = EDocID.CARD_DETAIL.getDoc(); - private final IVDoc picture = EDocID.CARD_PICTURE.getDoc(); - private final IVDoc antes = EDocID.CARD_ANTES.getDoc(); - private final IVDoc devmode = EDocID.DEV_MODE.getDoc(); // Other instantiations private final CMatchUI control = null; - private boolean isPopulated = false; /** */ @Override public void instantiate() { - } /** */ @Override public void populate() { - if (isPopulated) { return; } - else { isPopulated = true; } + SLayoutIO.loadLayout(null); - SIOUtil.loadLayout(null); - } + // Pull dev mode if necessary, remove parent cell if required. + if (!Singletons.getModel().getPreferences().getPrefBoolean(FPref.DEV_MODE_ENABLED)) { + VDev.SINGLETON_INSTANCE.getParentCell().removeDoc(VDev.SINGLETON_INSTANCE); + } - /** NEVER ACTUALLY CALLED; could be removed... */ - public void defaultLayout() { - final DragCell cell0 = new DragCell(); - final DragCell cell1 = new DragCell(); - final DragCell cell2 = new DragCell(); - final DragCell cell3 = new DragCell(); - final DragCell cell4 = new DragCell(); - final DragCell cell5 = new DragCell(); - final DragCell cell6 = new DragCell(); - - cell0.addDoc(stack); - cell0.addDoc(combat); - cell0.addDoc(log); - cell0.addDoc(players); - - cell1.addDoc(message); - cell1.addDoc(devmode); - - cell2.addDoc(field0); - cell6.addDoc(field1); - if (AllZone.getPlayersInGame().size() > 2) { cell2.addDoc(field2); } - if (AllZone.getPlayersInGame().size() > 3) { cell2.addDoc(field3); } - - if (AllZone.getPlayersInGame().size() > 1000) { cell3.addDoc(hand0); } - cell3.addDoc(hand1); - if (AllZone.getPlayersInGame().size() > 2) { cell2.addDoc(hand2); } - if (AllZone.getPlayersInGame().size() > 3) { cell2.addDoc(hand3); } - - cell4.addDoc(dock); - cell5.addDoc(detail); - cell5.addDoc(picture); - cell5.addDoc(antes); - - FView.SINGLETON_INSTANCE.addDragCell(cell0); - FView.SINGLETON_INSTANCE.addDragCell(cell1); - FView.SINGLETON_INSTANCE.addDragCell(cell2); - FView.SINGLETON_INSTANCE.addDragCell(cell3); - FView.SINGLETON_INSTANCE.addDragCell(cell4); - FView.SINGLETON_INSTANCE.addDragCell(cell5); - FView.SINGLETON_INSTANCE.addDragCell(cell6); - - cell0.setRoughBounds(0, 0, 0.2, 0.7); - cell1.setRoughBounds(0, 0.7, 0.2, 0.3); - cell2.setRoughBounds(0.2, 0, 0.6, 0.33); - cell3.setRoughBounds(0.2, 0.66, 0.6, 0.34); - cell4.setRoughBounds(0.8, 0, 0.2, 0.25); - cell5.setRoughBounds(0.8, 0.25, 0.2, 0.75); - cell6.setRoughBounds(0.2, 0.33, 0.6, 0.33); - - SResizingUtil.resizeWindow(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + for (final DragCell c : FView.SINGLETON_INSTANCE.getDragCells()) { + if (c.getDocs().size() == 0) { + SRearrangingUtil.fillGap(c); + FView.SINGLETON_INSTANCE.removeDragCell(c); + } + } + } + }); } //========== Retrieval methods @@ -133,38 +78,29 @@ public enum VMatchUI implements IVTopLevelUI { return this.control; } - /** @return {@link forge.gui.match.views.VDetail} */ - public VDetail getViewDetail() { - return ((VDetail) this.detail); - } - - /** @return {@link forge.gui.match.views.VPicture} */ - public VPicture getViewPicture() { - return ((VPicture) this.picture); - } - - /** @return {@link forge.gui.match.views.VDev} */ - public VDev getViewDevMode() { - return ((VDev) this.devmode); - } - /** @return {@link java.util.List}<{@link forge.gui.match.nonsigleton.VField}> */ public List getFieldViews() { final List lst = new ArrayList(); lst.add((VField) field0); lst.add((VField) field1); - //lst.add((VField) field2); - //lst.add((VField) field3); + return lst; + } + + /** @return {@link java.util.List}<{@link forge.gui.match.nonsigleton.VHand}> */ + public List getHandViews() { + final List lst = new ArrayList(); + lst.add((VHand) hand0); + lst.add((VHand) hand1); return lst; } /** @return {@link javax.swing.JButton} */ public JButton getBtnCancel() { - return ((VMessage) this.message).getBtnCancel(); + return VMessage.SINGLETON_INSTANCE.getBtnCancel(); } /** @return {@link javax.swing.JButton} */ public JButton getBtnOK() { - return ((VMessage) this.message).getBtnOK(); + return VMessage.SINGLETON_INSTANCE.getBtnOK(); } } diff --git a/src/main/java/forge/gui/match/ViewWinLose.java b/src/main/java/forge/gui/match/ViewWinLose.java index 26dbc0afb33..86c8d603b2c 100644 --- a/src/main/java/forge/gui/match/ViewWinLose.java +++ b/src/main/java/forge/gui/match/ViewWinLose.java @@ -151,7 +151,7 @@ public class ViewWinLose { pnlLog.setOpaque(false); pnlLog.add(new FLabel.Builder().text("Game Log").fontAlign(SwingConstants.CENTER) - .fontScaleFactor(0.8).fontStyle(Font.BOLD).build(), + .fontSize(18).fontStyle(Font.BOLD).build(), "w 300px!, h 28px!, gap 0 0 20px 0"); pnlLog.add(scrLog, "w 300px!, h 100px!, gap 0 0 10px 0"); diff --git a/src/main/java/forge/gui/match/controllers/CDock.java b/src/main/java/forge/gui/match/controllers/CDock.java index f1a8fa72716..a995809ab71 100644 --- a/src/main/java/forge/gui/match/controllers/CDock.java +++ b/src/main/java/forge/gui/match/controllers/CDock.java @@ -39,7 +39,7 @@ import forge.deck.Deck; import forge.gui.ForgeAction; import forge.gui.SOverlayUtils; import forge.gui.framework.ICDoc; -import forge.gui.framework.SIOUtil; +import forge.gui.framework.SLayoutIO; import forge.gui.match.views.VDock; import forge.gui.toolbox.SaveOpenDialog; import forge.gui.toolbox.SaveOpenDialog.Filetypes; @@ -68,7 +68,7 @@ public enum CDock implements ICDoc { public void endTurn() { Singletons.getModel().getGameState().getPhaseHandler().autoPassToCleanup(); } - + private void revertLayout() { SOverlayUtils.genericOverlay(); FView.SINGLETON_INSTANCE.getPnlContent().removeAll(); @@ -76,23 +76,23 @@ public enum CDock implements ICDoc { final SwingWorker w = new SwingWorker() { @Override public Void doInBackground() { - SIOUtil.loadLayout(new File(SIOUtil.FILE_DEFAULT)); + SLayoutIO.loadLayout(null); SOverlayUtils.hideOverlay(); return null; } }; w.execute(); } - + private void saveLayout() { - final SwingWorker w = new SwingWorker() { + final SwingWorker w = new SwingWorker() { @Override public Void doInBackground() { - SaveOpenDialog dlgSave = new SaveOpenDialog(); - File DefFile = new File(SIOUtil.FILE_PREFERRED); - File SaveFile = dlgSave.SaveDialog(DefFile, Filetypes.LAYOUT); - if (SaveFile!=null) { - SIOUtil.saveLayout(SaveFile); + final SaveOpenDialog dlgSave = new SaveOpenDialog(); + final File defFile = new File(SLayoutIO.getFilePreferred()); + final File saveFile = dlgSave.SaveDialog(defFile, Filetypes.LAYOUT); + if (saveFile != null) { + SLayoutIO.saveLayout(saveFile); } return null; } @@ -103,26 +103,24 @@ public enum CDock implements ICDoc { private void openLayout() { SOverlayUtils.genericOverlay(); FView.SINGLETON_INSTANCE.getPnlContent().removeAll(); - - - final SwingWorker w = new SwingWorker() { + + final SwingWorker w = new SwingWorker() { @Override public Void doInBackground() { - SaveOpenDialog dlgOpen = new SaveOpenDialog(); - File DefFile = new File(SIOUtil.FILE_PREFERRED); - File LoadFile = dlgOpen.OpenDialog(DefFile, Filetypes.LAYOUT); - - if (LoadFile!=null) { - SIOUtil.loadLayout(LoadFile); - SIOUtil.saveLayout(null); + final SaveOpenDialog dlgOpen = new SaveOpenDialog(); + final File defFile = new File(SLayoutIO.getFilePreferred()); + final File loadFile = dlgOpen.OpenDialog(defFile, Filetypes.LAYOUT); + + if (loadFile != null) { + SLayoutIO.loadLayout(loadFile); + SLayoutIO.saveLayout(null); } - + SOverlayUtils.hideOverlay(); return null; } }; - w.execute(); - + w.execute(); } /** @@ -244,12 +242,12 @@ public enum CDock implements ICDoc { .addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { revertLayout(); } }); - + VDock.SINGLETON_INSTANCE.getBtnOpenLayout() .addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { openLayout(); } }); - + VDock.SINGLETON_INSTANCE.getBtnSaveLayout() .addMouseListener(new MouseAdapter() { @Override public void mousePressed(final MouseEvent e) { diff --git a/src/main/java/forge/gui/match/nonsingleton/VField.java b/src/main/java/forge/gui/match/nonsingleton/VField.java index f1a3f1b6337..b178512e76c 100644 --- a/src/main/java/forge/gui/match/nonsingleton/VField.java +++ b/src/main/java/forge/gui/match/nonsingleton/VField.java @@ -314,7 +314,7 @@ public class VField implements IVDoc { private FLabel getBuiltFLabel(SkinProp p0, String s0, String s1) { return new FLabel.Builder().icon(new ImageIcon(FSkin.getImage(p0))) - .opaque(false).fontScaleAuto(false).fontSize(14) + .opaque(false).fontSize(14) .fontStyle(Font.BOLD).iconAlpha(0.6f).iconInBackground(true) .text(s0).tooltip(s1).fontAlign(SwingConstants.RIGHT).build(); } diff --git a/src/main/java/forge/gui/match/views/VMessage.java b/src/main/java/forge/gui/match/views/VMessage.java index ed91e05ed71..326e1b586c6 100644 --- a/src/main/java/forge/gui/match/views/VMessage.java +++ b/src/main/java/forge/gui/match/views/VMessage.java @@ -53,7 +53,7 @@ public enum VMessage implements IVDoc { private final JButton btnOK = new FButton("OK"); private final JButton btnCancel = new FButton("Cancel"); private final JTextArea tarMessage = new JTextArea(); - private final JLabel lblGames = new FLabel.Builder().fontScaleAuto(false) + private final JLabel lblGames = new FLabel.Builder() .fontSize(12).fontStyle(Font.BOLD).fontAlign(SwingConstants.CENTER).build(); //========= Constructor diff --git a/src/main/java/forge/gui/toolbox/CardFaceSymbols.java b/src/main/java/forge/gui/toolbox/CardFaceSymbols.java index 21fe0240f2f..9d4b0bdc0d8 100644 --- a/src/main/java/forge/gui/toolbox/CardFaceSymbols.java +++ b/src/main/java/forge/gui/toolbox/CardFaceSymbols.java @@ -20,12 +20,15 @@ package forge.gui.toolbox; import java.awt.Graphics; import java.awt.Image; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.StringTokenizer; import com.esotericsoftware.minlog.Log; +import forge.card.CardManaCost; +import forge.card.mana.ManaCostShard; import forge.view.arcane.util.UI; /** @@ -130,22 +133,27 @@ public class CardFaceSymbols { * @param y * a int. */ - public static void draw(Graphics g, String manaCost, int x, int y) { - if (manaCost.length() == 0) { + public static void draw(Graphics g, CardManaCost manaCost, int x, int y) { + if (manaCost.isEmpty()) { return; } - manaCost = UI.getDisplayManaCost(manaCost); - StringTokenizer tok = new StringTokenizer(manaCost, " "); - while (tok.hasMoreTokens()) { - String symbol = tok.nextToken(); - Image image = MANA_IMAGES.get(symbol); - if (image == null) { - Log.info("Symbol not recognized \"" + symbol + "\" in mana cost: " + manaCost); - continue; - } - g.drawImage(image, x, y, null); - x += symbol.length() > 2 ? 10 : 14; // slash.png is only 10 pixels - // wide. + + + final int genericManaCost = manaCost.getGenericCost(); + final boolean hasGeneric = (genericManaCost > 0) || manaCost.isPureGeneric(); + final List shards = manaCost.getShards(); + + int xpos = x; + final int offset = 14; + if (hasGeneric) { + final String sGeneric = Integer.toString(genericManaCost); + CardFaceSymbols.drawSymbol(sGeneric, g, xpos, y); + xpos += offset; + } + + for (final ManaCostShard s : shards) { + CardFaceSymbols.drawSymbol(s.getImageKey(), g, xpos, y); + xpos += offset; } } @@ -224,14 +232,19 @@ public class CardFaceSymbols { * a {@link java.lang.String} object. * @return a int. */ - public static int getWidth(final String manaCost) { - int width = 0; + public static int getWidth(final CardManaCost manaCost) { + int width = manaCost.getShards().size(); + if ( manaCost.getGenericCost() > 0 || ( manaCost.getGenericCost() == 0 && width == 0 ) ); + width++; + + /* StringTokenizer tok = new StringTokenizer(manaCost, " "); while (tok.hasMoreTokens()) { String symbol = tok.nextToken(); width += symbol.length() > 2 ? 10 : 14; // slash.png is only 10 // pixels wide. } - return width; + */ + return width * 14; } } diff --git a/src/main/java/forge/gui/toolbox/DeckLister.java b/src/main/java/forge/gui/toolbox/DeckLister.java index 3b7d7115040..b91996b5225 100644 --- a/src/main/java/forge/gui/toolbox/DeckLister.java +++ b/src/main/java/forge/gui/toolbox/DeckLister.java @@ -2,7 +2,9 @@ * Forge: Play Magic: the Gathering. * Copyright (C) 2011 Nate * - * This program is free software: you can redistribute it and/or modify + * This prog +import forge.gui.deckeditor.CDeckEditorUI; +ram 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. @@ -24,27 +26,31 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; + import javax.swing.ImageIcon; import javax.swing.JButton; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.border.MatteBorder; +import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Command; import forge.Constant; import forge.Singletons; +import forge.control.FControl; import forge.deck.CardCollections; import forge.deck.Deck; +import forge.deck.DeckBase; import forge.game.GameType; -import forge.gui.SOverlayUtils; -import forge.gui.deckeditor.DeckEditorConstructed; -import forge.gui.deckeditor.DeckEditorLimited; -import forge.gui.deckeditor.DeckEditorQuest; -import net.miginfocom.swing.MigLayout; +import forge.gui.deckeditor.CDeckEditorUI; +import forge.gui.deckeditor.controllers.ACEditorBase; +import forge.gui.deckeditor.controllers.CEditorConstructed; +import forge.gui.deckeditor.controllers.CEditorLimited; +import forge.gui.deckeditor.controllers.CEditorQuest; +import forge.gui.framework.ILocalRepaint; /** * Creates deck list for selected decks for quick deleting, editing, and basic @@ -52,7 +58,7 @@ import net.miginfocom.swing.MigLayout; * */ @SuppressWarnings("serial") -public class DeckLister extends JPanel { +public class DeckLister extends JPanel implements ILocalRepaint { private final ImageIcon icoDelete; private final ImageIcon icoDeleteOver; private final ImageIcon icoEdit; @@ -60,7 +66,7 @@ public class DeckLister extends JPanel { private RowPanel previousSelect; private RowPanel[] rows; private final GameType gametype; - private Command cmdEditorExit, cmdDelete, cmdRowSelect; + private Command cmdDelete, cmdRowSelect; private final Color clrDefault, clrHover, clrActive, clrBorders; /** @@ -87,7 +93,6 @@ public class DeckLister extends JPanel { public DeckLister(final GameType gt0, final Command cmd0) { super(); this.gametype = gt0; - this.cmdEditorExit = cmd0; this.clrDefault = new Color(0, 0, 0, 0); this.clrHover = FSkin.getColor(FSkin.Colors.CLR_HOVER); @@ -97,10 +102,10 @@ public class DeckLister extends JPanel { this.setOpaque(false); this.setLayout(new MigLayout("insets 0, gap 0, wrap")); - this.icoDelete = FSkin.getIcon(FSkin.ForgeIcons.ICO_DELETE); - this.icoDeleteOver = FSkin.getIcon(FSkin.ForgeIcons.ICO_DELETE_OVER); - this.icoEdit = FSkin.getIcon(FSkin.ForgeIcons.ICO_EDIT); - this.icoEditOver = FSkin.getIcon(FSkin.ForgeIcons.ICO_EDIT_OVER); + this.icoDelete = FSkin.getIcon(FSkin.InterfaceIcons.ICO_DELETE); + this.icoDeleteOver = FSkin.getIcon(FSkin.InterfaceIcons.ICO_DELETE_OVER); + this.icoEdit = FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT); + this.icoEditOver = FSkin.getIcon(FSkin.InterfaceIcons.ICO_EDIT_OVER); } /** @@ -118,18 +123,22 @@ public class DeckLister extends JPanel { // scroll panes will have difficulty dynamically resizing if 100% width // is set. final JPanel rowTitle = new TitlePanel(); - rowTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_ZEBRA)); + rowTitle.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); rowTitle.setLayout(new MigLayout("insets 0, gap 0")); rowTitle.add(new FLabel.Builder().text("Delete").fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Edit").fontAlign(SwingConstants.CENTER).build(), + rowTitle.add(new FLabel.Builder().text("Edit") + .fontSize(14).fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Deck Name").fontAlign(SwingConstants.CENTER).build(), - "w 60%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Main").fontAlign(SwingConstants.CENTER).build(), + rowTitle.add(new FLabel.Builder().text("Deck Name") + .fontSize(14).fontAlign(SwingConstants.CENTER).build(), + "w 58%!, h 20px!, gaptop 5px"); + rowTitle.add(new FLabel.Builder().text("Main") + .fontSize(14).fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); - rowTitle.add(new FLabel.Builder().text("Side").fontAlign(SwingConstants.CENTER).build(), + rowTitle.add(new FLabel.Builder().text("Side") + .fontSize(14).fontAlign(SwingConstants.CENTER).build(), "w 10%!, h 20px!, gaptop 5px"); this.add(rowTitle, "w 98%!, h 30px!, gapleft 1%"); @@ -142,7 +151,7 @@ public class DeckLister extends JPanel { row = new RowPanel(d); row.add(new DeleteButton(row), "w 10%!, h 20px!, gaptop 5px"); row.add(new EditButton(row), "w 10%!, h 20px!, gaptop 5px"); - row.add(new GenericLabel(d.getName()), "w 60%!, h 20px!, gaptop 5px"); + row.add(new GenericLabel(d.getName()), "w 58%!, h 20px!, gaptop 5px"); row.add(new MainLabel(String.valueOf(d.getMain().countAll())), "w 10%, h 20px!, gaptop 5px"); row.add(new GenericLabel(String.valueOf(d.getSideboard().countAll())), "w 10%!, h 20px!, gaptop 5px"); this.add(row, "w 98%!, h 30px!, gapleft 1%"); @@ -169,7 +178,8 @@ public class DeckLister extends JPanel { } /** Prevent panel from repainting the whole screen. */ - public void repaintOnlyThisPanel() { + @Override + public void repaintThis() { final Dimension d = DeckLister.this.getSize(); this.repaint(0, 0, d.width, d.height); } @@ -400,15 +410,6 @@ public class DeckLister extends JPanel { this.cmdRowSelect = c0; } - /** - * Sets the exit command. - * - * @param c0   {@link forge.Command} command executed on editor exit. - */ - public void setExitCommand(final Command c0) { - this.cmdEditorExit = c0; - } - private void selectHandler(final RowPanel r0) { if (this.previousSelect != null) { this.previousSelect.setSelected(false); @@ -420,41 +421,39 @@ public class DeckLister extends JPanel { this.cmdRowSelect.execute(); } } - - private void editDeck(final Deck d0) { - SOverlayUtils.showOverlay(); - - JFrame mainFrame = Singletons.getView().getFrame(); + @SuppressWarnings("unchecked") + private void editDeck(final Deck d0) { switch (this.gametype) { case Quest: - Constant.Runtime.HUMAN_DECK[0] = d0; - final DeckEditorQuest editor = new DeckEditorQuest(mainFrame, AllZone.getQuest()); - editor.show(this.cmdEditorExit); - editor.setVisible(true); - break; + Constant.Runtime.HUMAN_DECK[0] = d0; + final CEditorQuest qEditor = new CEditorQuest(AllZone.getQuest()); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(qEditor); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_QUEST); + break; case Constructed: - final DeckEditorConstructed cEditor = - new DeckEditorConstructed(mainFrame); - cEditor.show(this.cmdEditorExit); - cEditor.getController().load(d0.getName()); - cEditor.setVisible(true); - break; - case Sealed: - final DeckEditorLimited sEditor = - new DeckEditorLimited(mainFrame, Singletons.getModel().getDecks().getSealed()); - sEditor.show(this.cmdEditorExit); - sEditor.getController().load(d0.getName()); - sEditor.setVisible(true); - break; - case Draft: - final DeckEditorLimited dEditor = - new DeckEditorLimited(mainFrame, Singletons.getModel().getDecks().getDraft()); - dEditor.show(this.cmdEditorExit); - dEditor.getController().load(d0.getName()); - dEditor.setVisible(true); - break; - default: - break; + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(new CEditorConstructed()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_CONSTRUCTED); + CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckController().load(d0.getName()); + break; + case Sealed: + final ACEditorBase sEditor = (ACEditorBase) + new CEditorLimited(Singletons.getModel().getDecks().getSealed()); + + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(sEditor); + + sEditor.getDeckController().load(d0.getName()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); + break; + case Draft: + final ACEditorBase dEditor = (ACEditorBase) + new CEditorLimited(Singletons.getModel().getDecks().getDraft()); + CDeckEditorUI.SINGLETON_INSTANCE.setCurrentEditorController(dEditor); + + dEditor.getDeckController().load(d0.getName()); + FControl.SINGLETON_INSTANCE.changeState(FControl.DECK_EDITOR_LIMITED); + break; + default: + break; } } @@ -482,7 +481,7 @@ public class DeckLister extends JPanel { } this.remove(r0); - this.repaintOnlyThisPanel(); + this.repaintThis(); this.revalidate(); if (this.cmdDelete != null) { diff --git a/src/main/java/forge/gui/toolbox/FLabel.java b/src/main/java/forge/gui/toolbox/FLabel.java index 3129295760a..9c05bacd0f3 100644 --- a/src/main/java/forge/gui/toolbox/FLabel.java +++ b/src/main/java/forge/gui/toolbox/FLabel.java @@ -7,6 +7,7 @@ import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; +import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; @@ -48,18 +49,17 @@ public class FLabel extends JLabel { */ public static class Builder extends FLabel { //========== Default values for FLabel are set here. - private double bldFontScaleFactor = 0.6; private double bldIconScaleFactor = 0.8; - private int bldFontScaleBy = SwingConstants.VERTICAL; private int bldFontStyle = Font.PLAIN; private int bldFontSize = 14; private float bldIconAlpha = 1.0f; + private int bldIconAlignX = SwingConstants.LEFT; + private Point bldIconInsets = new Point(0, 0); private boolean bldSelectable = false; private boolean bldHoverable = false; private boolean bldOpaque = false; private boolean bldIconInBackground = false; - private boolean bldFontScaleAuto = true; private boolean bldIconScaleAuto = true; private String bldText, bldToolTip; @@ -74,71 +74,69 @@ public class FLabel extends JLabel { // Begin builder methods. /**@param s0   {@link java.lang.String} * @return {@link forge.gui.toolbox.Builder} */ - public Builder text(String s0) { this.bldText = s0; return this; } + public Builder text(final String s0) { this.bldText = s0; return this; } /**@param s0   {@link java.lang.String} * @return {@link forge.gui.toolbox.Builder} */ - public Builder tooltip(String s0) { this.bldToolTip = s0; return this; } + public Builder tooltip(final String s0) { this.bldToolTip = s0; return this; } /**@param i0   {@link javax.swing.ImageIcon} * @return {@link forge.gui.toolbox.Builder} */ - public Builder icon(ImageIcon i0) { this.bldIcon = i0; return this; } + public Builder icon(final ImageIcon i0) { this.bldIcon = i0; return this; } /**@param i0   SwingConstants.CENTER, .LEFT, or .RIGHT * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontAlign(int i0) { this.bldFontAlign = i0; return this; } + public Builder fontAlign(final int i0) { this.bldFontAlign = i0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder opaque(boolean b0) { this.bldOpaque = b0; return this; } + public Builder opaque(final boolean b0) { this.bldOpaque = b0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder hoverable(boolean b0) { this.bldHoverable = b0; return this; } + public Builder hoverable(final boolean b0) { this.bldHoverable = b0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder selectable(boolean b0) { this.bldSelectable = b0; return this; } + public Builder selectable(final boolean b0) { this.bldSelectable = b0; return this; } /**@param c0   {@link forge.Command} to execute if clicked * @return {@link forge.gui.toolbox.Builder} */ - public Builder cmdClick(Command c0) { this.bldCmd = c0; return this; } + public Builder cmdClick(final Command c0) { this.bldCmd = c0; return this; } /**@param i0   int * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontSize(int i0) { this.bldFontSize = i0; return this; } + public Builder fontSize(final int i0) { this.bldFontSize = i0; return this; } /**@param i0   Font.PLAIN, Font.BOLD, or Font.ITALIC * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontStyle(int i0) { this.bldFontStyle = i0; return this; } + public Builder fontStyle(final int i0) { this.bldFontStyle = i0; return this; } /**@param b0   boolean * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontScaleAuto(boolean b0) { this.bldFontScaleAuto = b0; return this; } - - /**@param d0   double between 0 and 1, 0.6 by default - * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontScaleFactor(double d0) { this.bldFontScaleFactor = d0; return this; } - - /**@param i0   SwingConstants.HORIZONTAL or .VERTICAL - * @return {@link forge.gui.toolbox.Builder} */ - public Builder fontScaleBy(int i0) { this.bldFontScaleBy = i0; return this; } - - /**@param b0   boolean - * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconScaleAuto(boolean b0) { this.bldIconScaleAuto = b0; return this; } + public Builder iconScaleAuto(final boolean b0) { this.bldIconScaleAuto = b0; return this; } /**@param d0   double between 0 and 1, 0.8 by default * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconScaleFactor(double d0) { this.bldIconScaleFactor = d0; return this; } + public Builder iconScaleFactor(final double d0) { this.bldIconScaleFactor = d0; return this; } /**@param b0   boolean, icon will be drawn independent of text * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconInBackground(boolean b0) { this.bldIconInBackground = b0; return this; } + public Builder iconInBackground(final boolean b0) { this.bldIconInBackground = b0; return this; } /**@param f0   0.0f - 1.0f. If icon is in background, this alpha is applied. * @return {@link forge.gui.toolbox.Builder} */ - public Builder iconAlpha(float f0) { this.bldIconAlpha = f0; return this; } + public Builder iconAlpha(final float f0) { this.bldIconAlpha = f0; return this; } + + /**@param i0   Int. Only available for background icon. + * SwingConstants.HORIZONTAL .VERTICAL or .CENTER + * @return {@link forge.gui.toolbox.Builder} */ + public Builder iconAlignX(final int i0) { this.bldIconAlignX = i0; return this; } + + /**@param i0   Point. Only available for background icon. + * Additional padding to top left corner of icon, after alignX. + * @return {@link forge.gui.toolbox.Builder} */ + public Builder iconInsets(final Point i0) { this.bldIconInsets = i0; return this; } } //========== Constructors @@ -146,20 +144,19 @@ public class FLabel extends JLabel { protected FLabel() { } // Call this using FLabel.Builder()... - private FLabel(Builder b0) { + private FLabel(final Builder b0) { super(b0.bldText); // Init fields from builder - this.fontScaleFactor = b0.bldFontScaleFactor; this.iconScaleFactor = b0.bldIconScaleFactor; this.opaque = b0.bldOpaque; this.iconInBackground = b0.bldIconInBackground; - this.fontScaleAuto = b0.bldFontScaleAuto; this.iconScaleAuto = b0.bldIconScaleAuto; this.selectable = b0.bldSelectable; + this.iconAlignX = b0.bldIconAlignX; + this.iconInsets = b0.bldIconInsets; - this.setFontScaleBy(b0.bldFontScaleBy); this.setFontStyle(b0.bldFontStyle); this.setFontSize(b0.bldFontSize); this.setIconAlpha(b0.bldIconAlpha); @@ -193,46 +190,47 @@ public class FLabel extends JLabel { // Custom properties, assigned either at realization (using builder) // or dynamically (using methods below). - private double fontScaleFactor, iconScaleFactor; - private int fontScaleBy, fontStyle; + private double iconScaleFactor; + private int fontStyle, iconAlignX; private boolean selectable, selected, hoverable, hovered, opaque, - iconInBackground, fontScaleAuto, iconScaleAuto; + iconInBackground, iconScaleAuto; + private Point iconInsets; // Various variables used in image rendering. private Image img; private Graphics2D g2d; private Command cmdClick; - private int x, y, w, h, iw, ih, sw, sh, ref; + private int x, y, w, h, iw, ih, sw, sh; private double iar; private AlphaComposite alphaDim, alphaStrong; private final ActionListener fireResize = new ActionListener() { @Override - public void actionPerformed(ActionEvent evt) { resize(); resizeTimer.stop(); } + public void actionPerformed(final ActionEvent evt) { resize(); resizeTimer.stop(); } }; - private Timer resizeTimer = new Timer(10, fireResize); + private final Timer resizeTimer = new Timer(10, fireResize); // Resize adapter; on a timer to prevent resizing while "sliding" between sizes private final ComponentAdapter cadResize = new ComponentAdapter() { @Override - public void componentResized(ComponentEvent e) { resizeTimer.restart(); } + public void componentResized(final ComponentEvent e) { resizeTimer.restart(); } }; // Mouse event handler private final MouseAdapter madEvents = new MouseAdapter() { @Override - public void mouseEntered(MouseEvent e) { + public void mouseEntered(final MouseEvent e) { hovered = true; repaintOnlyThisLabel(); } @Override - public void mouseExited(MouseEvent e) { + public void mouseExited(final MouseEvent e) { hovered = false; repaintOnlyThisLabel(); } @Override - public void mouseClicked(MouseEvent e) { + public void mouseClicked(final MouseEvent e) { if (cmdClick != null && FLabel.this.isEnabled()) { cmdClick.execute(); } if (!selectable) { return; } if (selected) { setSelected(false); } @@ -243,7 +241,7 @@ public class FLabel extends JLabel { //========== Methods /** @param b0   boolean */ // Must be public. - public void setHoverable(boolean b0) { + public void setHoverable(final boolean b0) { this.hoverable = b0; if (!b0) { this.removeMouseListener(madEvents); } else { this.addMouseListener(madEvents); } @@ -251,7 +249,7 @@ public class FLabel extends JLabel { /** @param b0   boolean */ // Must be public. - public void setSelected(boolean b0) { + public void setSelected(final boolean b0) { this.selected = b0; repaintOnlyThisLabel(); } @@ -259,24 +257,12 @@ public class FLabel extends JLabel { /** Sets alpha if icon is in background. * @param f0   float */ // NOT public; must be set when label is built. - private void setIconAlpha(float f0) { + private void setIconAlpha(final float f0) { this.alphaDim = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, f0); this.alphaStrong = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f); } - /** @param i0   int, must be SwingConstants.HORIZONTAL or VERTICAL */ - // NOT public; must be set when label is built. - private void setFontScaleBy(int i0) { - if (i0 != SwingConstants.HORIZONTAL && i0 != SwingConstants.VERTICAL) { - throw new IllegalArgumentException("FLabel$setScaleBy " - + "must be passed either SwingConstants.HORIZONTAL " - + "or SwingConstants.VERTICAL."); - } - - this.fontScaleBy = i0; - } - - private void setFontSize(int i0) { + private void setFontSize(final int i0) { switch(this.fontStyle) { case Font.BOLD: this.setFont(FSkin.getBoldFont(i0)); break; case Font.ITALIC: this.setFont(FSkin.getItalicFont(i0)); break; @@ -286,7 +272,7 @@ public class FLabel extends JLabel { /** @param i0   Font.PLAIN, .BOLD, or .ITALIC */ // NOT public; must be set when label is built. - private void setFontStyle(int i0) { + private void setFontStyle(final int i0) { if (i0 != Font.PLAIN && i0 != Font.BOLD && i0 != Font.ITALIC) { throw new IllegalArgumentException("FLabel$setFontStyle " + "must be passed either Font.PLAIN, Font.BOLD, or Font.ITALIC."); @@ -296,7 +282,7 @@ public class FLabel extends JLabel { /** @param i0   SwingConstants.CENTER, .LEFT or .RIGHT */ // NOT public; must be set when label is built. - private void setFontAlign(int i0) { + private void setFontAlign(final int i0) { if (i0 != SwingConstants.CENTER && i0 != SwingConstants.LEFT && i0 != SwingConstants.RIGHT) { throw new IllegalArgumentException("FLabel$setFontStyle " + "must be passed either SwingConstants.CENTER, " @@ -345,7 +331,7 @@ public class FLabel extends JLabel { } /** @param c0   {@link forge.Command} on click */ - public void setCommand(Command c0) { + public void setCommand(final Command c0) { this.cmdClick = c0; } @@ -363,7 +349,7 @@ public class FLabel extends JLabel { } @Override - public void paintComponent(Graphics g) { + public void paintComponent(final Graphics g) { g2d = (Graphics2D) g.create(); w = getWidth(); h = getHeight(); @@ -388,10 +374,16 @@ public class FLabel extends JLabel { // Icon in background if (iconInBackground) { - x = 3; - sh = (int) ((h - 2 * x) * iconScaleFactor); + sh = (int) (h * iconScaleFactor); sw = (int) (sh * iar); - y = (int) ((h - sh) / 2); + + if (iconAlignX == SwingConstants.CENTER) { + x = (int) ((w - sw) / 2 + iconInsets.getX()); + } + else { + x = (int) iconInsets.getX(); + } + y = (int) (((h - sh) / 2) + iconInsets.getY()); if (hoverable && hovered && !selected) { g2d.setComposite(alphaStrong); @@ -406,24 +398,10 @@ public class FLabel extends JLabel { } private void resize() { - if (fontScaleAuto) { - ref = (fontScaleBy == SwingConstants.VERTICAL ? getHeight() : getWidth()); - switch (fontStyle) { - case Font.BOLD: - setFont(FSkin.getBoldFont((int) (ref * fontScaleFactor))); - break; - case Font.ITALIC: - setFont(FSkin.getItalicFont((int) (ref * fontScaleFactor))); - break; - default: - setFont(FSkin.getFont((int) (ref * fontScaleFactor))); - } - } - // Non-background icon if (img != null && iconScaleAuto && !iconInBackground) { h = (int) (getHeight() * iconScaleFactor); - w = (int) (h * iar * iconScaleFactor); + w = (int) (h * iar); if (w == 0 || h == 0) { return; } FLabel.super.setIcon(new ImageIcon(img.getScaledInstance(w, h, Image.SCALE_SMOOTH))); diff --git a/src/main/java/forge/gui/toolbox/FSkin.java b/src/main/java/forge/gui/toolbox/FSkin.java index 2d5ec0dbdb1..7345eb0153a 100644 --- a/src/main/java/forge/gui/toolbox/FSkin.java +++ b/src/main/java/forge/gui/toolbox/FSkin.java @@ -2,7 +2,9 @@ * Forge: Play Magic: the Gathering. * Copyright (C) 2011 Forge Team * - * This program is free software: you can redistribute it and/or modify + * +import forge.view.SplashFrame; + 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. @@ -214,8 +216,8 @@ public enum FSkin { ICO_ENDTURN (new int[] {320, 640, 80, 80}), /** */ ICO_CONCEDE (new int[] {240, 640, 80, 80}), /** */ ICO_REVERTLAYOUT (new int[] {400, 720, 80, 80}), /** */ - ICO_OPENLAYOUT (new int[] {480, 640, 80, 80}), - ICO_SAVELAYOUT (new int[] {480, 720, 80, 80}), + ICO_OPENLAYOUT (new int[] {0, 800, 80, 80}), /** */ + ICO_SAVELAYOUT (new int[] {80, 800, 80, 80}), /** */ ICO_DECKLIST (new int[] {400, 640, 80, 80}); private int[] coords; @@ -257,19 +259,24 @@ public enum FSkin { } /** */ - public enum ForgeIcons implements SkinProp { /** */ - ICO_EDIT (new int[] {640, 500, 20, 20}), /** */ - ICO_EDIT_OVER (new int[] {660, 500, 20, 20}), /** */ + public enum InterfaceIcons implements SkinProp { /** */ ICO_DELETE (new int[] {640, 480, 20, 20}), /** */ ICO_DELETE_OVER (new int[] {660, 480, 20, 20}), /** */ + ICO_EDIT (new int[] {640, 500, 20, 20}), /** */ + ICO_EDIT_OVER (new int[] {660, 500, 20, 20}), /** */ + ICO_OPEN (new int[] {660, 520, 20, 20}), /** */ + ICO_MINUS (new int[] {660, 620, 20, 20}), /** */ + ICO_NEW (new int[] {660, 540, 20, 20}), /** */ + ICO_PLUS (new int[] {660, 600, 20, 20}), /** */ + ICO_SAVE (new int[] {660, 560, 20, 20}), /** */ + ICO_SAVEAS (new int[] {660, 580, 20, 20}), /** */ ICO_UNKNOWN (new int[] {80, 720, 80, 80}), /** */ ICO_LOGO (new int[] {480, 0, 200, 200}), /** */ - ICO_DEFAULT_MAGE (new int[] {0, 720, 80, 80}), /** */ ICO_FAVICON (new int[] {0, 640, 80, 80}); private int[] coords; /** @param xy   int[] coordinates */ - ForgeIcons(final int[] xy) { this.coords = xy; } + InterfaceIcons(final int[] xy) { this.coords = xy; } /** @return int[] */ public int[] getCoords() { return coords; } } @@ -277,11 +284,11 @@ public enum FSkin { /** */ public enum LayoutImages implements SkinProp { /** */ IMG_HANDLE (new int[] {320, 450, 80, 20}), /** */ - IMG_CUR_L (new int[] {644, 524, 32, 32}), /** */ - IMG_CUR_R (new int[] {644, 564, 32, 32}), /** */ - IMG_CUR_T (new int[] {644, 604, 32, 32}), /** */ - IMG_CUR_B (new int[] {644, 644, 32, 32}), /** */ - IMG_CUR_TAB (new int[] {644, 684, 32, 32}); + IMG_CUR_L (new int[] {564, 724, 32, 32}), /** */ + IMG_CUR_R (new int[] {564, 764, 32, 32}), /** */ + IMG_CUR_T (new int[] {604, 724, 32, 32}), /** */ + IMG_CUR_B (new int[] {604, 764, 32, 32}), /** */ + IMG_CUR_TAB (new int[] {644, 764, 32, 32}); private int[] coords; /** @param xy   int[] coordinates */ @@ -290,6 +297,24 @@ public enum FSkin { public int[] getCoords() { return coords; } } + /** */ + public enum EditorImages implements SkinProp { /** */ + IMG_ARTIFACT (new int[] {280, 720, 40, 40}), /** */ + IMG_CREATURE (new int[] {240, 720, 40, 40}), /** */ + IMG_ENCHANTMENT (new int[] {320, 720, 40, 40}), /** */ + IMG_INSTANT (new int[] {360, 720, 40, 40}), /** */ + IMG_LAND (new int[] {120, 720, 40, 40}), /** */ + IMG_MULTI (new int[] {80, 720, 40, 40}), /** */ + IMG_PLANESWALKER (new int[] {200, 720, 40, 40}), /** */ + IMG_SORCERY (new int[] {160, 720, 40, 40}); + + private int[] coords; + /** @param xy   int[] coordinates */ + EditorImages(final int[] xy) { this.coords = xy; } + /** @return int[] */ + public int[] getCoords() { return coords; } + } + /** */ public enum ButtonImages implements SkinProp { /** */ IMG_BTN_START_UP (new int[] {480, 200, 160, 80}), /** */ @@ -500,10 +525,11 @@ public enum FSkin { for (final Colors e : Colors.values()) { FSkin.setColor(e); } for (final ZoneImages e : ZoneImages.values()) { FSkin.setImage(e); } for (final DockIcons e : DockIcons.values()) { FSkin.setIcon(e); } - for (final ForgeIcons e : ForgeIcons.values()) { FSkin.setIcon(e); } + for (final InterfaceIcons e : InterfaceIcons.values()) { FSkin.setIcon(e); } for (final ButtonImages e : ButtonImages.values()) { FSkin.setIcon(e); } for (final QuestIcons e : QuestIcons.values()) { FSkin.setIcon(e); } + for (final EditorImages e : EditorImages.values()) { FSkin.setImage(e); } for (final ManaImages e : ManaImages.values()) { FSkin.setImage(e); } for (final ColorlessManaImages e : ColorlessManaImages.values()) { FSkin.setImage(e); } for (final GameplayImages e : GameplayImages.values()) { FSkin.setImage(e); } @@ -515,6 +541,9 @@ public enum FSkin { // Assemble avatar images FSkin.assembleAvatars(); + // Table zebra striping + UIManager.put("Table.alternateRowColor", new Color(240, 240, 240)); + // Images loaded; can start UI init. SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/src/main/java/forge/gui/toolbox/FTextArea.java b/src/main/java/forge/gui/toolbox/FTextArea.java index aca88632543..64f230bbb00 100644 --- a/src/main/java/forge/gui/toolbox/FTextArea.java +++ b/src/main/java/forge/gui/toolbox/FTextArea.java @@ -12,6 +12,7 @@ public class FTextArea extends JTextArea { public FTextArea() { super(); this.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT)); this.setOpaque(false); this.setWrapStyleWord(true); this.setLineWrap(true); diff --git a/src/main/java/forge/gui/toolbox/FTextField.java b/src/main/java/forge/gui/toolbox/FTextField.java new file mode 100644 index 00000000000..1228bd0d554 --- /dev/null +++ b/src/main/java/forge/gui/toolbox/FTextField.java @@ -0,0 +1,20 @@ +package forge.gui.toolbox; + +import javax.swing.JTextField; + +/** + * A custom instance of JTextArea using Forge skin properties. + * + */ +@SuppressWarnings("serial") +public class FTextField extends JTextField { + /** */ + public FTextField() { + super(); + this.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT)); + this.setOpaque(false); + this.setFocusable(false); + this.setEditable(false); + } +} diff --git a/src/main/java/forge/item/CardPrinted.java b/src/main/java/forge/item/CardPrinted.java index e7e03cf2502..425e0f05671 100644 --- a/src/main/java/forge/item/CardPrinted.java +++ b/src/main/java/forge/item/CardPrinted.java @@ -36,9 +36,10 @@ import forge.util.closures.Predicate; import forge.util.closures.PredicateString; /** - *

- * CardReference class. - *

+ * A viciously lightweight version of a card, for instances + * where a full set of meta and rules is not needed. + *

+ * The full set of rules is in the CardRules class. * * @author Forge * @version $Id: CardReference.java 9708 2011-08-09 19:34:12Z jendave $ @@ -164,8 +165,10 @@ public final class CardPrinted implements Comparable, InventoryItem return this.card.getType().toString(); } - // Lambda to get rules for selects from list of printed cards - /** The Constant fnGetRules. */ + /** + * Lambda to get rules for selects from list of printed cards. + * + */ public static final Lambda1 FN_GET_RULES = new Lambda1() { @Override public CardRules apply(final CardPrinted from) { diff --git a/src/main/java/forge/item/ItemPool.java b/src/main/java/forge/item/ItemPool.java index f7ba8d3271e..3a90bf2e643 100644 --- a/src/main/java/forge/item/ItemPool.java +++ b/src/main/java/forge/item/ItemPool.java @@ -227,6 +227,11 @@ public class ItemPool extends ItemPoolView { // need not set out-of-sync: either remove did set, or nothing was removed } + /** + * + * TODO: Write javadoc for this method. + * @param flat Iterable + */ public void removeAllFlat(final Iterable flat) { for (final T e : flat) { this.remove(e); diff --git a/src/main/java/forge/model/FModel.java b/src/main/java/forge/model/FModel.java index 1d7e6b15a4b..b660f262695 100644 --- a/src/main/java/forge/model/FModel.java +++ b/src/main/java/forge/model/FModel.java @@ -419,7 +419,7 @@ public enum 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())); - final VDev v = VMatchUI.SINGLETON_INSTANCE.getViewDevMode(); + final VDev v = VDev.SINGLETON_INSTANCE; Constant.Runtime.MILL[0] = v.getLblMilling().getEnabled(); fp.setPref(FPref.DEV_MILLING_LOSS, String.valueOf(Constant.Runtime.MILL[0])); diff --git a/src/main/java/forge/properties/ForgePreferences.java b/src/main/java/forge/properties/ForgePreferences.java index ed71355d365..4b7fe5a247c 100644 --- a/src/main/java/forge/properties/ForgePreferences.java +++ b/src/main/java/forge/properties/ForgePreferences.java @@ -19,10 +19,15 @@ package forge.properties; import java.io.BufferedReader; import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.HashMap; import java.util.Map; @@ -48,7 +53,6 @@ public class ForgePreferences { public enum FPref { /** */ UI_USE_OLD ("false"), /** */ UI_RANDOM_FOIL ("false"), /** */ - UI_LAYOUT_PARAMS ("0.15,0.55,0.68,0.73,0.44,0.40"), /** */ UI_SMOOTH_LAND ("false"), /** */ UI_AVATARS ("0,1"), /** */ UI_CARD_OVERLAY ("true"), /** */ @@ -146,7 +150,27 @@ public class ForgePreferences { public ForgePreferences() { preferenceValues = new HashMap(); try { - final BufferedReader input = new BufferedReader(new FileReader(NewConstants.PREFERENCE_FILE)); + // Preferences files have been consolidated into res/prefs/. + // This code is here temporarily to facilitate this transfer. + // After a while, this can be deleted. Doublestrike 21-5-12 + final File oldFile = new File("forge.preferences"); + if (oldFile.exists()) { + final File newFile = new File(NewConstants.PREFS_GLOBAL_FILE); + final InputStream in = new FileInputStream(oldFile); + final OutputStream out = new FileOutputStream(newFile); + + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + in.close(); + out.close(); + + oldFile.delete(); + } // END TEMPORARY CONSOLIDATION FACILITATION + + final BufferedReader input = new BufferedReader(new FileReader(NewConstants.PREFS_GLOBAL_FILE)); String line = null; while ((line = input.readLine()) != null) { if (line.startsWith("#") || (line.length() == 0)) { @@ -171,7 +195,7 @@ public class ForgePreferences { BufferedWriter writer = null; try { - writer = new BufferedWriter(new FileWriter(NewConstants.PREFERENCE_FILE)); + writer = new BufferedWriter(new FileWriter(NewConstants.PREFS_GLOBAL_FILE)); for (FPref key : FPref.values()) { writer.write(key + "=" + getPref(key)); writer.newLine(); diff --git a/src/main/java/forge/properties/ForgeProps.java b/src/main/java/forge/properties/ForgeProps.java index b721151bd32..2151d9151a1 100644 --- a/src/main/java/forge/properties/ForgeProps.java +++ b/src/main/java/forge/properties/ForgeProps.java @@ -44,7 +44,7 @@ public class ForgeProps { static { TreeProperties p; try { - p = new TreeProperties("forge.properties"); + p = new TreeProperties(NewConstants.PREFS_MAIN_PROPERTIES_FILE); p.rethrow(); } catch (final IOException ex) { ErrorViewer.showError(ex); diff --git a/src/main/java/forge/properties/NewConstants.java b/src/main/java/forge/properties/NewConstants.java index 5d6954cfc08..54c7d184765 100644 --- a/src/main/java/forge/properties/NewConstants.java +++ b/src/main/java/forge/properties/NewConstants.java @@ -43,8 +43,15 @@ public final class NewConstants { /** Constant CARDFORGE_URL = "program/cardforgeURL". */ public static final String CARDFORGE_URL = "program/cardforgeURL"; - /** Constant CARDFORGE_URL = "program/cardforgeURL". */ - public static final String PREFERENCE_FILE = "forge.preferences"; + /** Constant PREFS_GLOBAL_FILE = "forge.preferences". */ + public static final String PREFS_GLOBAL_FILE = "res/preferences/forge.preferences"; + /** Constant PREFS_GLOBAL_FILE = "editor.preferences". */ + public static final String PREFS_EDITOR_FILE = "res/preferences/editor.preferences"; + /** */ + public static final String PREFS_MAIN_PROPERTIES_FILE = "res/preferences/main.properties"; + + /** Constant LAYOUT_DIR = "res/layouts/". */ + public static final String LAYOUT_DIR = "res/layouts/"; /** Constant DECKS="decks". */ public static final String DECKS = "decks"; @@ -60,6 +67,7 @@ public final class NewConstants { /** Constant CARD_PICTURES_A="card-pictures_a". */ public static final class CardPicturesByLetter { + /** */ public static final String CARD_PICTURES_A = "card-pictures_a"; /** Constant CARD_PICTURES_B="card-pictures_b". */ public static final String CARD_PICTURES_B = "card-pictures_b"; @@ -112,22 +120,15 @@ public final class NewConstants { /** Constant CARD_PICTURES_Z="card-pictures_z". */ public static final String CARD_PICTURES_Z = "card-pictures_z"; } - /** Constant CARD_PICTURES_OTHER="card-pictures_other". */ - public static final String CARD_PICTURES_OTHER = "card-pictures_other"; - /** Constant CARD_PICTURES_TOKEN_HQ="card-pictures_token_hq". */ - public static final String CARD_PICTURES_TOKEN_HQ = "card-pictures_token_hq"; + /** Constant TOKEN_IMAGES="token-images". */ public static final String TOKEN_IMAGES = "token-images"; - /** Constant CARDS="cards". */ - public static final String CARDS = "cards"; /** Constant CARDSFOLDER="cardsfolder". */ public static final String CARDSFOLDER = "cardsfolder"; /** Constant REMOVED="removed-cards". */ public static final String REMOVED = "removed-cards"; /** Constant NAME_MUTATOR="name-mutator". */ public static final String NAME_MUTATOR = "name-mutator"; - /** Constant BOOSTERDATA="boosterdata". */ - public static final String BOOSTERDATA = "boosterdata"; /** The file name of the image for face down cards on the battlefield. */ public static final String MORPH_IMAGE_FILE_NAME = "morph"; @@ -143,12 +144,10 @@ public final class NewConstants { public static final String IMAGE_TOKEN = "image/token"; /** Constant IMAGE_ICON="image/icon". */ public static final String IMAGE_ICON = "image/icon"; + /** Constant IMAGE_SEALED_PRODUCT="image/product". */ public static final String IMAGE_SEALED_PRODUCT = "image/product"; /** Constant PICS_BOOSTER_IMAGES="pics/booster/images". */ public static final String PICS_BOOSTER_IMAGES = "pics/booster/images"; - /** Constant SOUND_BASE="sound/base". */ - public static final String SOUND_BASE = "sound/base"; - /** * These properties are for a regular game. @@ -199,6 +198,7 @@ public final class NewConstants { /** The DECKS. */ public static final String DUELS = "quest/duels-dir"; + /** */ public static final String CHALLENGES = "quest/challenges-dir"; /** The XMLDATA. */ @@ -222,38 +222,12 @@ public final class NewConstants { /** */ public static final String PRECONS = "quest/precons-dir"; + /** */ public static final String BAZAAR = "quest/bazaar"; + /** */ public static final String BAZAAR_DIR = "quest/bazaar-dir"; } - /** - * These are GUI-related properties. - */ - public static class Gui { - - /** - * The Interface GuiDisplay. - */ - public static class GuiDisplay { - - /** The LAYOUT. */ - public static final String LAYOUT = "gui/Display"; - - /** The LAYOUT_NEW. */ - public static final String LAYOUT_NEW = "gui/Display/new"; - } - - /** - * The Interface GuiDeckEditor. - */ - public static class GuiDeckEditor { - - /** The LAYOUT. */ - public static final String LAYOUT = "gui/DeckEditor"; - - } - } - /** * These are localization properties. */ diff --git a/src/main/java/forge/quest/QuestUtilCards.java b/src/main/java/forge/quest/QuestUtilCards.java index ccf9a600297..e53ae18e44e 100644 --- a/src/main/java/forge/quest/QuestUtilCards.java +++ b/src/main/java/forge/quest/QuestUtilCards.java @@ -279,7 +279,7 @@ public final class QuestUtilCards { * * @return the sell mutliplier */ - public double getSellMutliplier() { + public double getSellMultiplier() { double multi = 0.20 + (0.001 * this.qc.getAchievements().getWin()); if (multi > 0.6) { multi = 0.6; diff --git a/src/main/java/forge/MyObservable.java b/src/main/java/forge/util/MyObservable.java similarity index 72% rename from src/main/java/forge/MyObservable.java rename to src/main/java/forge/util/MyObservable.java index f130dc41bd8..304f71cdf2d 100644 --- a/src/main/java/forge/MyObservable.java +++ b/src/main/java/forge/util/MyObservable.java @@ -15,10 +15,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package forge; +package forge.util; import java.util.Observable; +import forge.Singletons; +import forge.game.phase.PhaseHandler; + /** *

* MyObservable class. @@ -38,12 +41,13 @@ public class MyObservable extends Observable { this.notifyObservers(); if (Singletons.getModel() == null) { return; } - - if ((Singletons.getModel().getGameState().getPhaseHandler() != null) && Singletons.getModel().getGameState().getPhaseHandler().isNeedToNextPhase()) { - if (Singletons.getModel().getGameState().getPhaseHandler().isNeedToNextPhaseInit()) { + PhaseHandler phases = Singletons.getModel().getGameState().getPhaseHandler(); + + if ((phases != null) && phases.isNeedToNextPhase()) { + if (phases.isNeedToNextPhaseInit()) { // this is used. - Singletons.getModel().getGameState().getPhaseHandler().setNeedToNextPhase(false); - Singletons.getModel().getGameState().getPhaseHandler().nextPhase(); + phases.setNeedToNextPhase(false); + phases.nextPhase(); } } } diff --git a/src/main/java/forge/util/closures/Predicate.java b/src/main/java/forge/util/closures/Predicate.java index 9126cf68c3b..caf4971be01 100644 --- a/src/main/java/forge/util/closures/Predicate.java +++ b/src/main/java/forge/util/closures/Predicate.java @@ -26,7 +26,7 @@ import java.util.Map; /** * Predicate class allows to select items or type , which are or contain an * object of type , matching to some criteria set by predicate. No need to - * write that simple operations by hand. + * write that simple operation by hand. * * PS: com.google.common.base.Predicates contains almost the same functionality, * except for they keep filtering, transformations aside from the predicate in @@ -58,7 +58,9 @@ public abstract class Predicate { NOR, /** The NAND. */ NAND, + /** */ GT, + /** */ LT } @@ -84,9 +86,8 @@ public abstract class Predicate { LT_OR_EQUAL } - // This is the main method, predicates were made for. /** - * Checks if is true. + * This is the main method, predicates were made for. * * @param subject * the subject @@ -94,11 +95,10 @@ public abstract class Predicate { */ public abstract boolean isTrue(T subject); - // These are checks against constants, they will let build simpler - // expressions // Overloaded only in LeafConstant /** - * Checks if is 1. + * These are checks against constants, they will let simpler + * expressions be built. * * @return true, if is 1 */ @@ -675,7 +675,8 @@ public abstract class Predicate { // Static builder methods - they choose concrete implementation by // themselves /** - * Brigde. + * Brigde (transforms a predicate of type T into a predicate + * of type U, using a bridge function passed as an argument). * * @param * the generic type @@ -708,19 +709,6 @@ public abstract class Predicate { return new BridgeToInstance(predicate, clsTarget); } - /** - * Not. - * - * @param - * the generic type - * @param operand1 - * the operand1 - * @return the predicate - */ - public static Predicate not(final Predicate operand1) { - return new Not(operand1); - } - /** * Compose. * @@ -842,6 +830,32 @@ public abstract class Predicate { return new NodeOrBridged(operand1, operand2, bridge); } + /** + * Not. + * + * @param + * the generic type + * @param operand1 + * the operand1 + * @return the predicate + */ + public static Predicate not(final Predicate operand1) { + return new Not(operand1); + } + + /** + * Not. + * + * @param + * the generic type + * @param operand + * the operand + * @return the predicate + */ + public static Predicate not(final Iterable> operand) { + return new MultiNodeNot(operand); + } + /** * Gets the true. * @@ -1252,6 +1266,35 @@ final class MultiNodeOr extends MultiNode { } } + +/** + * + * TODO: Write javadoc for this type. + * + * @param + */ +final class MultiNodeNot extends MultiNode { + /** + * + * TODO: Write javadoc for Constructor. + * @param filters Iterable> + */ + public MultiNodeNot(final Iterable> filters) { + super(filters); + } + + @Override + public boolean isTrue(final T subject) { + for (final Predicate p : this.getOperands()) { + if (!p.isTrue(subject)) { + return true; + } + } + return false; + } +} + + /** * * TODO: Write javadoc for this type. diff --git a/src/main/java/forge/util/closures/PredicateInteger.java b/src/main/java/forge/util/closures/PredicateInteger.java new file mode 100644 index 00000000000..09278cb7896 --- /dev/null +++ b/src/main/java/forge/util/closures/PredicateInteger.java @@ -0,0 +1,75 @@ +/* + * Forge: Play Magic: the Gathering. + * Copyright (C) 2011 MaxMtg + * + * 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.util.closures; + +/** + * Special predicate class to perform integer operations. + * + * @param + * the generic type + */ +public abstract class PredicateInteger extends Predicate { + + /** The operator. */ + private final ComparableOp operator; + + /** + * Op. + * + * @param op1 + * the op1 + * @param op2 + * the op2 + * @return true, if successful + */ + protected final boolean op(final int op1, final int op2) { + switch (this.getOperator()) { + case GREATER_THAN: + return op1 > op2; + case LESS_THAN: + return op1 < op2; + case GT_OR_EQUAL: + return op1 >= op2; + case LT_OR_EQUAL: + return op1 <= op2; + case EQUALS: + return op1 == op2; + case NOT_EQUALS: + return op1 != op2; + default: + return false; + } + } + + /** + * Instantiates a new integer predicate. + * + * @param operator + * the operator + */ + public PredicateInteger(final ComparableOp operator) { + this.operator = operator; + } + + /** + * @return the operator + */ + public ComparableOp getOperator() { + return operator; + } +} diff --git a/src/main/java/forge/view/FView.java b/src/main/java/forge/view/FView.java index 0b11d767f21..a20b2d08174 100644 --- a/src/main/java/forge/view/FView.java +++ b/src/main/java/forge/view/FView.java @@ -11,7 +11,6 @@ import java.util.List; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; -import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; @@ -19,11 +18,10 @@ import net.miginfocom.swing.MigLayout; import forge.AllZone; import forge.Singletons; import forge.control.FControl; +import forge.gui.deckeditor.VDeckEditorUI; import forge.gui.framework.DragCell; import forge.gui.framework.EDocID; import forge.gui.framework.SLayoutConstants; -import forge.gui.framework.SOverflowUtil; -import forge.gui.framework.SResizingUtil; import forge.gui.home.VHomeUI; import forge.gui.match.VMatchUI; import forge.gui.toolbox.FOverlay; @@ -38,7 +36,6 @@ public enum FView { private SplashFrame splash; // Non-singleton instances (deprecated, but not updated yet) - private ViewEditorUI editor = null; private ViewBazaarUI bazaar = null; // Top-level UI components; all have getters. @@ -51,26 +48,19 @@ public enum FView { // private FView() { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - try { splash = new SplashFrame(); } - catch (Exception e) { e.printStackTrace(); } - } - }); + splash = new SplashFrame(); } /** */ public void initialize() { SplashFrame.PROGRESS_BAR.setDescription("Creating display components."); - Singletons.getView().cacheUIStates(); // Frame styling frmDocument.setMinimumSize(new Dimension(800, 600)); frmDocument.setLocationRelativeTo(null); frmDocument.setExtendedState(frmDocument.getExtendedState() | Frame.MAXIMIZED_BOTH); frmDocument.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); - frmDocument.setIconImage(FSkin.getIcon(FSkin.ForgeIcons.ICO_FAVICON).getImage()); + frmDocument.setIconImage(FSkin.getIcon(FSkin.InterfaceIcons.ICO_FAVICON).getImage()); frmDocument.setTitle("Forge: " + Singletons.getModel().getBuildInfo().getVersion()); // Frame components @@ -91,10 +81,12 @@ public enum FView { FOverlay.SINGLETON_INSTANCE.getPanel().setBackground(FSkin.getColor(FSkin.Colors.CLR_OVERLAY)); - // Populate all drag tabs. After they are realized, - // their controller can initialize actions on their components. + // Populate all drag tab components. + this.cacheUIStates(); + + // Initialize actions on all drag tab components (which should + // be realized / populated already). for (EDocID doc : EDocID.values()) { - if (doc.getDoc().getControl() == null) { continue; } doc.getDoc().getControl().initialize(); } @@ -105,11 +97,6 @@ public enum FView { FView.this.splash = null; frmDocument.setVisible(true); - - // TODO MOVE TO CONTROL! - // TODO delete FViewOld - lpnDocument.addMouseListener(SOverflowUtil.getHideOverflowListener()); - lpnDocument.addComponentListener(SResizingUtil.getWindowResizeListener()); } /** @return {@link javax.swing.JFrame} */ @@ -190,15 +177,6 @@ public enum FView { } } - /** @return {@link forge.view.ViewEditorUI} */ - public ViewEditorUI getViewEditor() { - if (Singletons.getControl().getState() != FControl.DEFAULT_EDITOR) { - throw new IllegalArgumentException("FView$getViewEditor\n" - + "may only be called while the editor UI is showing."); - } - return FView.this.editor; - } - /** @return {@link forge.view.ViewBazaarUI} */ public ViewBazaarUI getViewBazaar() { if (Singletons.getControl().getState() != FControl.QUEST_BAZAAR) { @@ -210,9 +188,9 @@ public enum FView { /** */ private void cacheUIStates() { - FView.this.editor = new ViewEditorUI(); FView.this.bazaar = new ViewBazaarUI(AllZone.getQuest().getBazaar()); VMatchUI.SINGLETON_INSTANCE.instantiate(); VHomeUI.SINGLETON_INSTANCE.instantiate(); + VDeckEditorUI.SINGLETON_INSTANCE.instantiate(); } } diff --git a/src/main/java/forge/view/Main.java b/src/main/java/forge/view/Main.java index ff4e77bb3c1..0e88c1772cc 100644 --- a/src/main/java/forge/view/Main.java +++ b/src/main/java/forge/view/Main.java @@ -21,7 +21,6 @@ import javax.swing.SwingUtilities; import forge.Singletons; import forge.control.FControl; -import forge.error.ErrorViewer; import forge.error.ExceptionHandler; import forge.model.FModel; @@ -45,28 +44,36 @@ public final class Main { */ public static void main(final String[] args) { ExceptionHandler.registerErrorHandling(); - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - @Override - public void run() { - // Only works if the program is not ABORTed / KILLed. - // Used instead of a finalizer to avoid leak issues. - Singletons.getModel().close(); - } - })); + + Singletons.setModel(FModel.SINGLETON_INSTANCE); try { - Singletons.setModel(FModel.SINGLETON_INSTANCE); - Singletons.setView(FView.SINGLETON_INSTANCE); - Singletons.setControl(FControl.SINGLETON_INSTANCE); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + Singletons.setView(FView.SINGLETON_INSTANCE); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } - // Use splash frame to initialize everything, then transition to core UI. - Singletons.getControl().initialize(); + Singletons.setControl(FControl.SINGLETON_INSTANCE); - SwingUtilities.invokeLater(new Runnable() { @Override - public void run() { Singletons.getView().initialize(); } }); + // Use splash frame to initialize everything, then transition to core UI. + Singletons.getControl().initialize(); - } catch (final Throwable exn) { - ErrorViewer.showError(exn); + SwingUtilities.invokeLater(new Runnable() { @Override + public void run() { Singletons.getView().initialize(); } }); + } + + /** @throws Throwable */ + protected void finalize() throws Throwable { + try { } catch (Exception e) { } + finally { + super.finalize(); + //more code can be written here as per need of application + Singletons.getModel().close(); } } } diff --git a/src/main/java/forge/view/SplashFrame.java b/src/main/java/forge/view/SplashFrame.java index 35eb2d8c0a1..7be6fa640d4 100644 --- a/src/main/java/forge/view/SplashFrame.java +++ b/src/main/java/forge/view/SplashFrame.java @@ -63,10 +63,8 @@ public class SplashFrame extends JFrame { * Create the frame; this must be called from an event * dispatch thread. * - * @throws Exception {@link IllegalStateException} if not called from an - * event dispatch thread. */ - public SplashFrame() throws Exception { + public SplashFrame() { super(); if (!SwingUtilities.isEventDispatchThread()) { diff --git a/src/main/java/forge/view/ViewBazaarUI.java b/src/main/java/forge/view/ViewBazaarUI.java index 76412d6f0af..5dde7d9f445 100644 --- a/src/main/java/forge/view/ViewBazaarUI.java +++ b/src/main/java/forge/view/ViewBazaarUI.java @@ -59,7 +59,7 @@ public class ViewBazaarUI extends FPanel { final FLabel lbl = new FLabel.Builder().text(s + " ") .fontAlign(SwingConstants.RIGHT).iconInBackground(true) - .fontScaleFactor(0.3).opaque(true).hoverable(true) + .fontSize(10).opaque(true).hoverable(true) .icon(FSkin.getIcon(bazaar.getStall(s).getIcon())).selectable(true).build(); pnlAllStalls.add(lbl, "h 80px!, w 90%!, gap 0 0 10px 10px"); diff --git a/src/main/java/forge/view/bazaar/ViewItem.java b/src/main/java/forge/view/bazaar/ViewItem.java index 276b6204cc4..a2555968c8c 100644 --- a/src/main/java/forge/view/bazaar/ViewItem.java +++ b/src/main/java/forge/view/bazaar/ViewItem.java @@ -27,9 +27,9 @@ public class ViewItem extends FPanel { // Final inits this.lblIcon = new FLabel.Builder().iconScaleFactor(1).iconInBackground(true).build(); this.lblName = new FLabel.Builder().fontStyle(Font.BOLD).build(); - this.lblPrice = new FLabel.Builder().fontStyle(Font.BOLD).fontScaleFactor(0.8).build(); + this.lblPrice = new FLabel.Builder().fontStyle(Font.BOLD).fontSize(12).build(); this.tarDesc = new FTextArea(); - this.btnPurchase = new FLabel.Builder().text("Buy").opaque(true).fontScaleFactor(0.2).hoverable(true).build(); + this.btnPurchase = new FLabel.Builder().text("Buy").opaque(true).fontSize(20).hoverable(true).build(); this.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2)); diff --git a/src/main/java/forge/view/bazaar/ViewStall.java b/src/main/java/forge/view/bazaar/ViewStall.java index e99ed4ab0d2..9987b0eb1b3 100644 --- a/src/main/java/forge/view/bazaar/ViewStall.java +++ b/src/main/java/forge/view/bazaar/ViewStall.java @@ -69,7 +69,7 @@ public class ViewStall extends JPanel { this.lblStallName = new FLabel.Builder().text("").fontAlign(SwingConstants.CENTER).build(); this.lblEmpty = new FLabel.Builder().text("The merchant does not have anything useful for sale.") .fontAlign(SwingConstants.CENTER).build(); - this.lblStats = new FLabel.Builder().fontAlign(SwingConstants.CENTER).fontScaleFactor(0.9).build(); + this.lblStats = new FLabel.Builder().fontAlign(SwingConstants.CENTER).fontSize(12).build(); this.tpnFluff = new JTextPane(); this.pnlInventory = new JPanel(); diff --git a/src/test/java/forge/RunTest.java b/src/test/java/forge/RunTest.java index c413690a7ec..cf48e34f1fa 100644 --- a/src/test/java/forge/RunTest.java +++ b/src/test/java/forge/RunTest.java @@ -7,8 +7,10 @@ import java.util.Set; import org.testng.annotations.Test; +import forge.card.CardManaCost; import forge.card.cardfactory.CardFactoryInterface; import forge.card.mana.ManaCost; +import forge.card.mana.ManaCostParser; import forge.control.input.InputPayManaCostUtil; import forge.game.phase.CombatUtil; @@ -125,13 +127,13 @@ public class RunTest { // ********* test CardUtil.getColors() c = new Card(); - c.setManaCost("G"); + c.setManaCost(new CardManaCost(new ManaCostParser("G"))); ArrayList color = CardUtil.getColors(c); this.check("49", color.contains(Constant.Color.GREEN)); this.check("50", color.size() == 1); c = new Card(); - c.setManaCost("W B G R U"); + c.setManaCost(new CardManaCost(new ManaCostParser("W B G R U"))); color = CardUtil.getColors(c); final Set set = new HashSet(color); System.out.println("color: " + color); @@ -143,7 +145,7 @@ public class RunTest { this.check("56", color.contains(Constant.Color.WHITE)); c = new Card(); - c.setManaCost("2"); + c.setManaCost(new CardManaCost(new ManaCostParser("2"))); color = CardUtil.getColors(c); this.check("57", color.size() == 1); this.check("58", color.contains(Constant.Color.COLORLESS)); @@ -154,7 +156,7 @@ public class RunTest { this.check("60", color.contains(Constant.Color.COLORLESS)); c = new Card(); - c.setManaCost(""); + c.setManaCost(new CardManaCost(new ManaCostParser(""))); color = CardUtil.getColors(c); this.check("61", color.size() == 1); this.check("62", color.contains(Constant.Color.COLORLESS)); @@ -170,13 +172,13 @@ public class RunTest { this.check("66", color.contains(Constant.Color.GREEN)); c = new Card(); - c.setManaCost("11 W W B B U U R R G G"); + c.setManaCost(new CardManaCost(new ManaCostParser("11 W W B B U U R R G G"))); color = CardUtil.getColors(c); this.check("67", color.size() == 5); c = new Card(); c = cf.getCard("Elvish Warrior", null); - c.setManaCost("11"); + c.setManaCost(new CardManaCost(new ManaCostParser("11"))); color = CardUtil.getColors(c); this.check("68", color.size() == 1); this.check("69", color.contains(Constant.Color.COLORLESS));