Merge pull request #2 from magefree/master

merge
This commit is contained in:
Sarah Souders 2019-11-29 17:19:19 -05:00 committed by GitHub
commit e470e36124
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
102 changed files with 1595 additions and 819 deletions

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-client</artifactId> <artifactId>mage-client</artifactId>

View file

@ -0,0 +1,88 @@
1 [C19:207] Vraska the Unseen
1 [C19:48] Rayami, First of the Fallen
1 [C19:51] Volrath, the Shapestealer
1 [C19:8] Kadena's Silencer
1 [C19:12] Thought Sponge
1 [C19:21] Thieving Amalgam
1 [C19:31] Apex Altisaur
1 [C19:44] Grismold, the Dreadsower
1 [C19:160] Deathmist Raptor
1 [C19:172] Hooded Hydra
1 [C19:81] Chromeshell Crab
1 [C19:87] Ixidron
1 [C19:89] Kheru Spellsnatcher
1 [C19:96] Stratus Dancer
1 [C19:100] Thousand Winds
1 [C19:101] Vesuvan Shapeshifter
1 [C19:104] Bane of the Living
1 [C19:118] Grim Haruspex
1 [C19:128] Silumgar Assassin
1 [C19:161] Den Protector
1 [C19:179] Seedborn Muse
1 [C19:184] Thelonite Hermit
1 [C19:200] Sagu Mauler
1 [C19:36] Voice of Many
1 [C19:57] Scaretiller
1 [C19:102] Willbender
1 [C19:129] Skinthinner
1 [C19:156] Ainok Survivalist
1 [C19:170] Great Oak Guardian
1 [C19:174] Nantuko Vigilante
1 [C19:177] Sakura-Tribe Elder
1 [C19:194] Icefeather Aven
1 [C19:34] Road of Return
1 [C19:115] Ghastly Conscription
1 [C19:120] Hex
1 [C19:175] Overwhelming Stampede
1 [C19:183] Tempt with Discovery
1 [C19:19] Mire in Misery
1 [C19:98] Tezzeret's Gambit
1 [C19:159] Cultivate
1 [C19:164] Explore
1 [C19:165] Farseek
1 [C19:205] Urban Evolution
1 [C19:11] Sudden Substitution
1 [C19:187] Biomass Mutation
1 [C19:9] Leadership Vacuum
1 [C19:84] Echoing Truth
1 [C19:92] Reality Shift
1 [C19:197] Putrefy
1 [C19:202] Sultai Charm
1 [C19:56] Pendant of Prosperity
1 [C19:58] Scroll of Fate
1 [C19:224] Strionic Resonator
1 [C19:221] Sol Ring
1 [C19:225] Thran Dynamo
1 [C19:17] Gift of Doom
1 [C19:186] Trail of Mystery
1 [C19:189] Bounty of the Luxa
1 [C19:201] Secret Plans
1 [C19:238] Darkwater Catacombs
1 [C19:242] Exotic Orchard
1 [C19:258] Llanowar Wastes
1 [C19:273] Shrine of the Forsaken Gods
1 [C19:278] Sunken Hollow
1 [C19:282] Thespian's Stage
1 [C19:287] Yavimaya Coast
5 [C19:291] Island
3 [C19:294] Swamp
7 [C19:300] Forest
1 [C19:227] Ash Barrens
1 [C19:232] Bojuka Bog
1 [C19:237] Command Tower
1 [C19:239] Dimir Aqueduct
1 [C19:241] Evolving Wilds
1 [C19:244] Foul Orchard
1 [C19:247] Golgari Guildgate
1 [C19:248] Golgari Rot Farm
1 [C19:254] Jungle Hollow
1 [C19:261] Myriad Landscape
1 [C19:264] Opulent Palace
1 [C19:268] Reliquary Tower
1 [C19:274] Simic Growth Chamber
1 [C19:275] Simic Guildgate
1 [C19:280] Temple of the False God
1 [C19:281] Terramorphic Expanse
1 [C19:283] Thornwood Falls
1 [C19:286] Woodland Stream
SB: 1 [C19:45] Kadena, Slinking Sorcerer

View file

@ -0,0 +1,82 @@
1 [C19:124] Ob Nixilis Reignited
1 [C19:39] Chainer, Nightmare Adept
1 [C19:43] Greven, Predator Captain
1 [C19:14] Archfiend of Spite
1 [C19:15] Bone Miser
1 [C19:18] K'rrik, Son of Yawgmoth
1 [C19:22] Anje's Ravager
1 [C19:28] Skyfire Phoenix
1 [C19:30] Wildfire Devils
1 [C19:109] Champion of Stray Souls
1 [C19:114] Geth, Lord of the Vault
1 [C19:130] Soul of Innistrad
1 [C19:103] Asylum Visitor
1 [C19:111] Doomed Necromancer
1 [C19:125] Overseer of the Damned
1 [C19:144] Flayer of the Hatebound
1 [C19:149] Magus of the Wheel
1 [C19:152] Squee, Goblin Nabob
1 [C19:153] Stromkirk Occultist
1 [C19:188] Bloodhall Priest
1 [C19:222] Solemn Simulacrum
1 [C19:57] Scaretiller
1 [C19:106] Big Game Hunter
1 [C19:116] Gorgon Recluse
1 [C19:117] Grave Scrabbler
1 [C19:123] Nightshade Assassin
1 [C19:126] Plaguecrafter
1 [C19:127] Sanitarium Skeleton
1 [C19:218] Meteor Golem
1 [C19:20] Nightmare Unmaking
1 [C19:107] Boneyard Parley
1 [C19:105] Beacon of Unrest
1 [C19:113] From Under the Floorboards
1 [C19:121] In Garruk's Wake
1 [C19:134] Avacyn's Judgment
1 [C19:19] Mire in Misery
1 [C19:26] Hate Mirage
1 [C19:108] Call to the Netherworld
1 [C19:122] Murderous Compulsion
1 [C19:133] Alchemist's Greeting
1 [C19:150] Malevolent Whispers
1 [C19:136] Chaos Warp
1 [C19:110] Dark Withering
1 [C19:142] Fiery Temper
1 [C19:154] Violent Eruption
1 [C19:213] Grimoire of the Dead
1 [C19:216] Key to the City
1 [C19:53] Bloodthirsty Blade
1 [C19:52] Aeon Engine
1 [C19:209] Armillary Sphere
1 [C19:214] Hedron Archive
1 [C19:220] Rakdos Locket
1 [C19:221] Sol Ring
1 [C19:16] Curse of Fool's Wisdom
1 [C19:119] Hedonist's Trove
1 [C19:155] Warstorm Surge
1 [C19:112] Faith of the Devoted
1 [C19:131] The Eldest Reborn
1 [C19:132] Zombie Infestation
1 [C19:59] Sanctum of Eternity
1 [C19:240] Drownyard Temple
1 [C19:242] Exotic Orchard
1 [C19:246] Geier Reach Sanitarium
10 [C19:294] Swamp
10 [C19:297] Mountain
1 [C19:226] Akoum Refuge
1 [C19:227] Ash Barrens
1 [C19:229] Barren Moor
1 [C19:230] Bloodfell Caves
1 [C19:235] Cinder Barrens
1 [C19:237] Command Tower
1 [C19:241] Evolving Wilds
1 [C19:243] Forgotten Cave
1 [C19:259] Memorial to Folly
1 [C19:260] Mortuary Mire
1 [C19:261] Myriad Landscape
1 [C19:266] Rakdos Carnarium
1 [C19:267] Rakdos Guildgate
1 [C19:269] Rix Maadi, Dungeon Palace
1 [C19:281] Terramorphic Expanse
1 [C19:280] Temple of the False God
SB: 1 [C19:37] Anje Falkenrath

View file

@ -0,0 +1,82 @@
1 [C19:198] Ral Zarek
1 [C19:40] Elsha of the Infinite
1 [C19:47] Pramikon, Sky Rampart
1 [C19:7] Thalia's Geistcaller
1 [C19:13] Wall of Stolen Identity
1 [C19:23] Backdraft Hellkite
1 [C19:24] Dockside Extortionist
1 [C19:41] Gerrard, Weatherlight Hero
1 [C19:70] Pristine Angel
1 [C19:76] Sun Titan
1 [C19:82] Clever Impersonator
1 [C19:79] Zetalpa, Primal Dawn
1 [C19:93] River Kelpie
1 [C19:97] Talrand, Sky Summoner
1 [C19:196] Pristine Skywise
1 [C19:1] Cliffside Rescuer
1 [C19:57] Scaretiller
1 [C19:145] Guttersnipe
1 [C19:190] Crackling Drake
1 [C19:211] Burnished Hart
1 [C19:5] Sevinne's Reclamation
1 [C19:10] Mass Diminish
1 [C19:27] Ignite the Future
1 [C19:62] Divine Reckoning
1 [C19:63] Dusk // Dawn
1 [C19:66] Increasing Devotion
1 [C19:75] Storm Herd
1 [C19:138] Devil's Play
1 [C19:83] Deep Analysis
1 [C19:90] Mystic Retrieval
1 [C19:94] Runic Repetition
1 [C19:140] Faithless Looting
1 [C19:151] Rolling Temblor
1 [C19:4] Mandate of Peace
1 [C19:147] Increasing Vengeance
1 [C19:148] Magmaquake
1 [C19:199] Refuse // Cooperate
1 [C19:9] Leadership Vacuum
1 [C19:69] Prismatic Strands
1 [C19:71] Purify the Grave
1 [C19:72] Ray of Distortion
1 [C19:80] Chemister's Insight
1 [C19:85] Fact or Fiction
1 [C19:86] Fervent Denial
1 [C19:91] Oona's Grace
1 [C19:99] Think Twice
1 [C19:137] Desperate Ravings
1 [C19:192] Farm // Market
1 [C19:54] Empowered Autogenerator
1 [C19:53] Bloodthirsty Blade
1 [C19:209] Armillary Sphere
1 [C19:210] Azorius Locket
1 [C19:212] Commander's Sphere
1 [C19:215] Izzet Locket
1 [C19:221] Sol Ring
1 [C19:88] Jace's Sanctum
1 [C19:64] Ghostly Prison
1 [C19:95] Secrets of the Dead
1 [C19:135] Burning Vengeance
1 [C19:242] Exotic Orchard
1 [C19:265] Prairie Stream
9 [C19:288] Plains
8 [C19:291] Island
4 [C19:297] Mountain
1 [C19:227] Ash Barrens
1 [C19:228] Azorius Chancery
1 [C19:233] Boros Garrison
1 [C19:234] Boros Guildgate
1 [C19:237] Command Tower
1 [C19:241] Evolving Wilds
1 [C19:251] Highland Lake
1 [C19:252] Izzet Boilerworks
1 [C19:253] Izzet Guildgate
1 [C19:261] Myriad Landscape
1 [C19:262] Mystic Monastery
1 [C19:276] Stone Quarry
1 [C19:279] Swiftwater Cliffs
1 [C19:280] Temple of the False God
1 [C19:281] Terramorphic Expanse
1 [C19:284] Tranquil Cove
1 [C19:285] Wind-Scarred Crag
SB: 1 [C19:49] Sevinne, the Chronoclasm

View file

@ -0,0 +1,84 @@
1 [C19:167] Garruk, Primal Hunter
1 [C19:38] Atla Palani, Nest Tender
1 [C19:46] Marisi, Breaker of the Coil
1 [C19:3] Doomed Artisan
1 [C19:29] Tectonic Hellion
1 [C19:33] Ohran Frostfang
1 [C19:35] Selesnya Eulogist
1 [C19:50] Tahngarth, First Mate
1 [C19:61] Angel of Sanctions
1 [C19:78] Wingmate Roc
1 [C19:139] Dragonmaster Outcast
1 [C19:141] Feldon of the Third Path
1 [C19:169] Giant Adephage
1 [C19:182] Soul of Zendikar
1 [C19:204] Trostani, Selesnya's Voice
1 [C19:60] Desolation Twin
1 [C19:143] Flamerush Rider
1 [C19:146] Heart-Piercer Manticore
1 [C19:176] Rampaging Baloths
1 [C19:185] Thragtusk
1 [C19:191] Emmara Tandris
1 [C19:208] Wayfaring Temple
1 [C19:1] Cliffside Rescuer
1 [C19:36] Voice of Many
1 [C19:57] Scaretiller
1 [C19:73] Roc Egg
1 [C19:168] Garruk's Packleader
1 [C19:177] Sakura-Tribe Elder
1 [C19:206] Vitu-Ghazi Guildmage
1 [C19:25] Ghired's Belligerence
1 [C19:32] Full Flowering
1 [C19:65] Hour of Reckoning
1 [C19:68] Phyrexian Rebirth
1 [C19:180] Shamanic Revelation
1 [C19:26] Hate Mirage
1 [C19:159] Cultivate
1 [C19:164] Explore
1 [C19:165] Farseek
1 [C19:171] Harmonize
1 [C19:166] Fresh Meat
1 [C19:173] Momentous Fall
1 [C19:178] Second Harvest
1 [C19:74] Rootborn Defenses
1 [C19:77] Trostani's Judgment
1 [C19:157] Beast Within
1 [C19:162] Druid's Deliverance
1 [C19:181] Slice in Twain
1 [C19:195] Naya Charm
1 [C19:203] Sundering Growth
1 [C19:55] Idol of Oblivion
1 [C19:219] Mimic Vat
1 [C19:223] Soul Foundry
1 [C19:217] Lightning Greaves
1 [C19:221] Sol Ring
1 [C19:2] Commander's Insignia
1 [C19:6] Song of the Worldsoul
1 [C19:193] Growing Ranks
1 [C19:67] Intangible Virtue
1 [C19:158] Colossal Majesty
1 [C19:163] Elemental Bond
1 [C19:236] Cinder Glade
1 [C19:242] Exotic Orchard
1 [C19:245] Gargoyle Castle
1 [C19:277] Sungrass Prairie
7 [C19:288] Plains
4 [C19:297] Mountain
8 [C19:300] Forest
1 [C19:227] Ash Barrens
1 [C19:231] Blossoming Sands
1 [C19:233] Boros Garrison
1 [C19:237] Command Tower
1 [C19:241] Evolving Wilds
1 [C19:249] Graypelt Refuge
1 [C19:250] Gruul Turf
1 [C19:255] Jungle Shrine
1 [C19:256] Kazandu Refuge
1 [C19:257] Krosan Verge
1 [C19:261] Myriad Landscape
1 [C19:263] Naya Panorama
1 [C19:270] Rogue's Passage
1 [C19:271] Rugged Highlands
1 [C19:272] Selesnya Sanctuary
1 [C19:281] Terramorphic Expanse
SB: 1 [C19:42] Ghired, Conclave Exile

View file

@ -480,19 +480,32 @@ public class AddLandDialog extends MageDialog {
white += m.getWhite(); white += m.getWhite();
} }
int total = red + green + black + blue + white; int total = red + green + black + blue + white;
int redcards = Math.round(land_number * ((float) red / (float) total));
int redcards = 0;
int greencards = 0;
int blackcards = 0;
int bluecards = 0;
int whitecards = 0;
if (total > 0) {
redcards = Math.round(land_number * ((float) red / (float) total));
total -= red; total -= red;
land_number -= redcards; land_number -= redcards;
int greencards = Math.round(land_number * ((float) green / (float) total));
greencards = Math.round(land_number * ((float) green / (float) total));
total -= green; total -= green;
land_number -= greencards; land_number -= greencards;
int blackcards = Math.round(land_number * ((float) black / (float) total));
blackcards = Math.round(land_number * ((float) black / (float) total));
total -= black; total -= black;
land_number -= blackcards; land_number -= blackcards;
int bluecards = Math.round(land_number * ((float) blue / (float) total));
bluecards = Math.round(land_number * ((float) blue / (float) total));
total -= blue; total -= blue;
land_number -= bluecards; land_number -= bluecards;
int whitecards = land_number;
whitecards = land_number;
}
spnMountain.setValue(redcards); spnMountain.setValue(redcards);
spnForest.setValue(greencards); spnForest.setValue(greencards);
spnSwamp.setValue(blackcards); spnSwamp.setValue(blackcards);

View file

@ -49,6 +49,143 @@ public class ScryfallImageSupportTokens {
put("RNA/Treasure", "https://api.scryfall.com/cards/trna/12/en?format=image"); put("RNA/Treasure", "https://api.scryfall.com/cards/trna/12/en?format=image");
put("RNA/Zombie", "https://api.scryfall.com/cards/trna/3/en?format=image"); put("RNA/Zombie", "https://api.scryfall.com/cards/trna/3/en?format=image");
//GRN
put("GRN/Angel", "https://api.scryfall.com/cards/tgrn/1/en?format=image");
put("GRN/Bird Illusion", "https://api.scryfall.com/cards/tgrn/3/en?format=image");
put("GRN/Elf Knight", "https://api.scryfall.com/cards/tgrn/6/en?format=image");
put("GRN/Goblin", "https://api.scryfall.com/cards/tgrn/4/en?format=image");
put("GRN/Insect", "https://api.scryfall.com/cards/tgrn/5/en?format=image");
put("GRN/Emblem Ral, Izzet Viceroy", "https://api.scryfall.com/cards/tgrn/7/en?format=image");
put("GRN/Soldier", "https://api.scryfall.com/cards/tgrn/2/en?format=image");
put("GRN/Emblem Vraska, Golgari Queen", "https://api.scryfall.com/cards/tgrn/8/en?format=image");
//DOM
put("DOM/Cleric", "https://api.scryfall.com/cards/tdom/4/en?format=image");
put("DOM/Construct", "https://api.scryfall.com/cards/tdom/14/en?format=image");
put("DOM/Demon", "https://api.scryfall.com/cards/tdom/7/en?format=image");
put("DOM/Elemental", "https://api.scryfall.com/cards/tdom/8/en?format=image");
put("DOM/Goblin", "https://api.scryfall.com/cards/tdom/9/en?format=image");
put("DOM/Emblem Jaya Ballard", "https://api.scryfall.com/cards/tdom/15/en?format=image");
put("DOM/Karox Bladewing", "https://api.scryfall.com/cards/tdom/10/en?format=image");
put("DOM/Knight/1", "https://api.scryfall.com/cards/tdom/1/en?format=image");
put("DOM/Knight/2", "https://api.scryfall.com/cards/tdom/2/en?format=image");
put("DOM/Nightmare Horror", "https://api.scryfall.com/cards/tdom/6/en?format=image");
put("DOM/Saproling/1", "https://api.scryfall.com/cards/tdom/11/en?format=image");
put("DOM/Saproling/2", "https://api.scryfall.com/cards/tdom/12/en?format=image");
put("DOM/Saproling/3", "https://api.scryfall.com/cards/tdom/13/en?format=image");
put("DOM/Soldier", "https://api.scryfall.com/cards/tdom/3/en?format=image");
put("DOM/Emblem Teferi, Hero of Dominaria", "https://api.scryfall.com/cards/tdom/16/en?format=image");
put("DOM/Zombie Knight", "https://api.scryfall.com/cards/tdom/5/en?format=image");
//XLN
put("XLN/Dinosaur", "https://api.scryfall.com/cards/txln/5/en?format=image");
put("XLN/Illusion", "https://api.scryfall.com/cards/txln/2/en?format=image");
put("XLN/Merfolk", "https://api.scryfall.com/cards/txln/3/en?format=image");
put("XLN/Pirate", "https://api.scryfall.com/cards/txln/4/en?format=image");
put("XLN/Plant", "https://api.scryfall.com/cards/txln/6/en?format=image");
put("XLN/Treasure/1", "https://api.scryfall.com/cards/txln/7/en?format=image");
put("XLN/Treasure/2", "https://api.scryfall.com/cards/txln/8/en?format=image");
put("XLN/Treasure/3", "https://api.scryfall.com/cards/txln/9/en?format=image");
put("XLN/Treasure/4", "https://api.scryfall.com/cards/txln/10/en?format=image");
put("XLN/Vampire", "https://api.scryfall.com/cards/txln/1/en?format=image");
//HOU
put("HOU/Horse", "https://api.scryfall.com/cards/thou/10/en?format=image");
put("HOU/Insect", "https://api.scryfall.com/cards/thou/12/en?format=image");
put("HOU/Snake", "https://api.scryfall.com/cards/thou/11/en?format=image");
//AKH
put("AKH/Beast", "https://api.scryfall.com/cards/takh/21/en?format=image");
put("AKH/Cat", "https://api.scryfall.com/cards/takh/16/en?format=image");
put("AKH/Drake", "https://api.scryfall.com/cards/takh/18/en?format=image");
put("AKH/Emblem Gideon", "https://api.scryfall.com/cards/takh/25/en?format=image");
put("AKH/Hippo", "https://api.scryfall.com/cards/takh/22/en?format=image");
put("AKH/Snake", "https://api.scryfall.com/cards/takh/23/en?format=image");
put("AKH/Warrior", "https://api.scryfall.com/cards/takh/17/en?format=image");
put("AKH/Wurm", "https://api.scryfall.com/cards/takh/24/en?format=image");
put("AKH/Zombie", "https://api.scryfall.com/cards/takh/20/en?format=image");
//AER
put("AER/Etherium Cell", "https://api.scryfall.com/cards/taer/3/en?format=image");
put("AER/Gremlin", "https://api.scryfall.com/cards/taer/1/en?format=image");
put("AER/Ragavan", "https://api.scryfall.com/cards/taer/2/en?format=image");
put("AER/Emblem Tezzeret the Schemer", "https://api.scryfall.com/cards/taer/4/en?format=image");
//KLD
put("KLD/Beast", "https://api.scryfall.com/cards/tkld/1/en?format=image");
put("KLD/Emblem Chandra", "https://api.scryfall.com/cards/tkld/10/en?format=image");
put("KLD/Construct/1", "https://api.scryfall.com/cards/tkld/2/en?format=image");
put("KLD/Construct/2", "https://api.scryfall.com/cards/tkld/3/en?format=image");
put("KLD/Emblem Dovin", "https://api.scryfall.com/cards/tkld/12/en?format=image");
put("KLD/Emblem Nissa", "https://api.scryfall.com/cards/tkld/11/en?format=image");
put("KLD/Servo/1", "https://api.scryfall.com/cards/tkld/4/en?format=image");
put("KLD/Servo/2", "https://api.scryfall.com/cards/tkld/5/en?format=image");
put("KLD/Servo/3", "https://api.scryfall.com/cards/tkld/6/en?format=image");
put("KLD/Thopter/1", "https://api.scryfall.com/cards/tkld/7/en?format=image");
put("KLD/Thopter/2", "https://api.scryfall.com/cards/tkld/8/en?format=image");
put("KLD/Thopter/3", "https://api.scryfall.com/cards/tkld/9/en?format=image");
//EMN
put("EMN/Eldrazi Horror", "https://api.scryfall.com/cards/temn/1/en?format=image");
put("EMN/Human", "https://api.scryfall.com/cards/temn/7/en?format=image");
put("EMN/Human Wizard", "https://api.scryfall.com/cards/temn/2/en?format=image");
put("EMN/Emblem Liliana", "https://api.scryfall.com/cards/temn/9/en?format=image");
put("EMN/Spider", "https://api.scryfall.com/cards/temn/8/en?format=image");
put("EMN/Emblem Tamiyo", "https://api.scryfall.com/cards/temn/10/en?format=image");
put("EMN/Zombie/1", "https://api.scryfall.com/cards/temn/3/en?format=image");
put("EMN/Zombie/2", "https://api.scryfall.com/cards/temn/4/en?format=image");
put("EMN/Zombie/3", "https://api.scryfall.com/cards/temn/5/en?format=image");
put("EMN/Zombie/4", "https://api.scryfall.com/cards/temn/6/en?format=image");
//SOI
put("SOI/Angel", "https://api.scryfall.com/cards/tsoi/1/en?format=image");
put("SOI/Emblem Arlinn", "https://api.scryfall.com/cards/tsoi/18/en?format=image");
put("SOI/Clue/1", "https://api.scryfall.com/cards/tsoi/11/en?format=image");
put("SOI/Clue/2", "https://api.scryfall.com/cards/tsoi/12/en?format=image");
put("SOI/Clue/3", "https://api.scryfall.com/cards/tsoi/13/en?format=image");
put("SOI/Clue/4", "https://api.scryfall.com/cards/tsoi/14/en?format=image");
put("SOI/Clue/5", "https://api.scryfall.com/cards/tsoi/15/en?format=image");
put("SOI/Clue/6", "https://api.scryfall.com/cards/tsoi/16/en?format=image");
put("SOI/Devil", "https://api.scryfall.com/cards/tsoi/6/en?format=image");
put("SOI/Human Cleric", "https://api.scryfall.com/cards/tsoi/10/en?format=image");
put("SOI/Human Soldier", "https://api.scryfall.com/cards/tsoi/2/en?format=image");
put("SOI/Insect", "https://api.scryfall.com/cards/tsoi/7/en?format=image");
put("SOI/Emblem Jace", "https://api.scryfall.com/cards/tsoi/17/en?format=image");
put("SOI/Ooze", "https://api.scryfall.com/cards/tsoi/8/en?format=image");
put("SOI/Spirit", "https://api.scryfall.com/cards/tsoi/3/en?format=image");
put("SOI/Vampire Knight", "https://api.scryfall.com/cards/tsoi/4/en?format=image");
put("SOI/Wolf", "https://api.scryfall.com/cards/tsoi/9/en?format=image");
put("SOI/Zombie", "https://api.scryfall.com/cards/tsoi/5/en?format=image");
//OGW
put("OGW/Angel", "https://api.scryfall.com/cards/togw/7/en?format=image");
put("OGW/Eldrazi Scion/1", "https://api.scryfall.com/cards/togw/1/en?format=image");
put("OGW/Eldrazi Scion/2", "https://api.scryfall.com/cards/togw/2/en?format=image");
put("OGW/Eldrazi Scion/3", "https://api.scryfall.com/cards/togw/3/en?format=image");
put("OGW/Eldrazi Scion/4", "https://api.scryfall.com/cards/togw/4/en?format=image");
put("OGW/Eldrazi Scion/5", "https://api.scryfall.com/cards/togw/5/en?format=image");
put("OGW/Eldrazi Scion/6", "https://api.scryfall.com/cards/togw/6/en?format=image");
put("OGW/Elemental/1", "https://api.scryfall.com/cards/togw/10/en?format=image");
put("OGW/Elemental/2", "https://api.scryfall.com/cards/togw/9/en?format=image");
put("OGW/Plant", "https://api.scryfall.com/cards/togw/11/en?format=image");
put("OGW/Zombie", "https://api.scryfall.com/cards/togw/8/en?format=image");
//BFZ
put("BFZ/Dragon", "https://api.scryfall.com/cards/tbfz/8/en?format=image");
put("BFZ/Eldrazi", "https://api.scryfall.com/cards/tbfz/1/en?format=image");
put("BFZ/Eldrazi Scion/1", "https://api.scryfall.com/cards/tbfz/2/en?format=image");
put("BFZ/Eldrazi Scion/2", "https://api.scryfall.com/cards/tbfz/3/en?format=image");
put("BFZ/Eldrazi Scion/3", "https://api.scryfall.com/cards/tbfz/4/en?format=image");
put("BFZ/Elemental/1", "https://api.scryfall.com/cards/tbfz/11/en?format=image");
put("BFZ/Elemental/2", "https://api.scryfall.com/cards/tbfz/9/en?format=image");
put("BFZ/Emblem Gideon", "https://api.scryfall.com/cards/tbfz/12/en?format=image");
put("BFZ/Emblem Kiora", "https://api.scryfall.com/cards/tbfz/14/en?format=image");
put("BFZ/Knight Ally", "https://api.scryfall.com/cards/tbfz/5/en?format=image");
put("BFZ/Kor Ally", "https://api.scryfall.com/cards/tbfz/6/en?format=image");
put("BFZ/Emblem Nixilis", "https://api.scryfall.com/cards/tbfz/13/en?format=image");
put("BFZ/Octopus", "https://api.scryfall.com/cards/tbfz/7/en?format=image");
put("BFZ/Plant", "https://api.scryfall.com/cards/tbfz/10/en?format=image");
// WAR // WAR
put("WAR/Angel", "https://api.scryfall.com/cards/twar/2/en?format=image"); put("WAR/Angel", "https://api.scryfall.com/cards/twar/2/en?format=image");
put("WAR/Assassin", "https://api.scryfall.com/cards/twar/6/en?format=image"); put("WAR/Assassin", "https://api.scryfall.com/cards/twar/6/en?format=image");
@ -149,6 +286,33 @@ public class ScryfallImageSupportTokens {
put("C18/Worm", "https://api.scryfall.com/cards/tc18/18/en?format=image"); put("C18/Worm", "https://api.scryfall.com/cards/tc18/18/en?format=image");
put("C18/Zombie", "https://api.scryfall.com/cards/tc18/9/en?format=image"); put("C18/Zombie", "https://api.scryfall.com/cards/tc18/9/en?format=image");
//C19
put("C19/Assassin", "https://api.scryfall.com/cards/tc19/9/en?format=image");
put("C19/Beast/1", "https://api.scryfall.com/cards/tc19/13/en?format=image");
put("C19/Beast/2", "https://api.scryfall.com/cards/tc19/14/en?format=image");
put("C19/Bird/1", "https://api.scryfall.com/cards/tc19/2/en?format=image");
put("C19/Bird/2", "https://api.scryfall.com/cards/tc19/1/en?format=image");
put("C19/Centaur", "https://api.scryfall.com/cards/tc19/15/en?format=image");
put("C19/Dragon", "https://api.scryfall.com/cards/tc19/12/en?format=image");
put("C19/Drake", "https://api.scryfall.com/cards/tc19/8/en?format=image");
put("C19/Egg", "https://api.scryfall.com/cards/tc19/16/en?format=image");
put("C19/Eldrazi", "https://api.scryfall.com/cards/tc19/26/en?format=image");
put("C19/Gargoyle", "https://api.scryfall.com/cards/tc19/22/en?format=image");
put("C19/Horror", "https://api.scryfall.com/cards/tc19/23/en?format=image");
put("C19/Human", "https://api.scryfall.com/cards/tc19/3/en?format=image");
put("C19/Emblem Ob Nixilis Reignited", "https://api.scryfall.com/cards/tc19/29/en?format=image");
put("C19/Pegasus", "https://api.scryfall.com/cards/tc19/4/en?format=image");
put("C19/Plant", "https://api.scryfall.com/cards/tc19/17/en?format=image");
put("C19/Rhino", "https://api.scryfall.com/cards/tc19/18/en?format=image");
put("C19/Saproling", "https://api.scryfall.com/cards/tc19/19/en?format=image");
put("C19/Sculpture", "https://api.scryfall.com/cards/tc19/24/en?format=image");
put("C19/Snake", "https://api.scryfall.com/cards/tc19/20/en?format=image");
put("C19/Spirit", "https://api.scryfall.com/cards/tc19/5/en?format=image");
put("C19/Treasure", "https://api.scryfall.com/cards/tc19/25/en?format=image");
put("C19/Wurm", "https://api.scryfall.com/cards/tc19/21/en?format=image");
put("C19/Zombie/1", "https://api.scryfall.com/cards/tc19/11/en?format=image");
put("C19/Zombie/2", "https://api.scryfall.com/cards/tc19/10/en?format=image");
// ELD // ELD
put("ELD/Bear", "https://api.scryfall.com/cards/teld/8/en?format=image"); put("ELD/Bear", "https://api.scryfall.com/cards/teld/8/en?format=image");
put("ELD/Boar", "https://api.scryfall.com/cards/teld/9/en?format=image"); put("ELD/Boar", "https://api.scryfall.com/cards/teld/9/en?format=image");

View file

@ -547,9 +547,11 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName); CardDownloadData card = new CardDownloadData(params[3], set, "0", false, type, "", "", true, fileName);
card.setTokenClassName(tokenClassName); card.setTokenClassName(tokenClassName);
list.add(card); list.add(card);
} else {
logger.error("wrong line format in tokens file: " + line);
} }
} else { } else {
logger.error("wrong format for image urls: " + line); logger.error("wrong line data in tokens file: " + line);
} }
} }
line = reader.readLine(); line = reader.readLine();

View file

@ -54,6 +54,7 @@
|Generate|EMBLEM!:C14|Emblem Nixilis|||ObNixilisOfTheBlackOathEmblem| |Generate|EMBLEM!:C14|Emblem Nixilis|||ObNixilisOfTheBlackOathEmblem|
|Generate|EMBLEM!:C14|Emblem Teferi|||TeferiTemporalArchmageEmblem| |Generate|EMBLEM!:C14|Emblem Teferi|||TeferiTemporalArchmageEmblem|
|Generate|EMBLEM!:C16|Emblem Daretti|||DarettiScrapSavantEmblem| |Generate|EMBLEM!:C16|Emblem Daretti|||DarettiScrapSavantEmblem|
|Generate|EMBLEM:C19|Ob Nixilis Reignited||Emblem Nixilis|ObNixilisReignitedEmblem|
|Generate|EMBLEM!:CNS|Emblem Dack Fayden||Emblem Dack|DackFaydenEmblem| |Generate|EMBLEM!:CNS|Emblem Dack Fayden||Emblem Dack|DackFaydenEmblem|
|Generate|EMBLEM!:DTK|Emblem Narset|||NarsetTranscendentEmblem| |Generate|EMBLEM!:DTK|Emblem Narset|||NarsetTranscendentEmblem|
|Generate|EMBLEM!:EMA|Emblem Dack Fayden||Emblem Dack|DackFaydenEmblem| |Generate|EMBLEM!:EMA|Emblem Dack Fayden||Emblem Dack|DackFaydenEmblem|
@ -62,7 +63,6 @@
|Generate|EMBLEM!:KLD|Emblem Chandra|||ChandraTorchOfDefianceEmblem| |Generate|EMBLEM!:KLD|Emblem Chandra|||ChandraTorchOfDefianceEmblem|
|Generate|EMBLEM!:KLD|Emblem Dovin|||DovinBaanEmblem| |Generate|EMBLEM!:KLD|Emblem Dovin|||DovinBaanEmblem|
|Generate|EMBLEM!:KLD|Emblem Nissa|||NissaVitalForceEmblem| |Generate|EMBLEM!:KLD|Emblem Nissa|||NissaVitalForceEmblem|
|Generate|EMBLEM!:KLD|Emblem Tezzeret|||TezzeretTheSchemerEmblem|
|Generate|EMBLEM!:KTK|Emblem Sarkhan|||SarkhanTheDragonspeakerEmblem| |Generate|EMBLEM!:KTK|Emblem Sarkhan|||SarkhanTheDragonspeakerEmblem|
|Generate|EMBLEM!:KTK|Emblem Sorin|||SorinSolemnVisitorEmblem| |Generate|EMBLEM!:KTK|Emblem Sorin|||SorinSolemnVisitorEmblem|
|Generate|EMBLEM!:M15|Emblem Ajani|||AjaniSteadfastEmblem| |Generate|EMBLEM!:M15|Emblem Ajani|||AjaniSteadfastEmblem|
@ -95,6 +95,11 @@
|Generate|EMBLEM:M19|Vivien Reid||Emblem Vivien|VivienReidEmblem| |Generate|EMBLEM:M19|Vivien Reid||Emblem Vivien|VivienReidEmblem|
|Generate|EMBLEM:M20|Chandra, Awakened Inferno||Emblem Chandra|ChandraAwakenedInfernoEmblem| |Generate|EMBLEM:M20|Chandra, Awakened Inferno||Emblem Chandra|ChandraAwakenedInfernoEmblem|
|Generate|EMBLEM:M20|Mu Yanling, Sky Dancer||Emblem Yanling|MuYanlingSkyDancerEmblem| |Generate|EMBLEM:M20|Mu Yanling, Sky Dancer||Emblem Yanling|MuYanlingSkyDancerEmblem|
|Generate|EMBLEM:GRN|Ral, Izzet Viceroy||Emblem Ral|RalIzzetViceroyEmblem|
|Generate|EMBLEM:GRN|Vraska, Golgari Queen||Emblem Vraska|VraskaGolgariQueenEmblem|
|Generate|EMBLEM:DOM|Jaya Ballard||Emblem Jaya Ballard|JayaBallardEmblem|
|Generate|EMBLEM:DOM|Teferi, Hero of Dominaria||Emblem Teferi|TeferiHeroOfDominariaEmblem|
|Generate|EMBLEM:AER|Tezzeret the Schemer||Emblem Tezzeret|TezzeretTheSchemerEmblem|
|Generate|EMBLEM:ELD|Garruk, Cursed Huntsman||Emblem Garruk|GarrukCursedHuntsmanEmblem| |Generate|EMBLEM:ELD|Garruk, Cursed Huntsman||Emblem Garruk|GarrukCursedHuntsmanEmblem|
|Generate|PLANE:PCA|Plane - Academy At Tolaria West|||AcademyAtTolariaWestPlane| |Generate|PLANE:PCA|Plane - Academy At Tolaria West|||AcademyAtTolariaWestPlane|
|Generate|PLANE:PCA|Plane - Agyrem|||AgyremPlane| |Generate|PLANE:PCA|Plane - Agyrem|||AgyremPlane|
@ -157,32 +162,33 @@
|Generate|TOK:8ED|Rukh|| |Generate|TOK:8ED|Rukh||
|Generate|TOK:9ED|Bird|||RukhEggBirdToken| |Generate|TOK:9ED|Bird|||RukhEggBirdToken|
|Generate|TOK:9ED|Saproling|||SaprolingToken| |Generate|TOK:9ED|Saproling|||SaprolingToken|
|Generate|TOK:AER|Etherium Cell|| |Generate|TOK:AER|Etherium Cell|||EtheriumCellToken|
|Generate|TOK:AER|Gremlin|| |Generate|TOK:AER|Gremlin|||GremlinToken|
|Generate|TOK:AER|Ragavan|| |Generate|TOK:AER|Ragavan|||RagavanToken|
|Generate|TOK:AKH|Angel of Sanctions||
|Generate|TOK:AKH|Anointer Priest||
|Generate|TOK:AKH|Aven Initiate||
|Generate|TOK:AKH|Aven Wind Guide||
|Generate|TOK:AKH|Beast|||BeastToken3| |Generate|TOK:AKH|Beast|||BeastToken3|
|Generate|TOK:AKH|Cat|||CatToken2| |Generate|TOK:AKH|Cat|||CatToken2|
|Generate|TOK:AKH|Drake|| |Generate|TOK:AKH|Drake|||DrakeToken|
|Generate|TOK:AKH|Glyph Keeper||
|Generate|TOK:AKH|Heart-Piercer Manticore||
|Generate|TOK:AKH|Hippo|||HippoToken2| |Generate|TOK:AKH|Hippo|||HippoToken2|
|Generate|TOK:AKH|Honored Hydra||
|Generate|TOK:AKH|Labyrinth Guardian||
|Generate|TOK:AKH|Oketra's Attendant||
|Generate|TOK:AKH|Sacred Cat||
|Generate|TOK:AKH|Snake|||DeathtouchSnakeToken| |Generate|TOK:AKH|Snake|||DeathtouchSnakeToken|
|Generate|TOK:AKH|Tah-Crop Skirmisher||
|Generate|TOK:AKH|Temmet, Vizier of Naktamun||
|Generate|TOK:AKH|Trueheart Duelist||
|Generate|TOK:AKH|Unwavering Initiate||
|Generate|TOK:AKH|Vizier of Many Faces||
|Generate|TOK:AKH|Warrior|||WarriorVigilantToken| |Generate|TOK:AKH|Warrior|||WarriorVigilantToken|
|Generate|TOK:AKH|Wurm|||WurmToken3| |Generate|TOK:AKH|Wurm|||WurmToken3|
|Generate|TOK:AKH|Zombie|| |Generate|TOK:AKH|Zombie|||ZombieToken
#TOK:AKH - some tokens from real cards (see Embalm ability)
#|Generate|TOK:AKH|Angel of Sanctions||
#|Generate|TOK:AKH|Anointer Priest||
#|Generate|TOK:AKH|Aven Initiate||
#|Generate|TOK:AKH|Aven Wind Guide||
#|Generate|TOK:AKH|Glyph Keeper||
#|Generate|TOK:AKH|Heart-Piercer Manticore||
#|Generate|TOK:AKH|Honored Hydra||
#|Generate|TOK:AKH|Labyrinth Guardian||
#|Generate|TOK:AKH|Oketra's Attendant||
#|Generate|TOK:AKH|Sacred Cat||
#|Generate|TOK:AKH|Tah-Crop Skirmisher||
#|Generate|TOK:AKH|Temmet, Vizier of Naktamun||
#|Generate|TOK:AKH|Trueheart Duelist||
#|Generate|TOK:AKH|Unwavering Initiate||
#|Generate|TOK:AKH|Vizier of Many Faces||
|Generate|TOK:ALA|Beast|||GodSireBeastToken| |Generate|TOK:ALA|Beast|||GodSireBeastToken|
|Generate|TOK:ALA|Dragon|||DragonToken| |Generate|TOK:ALA|Dragon|||DragonToken|
|Generate|TOK:ALA|Goblin|||GoblinTokenWithHaste| |Generate|TOK:ALA|Goblin|||GoblinTokenWithHaste|
@ -237,7 +243,7 @@
|Generate|TOK:BFZ|Eldrazi Scion|3||EldraziScionToken| |Generate|TOK:BFZ|Eldrazi Scion|3||EldraziScionToken|
|Generate|TOK:BFZ|Eldrazi|||EldraziToken| |Generate|TOK:BFZ|Eldrazi|||EldraziToken|
|Generate|TOK:BFZ|Elemental|1||OmnathElementalToken| |Generate|TOK:BFZ|Elemental|1||OmnathElementalToken|
|Generate|TOK:BFZ|Elemental|2||ElementalToken| |Generate|TOK:BFZ|Elemental|2||AkoumStonewakerElementalToken|
|Generate|TOK:BFZ|Knight Ally|||KnightAllyToken| |Generate|TOK:BFZ|Knight Ally|||KnightAllyToken|
|Generate|TOK:BFZ|Kor Ally|||KorAllyToken| |Generate|TOK:BFZ|Kor Ally|||KorAllyToken|
|Generate|TOK:BFZ|Octopus|||OctopusToken| |Generate|TOK:BFZ|Octopus|||OctopusToken|
@ -390,6 +396,30 @@
|Generate|TOK:C18|Thopter|3||ThopterColorlessToken| |Generate|TOK:C18|Thopter|3||ThopterColorlessToken|
|Generate|TOK:C18|Worm|||WormHarvestToken| |Generate|TOK:C18|Worm|||WormHarvestToken|
|Generate|TOK:C18|Zombie|||ZombieToken| |Generate|TOK:C18|Zombie|||ZombieToken|
|Generate|TOK:C19|Assassin|||AssassinToken|
|Generate|TOK:C19|Beast|1||BeastToken|
|Generate|TOK:C19|Beast|2||BeastToken2|
|Generate|TOK:C19|Bird|1||RocEggToken|
|Generate|TOK:C19|Bird|2||WingmateRocToken|
|Generate|TOK:C19|Centaur|||CentaurToken|
|Generate|TOK:C19|Dragon|||DragonToken2|
|Generate|TOK:C19|Drake|||DrakeToken|
|Generate|TOK:C19|Egg|||AtlaPalaniToken|
|Generate|TOK:C19|Eldrazi|||EldraziToken|
|Generate|TOK:C19|Gargoyle|||GargoyleToken|
|Generate|TOK:C19|Horror|||PhyrexianRebirthHorrorToken|
|Generate|TOK:C19|Human|||HumanToken|
|Generate|TOK:C19|Pegasus|||PegasusToken|
|Generate|TOK:C19|Plant|||GrismoldPlantToken|
|Generate|TOK:C19|Rhino|||RhinoToken|
|Generate|TOK:C19|Saproling|||SaprolingToken|
|Generate|TOK:C19|Sculpture|||DoomedArtisanToken|
|Generate|TOK:C19|Snake|||SnakeToken|
|Generate|TOK:C19|Spirit|||SpiritToken|
|Generate|TOK:C19|Treasure|||TreasureToken|
|Generate|TOK:C19|Wurm|||WurmToken|
|Generate|TOK:C19|Zombie|1||ZombieToken|
|Generate|TOK:C19|Zombie|2||ZombieToken|
|Generate|TOK:CHK|Dragon Spirit|||TatsumaDragonToken| |Generate|TOK:CHK|Dragon Spirit|||TatsumaDragonToken|
|Generate|TOK:CHK|Elemental|||SeedGuardianToken| |Generate|TOK:CHK|Elemental|||SeedGuardianToken|
|Generate|TOK:CHK|Illusion|||MelokuTheCloudedMirrorToken| |Generate|TOK:CHK|Illusion|||MelokuTheCloudedMirrorToken|
@ -551,16 +581,16 @@
|Generate|TOK:DOM|Construct|||KarnConstructToken| |Generate|TOK:DOM|Construct|||KarnConstructToken|
|Generate|TOK:DOM|Demon|||BelzenlokDemonToken| |Generate|TOK:DOM|Demon|||BelzenlokDemonToken|
|Generate|TOK:DOM|Elemental|||ValdukElementalToken| |Generate|TOK:DOM|Elemental|||ValdukElementalToken|
|Gererate|TOK:DOM|Goblin|| |Generate|TOK:DOM|Goblin|||GoblinToken|
|Generate|TOK:DOM|Karox Bladewing|||KaroxBladewingDragonToken| |Generate|TOK:DOM|Karox Bladewing|||KaroxBladewingDragonToken|
|Generate|TOK:DOM|Knight|1| |Generate|TOK:DOM|Knight|1||KnightToken|
|Generate|TOK:DOM|Knight|2| |Generate|TOK:DOM|Knight|2||KnightToken|
|Generate|TOK:DOM|Nightmare Horror|||ChainersTormentNightmareToken| |Generate|TOK:DOM|Nightmare Horror|||ChainersTormentNightmareToken|
|Generate|TOK:DOM|Saproling|1| |Generate|TOK:DOM|Saproling|1||SaprolingToken|
|Generate|TOK:DOM|Saproling|2| |Generate|TOK:DOM|Saproling|2||SaprolingToken|
|Generate|TOK:DOM|Saproling|3| |Generate|TOK:DOM|Saproling|3||SaprolingToken|
|Generate|TOK:DOM|Soldier|| |Generate|TOK:DOM|Soldier|||SoldierToken|
|Generate|TOK:DOM|Zombie Knight|| |Generate|TOK:DOM|Zombie Knight|||ZombieKnightToken|
|Generate|TOK:DRB|Saproling|||SaprolingToken| |Generate|TOK:DRB|Saproling|||SaprolingToken|
|Generate|TOK:DST|Beast|||BeastToken| |Generate|TOK:DST|Beast|||BeastToken|
|Generate|TOK:DST|Elemental|1||WandOfTheElementsFirstToken| |Generate|TOK:DST|Elemental|1||WandOfTheElementsFirstToken|
@ -599,15 +629,16 @@
|Generate|TOK:EMA|Wall|||TidalWaveWallToken| |Generate|TOK:EMA|Wall|||TidalWaveWallToken|
|Generate|TOK:EMA|Wurm|||WurmToken| |Generate|TOK:EMA|Wurm|||WurmToken|
|Generate|TOK:EMA|Zombie|||ZombieToken| |Generate|TOK:EMA|Zombie|||ZombieToken|
|Generate|TOK:EMN|Devil|||DevilToken| #TOK:EMN - Human Soldier, Spirit, Devil, Insect and Wolf tokens from SOI set
#|Generate|TOK:EMN|Devil|||DevilToken|
#|Generate|TOK:EMN|Human Soldier|||HumanSoldierToken|
#|Generate|TOK:EMN|Insect|||InsectToken|
#|Generate|TOK:EMN|Spirit|||SpiritWhiteToken|
#|Generate|TOK:EMN|Wolf|||WolfToken|
|Generate|TOK:EMN|Eldrazi Horror|||EldraziHorrorToken| |Generate|TOK:EMN|Eldrazi Horror|||EldraziHorrorToken|
|Generate|TOK:EMN|Human Soldier|||HumanSoldierToken|
|Generate|TOK:EMN|Human Wizard|||HumanWizardToken| |Generate|TOK:EMN|Human Wizard|||HumanWizardToken|
|Generate|TOK:EMN|Human|||RedHumanToken| |Generate|TOK:EMN|Human|||RedHumanToken|
|Generate|TOK:EMN|Insect|||InsectToken|
|Generate|TOK:EMN|Spider|||SpiderToken| |Generate|TOK:EMN|Spider|||SpiderToken|
|Generate|TOK:EMN|Spirit|||SpiritWhiteToken|
|Generate|TOK:EMN|Wolf|||WolfToken|
|Generate|TOK:EMN|Zombie|1||ZombieToken| |Generate|TOK:EMN|Zombie|1||ZombieToken|
|Generate|TOK:EMN|Zombie|2||ZombieToken| |Generate|TOK:EMN|Zombie|2||ZombieToken|
|Generate|TOK:EMN|Zombie|3||ZombieToken| |Generate|TOK:EMN|Zombie|3||ZombieToken|
@ -677,19 +708,20 @@
|Generate|TOK:HOP|Pentavite|||PentaviteToken| |Generate|TOK:HOP|Pentavite|||PentaviteToken|
|Generate|TOK:HOP|Pest|||PestToken| |Generate|TOK:HOP|Pest|||PestToken|
|Generate|TOK:HOP|Saproling|||SaprolingToken| |Generate|TOK:HOP|Saproling|||SaprolingToken|
|Generate|TOK:HOU|Horse|||CrestedSunmareToken|
|Generate|TOK:HOU|Insect|||TheLocustGodInsectToken|
|Generate|TOK:HOU|Snake|||RhonassLastStandToken|
#TOK:HOU - some tokens from real cards (see Eternalize ability)
#TOK:HOU - Cat, Warrior and Zombie tokens from AKH set
|Generate|TOK:HOU|Adorned Pouncer|||| |Generate|TOK:HOU|Adorned Pouncer||||
|Generate|TOK:HOU|Champion of Wits|||| |Generate|TOK:HOU|Champion of Wits||||
|Generate|TOK:HOU|Dreamstealer|||| |Generate|TOK:HOU|Dreamstealer||||
|Generate|TOK:HOU|Earthshaker Khenra|||| |Generate|TOK:HOU|Earthshaker Khenra||||
|Generate|TOK:HOU|Horse|||CrestedSunmareToken|
|Generate|TOK:HOU|Insect|||TheLocustGodInsectToken|
|Generate|TOK:HOU|Proven Combatant|||| |Generate|TOK:HOU|Proven Combatant||||
|Generate|TOK:HOU|Resilient Khenra|||| |Generate|TOK:HOU|Resilient Khenra||||
|Generate|TOK:HOU|Sinuous Striker|||| |Generate|TOK:HOU|Sinuous Striker||||
|Generate|TOK:HOU|Snake|||RhonassLastStandToken|
|Generate|TOK:HOU|Steadfast Sentinel|||| |Generate|TOK:HOU|Steadfast Sentinel||||
|Generate|TOK:HOU|Sunscourge Champion|||| |Generate|TOK:HOU|Sunscourge Champion||||
|Generate|TOK:HOU|Zombie||
|Generate|TOK:ICE|Caribou|||CaribouToken| |Generate|TOK:ICE|Caribou|||CaribouToken|
|Generate|TOK:INV|Bird|||OwlToken| |Generate|TOK:INV|Bird|||OwlToken|
|Generate|TOK:INV|Elephant|||ElephantToken| |Generate|TOK:INV|Elephant|||ElephantToken|
@ -1226,6 +1258,12 @@
|Generate|TOK:RNA|Thopter|||ThopterToken| |Generate|TOK:RNA|Thopter|||ThopterToken|
|Generate|TOK:RNA|Treasure|||TreasureToken| |Generate|TOK:RNA|Treasure|||TreasureToken|
|Generate|TOK:RNA|Zombie|||ZombieToken| |Generate|TOK:RNA|Zombie|||ZombieToken|
|Generate|TOK:GRN|Angel|||AngelVigilanceToken|
|Generate|TOK:GRN|Bird Illusion|||BirdIllusionToken|
|Generate|TOK:GRN|Elf Knight|||ElfKnightToken|
|Generate|TOK:GRN|Goblin|||GoblinToken|
|Generate|TOK:GRN|Insect|||IzoniInsectToken|
|Generate|TOK:GRN|Soldier|||SoldierLifelinkToken|
|Generate|TOK:WAR|Angel|||AngelVigilanceToken| |Generate|TOK:WAR|Angel|||AngelVigilanceToken|
|Generate|TOK:WAR|Assassin|||AssassinToken2| |Generate|TOK:WAR|Assassin|||AssassinToken2|
|Generate|TOK:WAR|Devil|||DevilToken| |Generate|TOK:WAR|Devil|||DevilToken|

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-common</artifactId> <artifactId>mage-common</artifactId>

View file

@ -11,7 +11,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
public static final int MAGE_VERSION_MAJOR = 1; public static final int MAGE_VERSION_MAJOR = 1;
public static final int MAGE_VERSION_MINOR = 4; public static final int MAGE_VERSION_MINOR = 4;
public static final int MAGE_VERSION_PATCH = 39; public static final int MAGE_VERSION_PATCH = 40;
public static final String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0 public static final String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0
public static final String MAGE_VERSION_MINOR_PATCH = "V0"; // default public static final String MAGE_VERSION_MINOR_PATCH = "V0"; // default
// strict mode // strict mode

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId> <artifactId>mage-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-counter-plugin</artifactId> <artifactId>mage-counter-plugin</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-plugins</artifactId> <artifactId>mage-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage.server.console</artifactId> <artifactId>mage.server.console</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-deck-constructed</artifactId> <artifactId>mage-deck-constructed</artifactId>

View file

@ -22,6 +22,7 @@ public class Brawl extends Constructed {
// Copy of standard sets // Copy of standard sets
setCodes.addAll(Standard.makeLegalSets()); setCodes.addAll(Standard.makeLegalSets());
banned.add("Oko, Thief of Crowns");
banned.add("Sorcerous Spyglass"); banned.add("Sorcerous Spyglass");
} }

View file

@ -90,6 +90,7 @@ public class Legacy extends Constructed {
banned.add("Wheel of Fortune"); banned.add("Wheel of Fortune");
banned.add("Windfall"); banned.add("Windfall");
banned.add("Worldknit"); banned.add("Worldknit");
banned.add("Wrenn and Six");
banned.add("Yawgmoth's Bargain"); banned.add("Yawgmoth's Bargain");
banned.add("Yawgmoth's Will"); banned.add("Yawgmoth's Will");

View file

@ -17,7 +17,10 @@ public class Standard extends Constructed {
setCodes.addAll(makeLegalSets()); setCodes.addAll(makeLegalSets());
banned.add("Field of the Dead"); // since 2019-10-21 banned.add("Field of the Dead");
banned.add("Oko, Thief of Crowns");
banned.add("Once Upon a Time");
banned.add("Veil of Summer");
} }
private static boolean isFallSet(ExpansionSet set) { private static boolean isFallSet(ExpansionSet set) {

View file

@ -75,6 +75,7 @@ public class Vintage extends Constructed {
restricted.add("Mox Sapphire"); restricted.add("Mox Sapphire");
restricted.add("Mystic Forge"); restricted.add("Mystic Forge");
restricted.add("Mystical Tutor"); restricted.add("Mystical Tutor");
restricted.add("Narset, Parter of Veils");
restricted.add("Necropotence"); restricted.add("Necropotence");
restricted.add("Ponder"); restricted.add("Ponder");
restricted.add("Sol Ring"); restricted.add("Sol Ring");

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-deck-limited</artifactId> <artifactId>mage-deck-limited</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-brawlduel</artifactId> <artifactId>mage-game-brawlduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-brawlfreeforall</artifactId> <artifactId>mage-game-brawlfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-canadianhighlanderduel</artifactId> <artifactId>mage-game-canadianhighlanderduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-commanderduel</artifactId> <artifactId>mage-game-commanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-commanderfreeforall</artifactId> <artifactId>mage-game-commanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-freeforall</artifactId> <artifactId>mage-game-freeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-freeformcommanderduel</artifactId> <artifactId>mage-game-freeformcommanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-freeformcommanderfreeforall</artifactId> <artifactId>mage-game-freeformcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-momirduel</artifactId> <artifactId>mage-game-momirduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-momirfreeforall</artifactId> <artifactId>mage-game-momirfreeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-oathbreakerduel</artifactId> <artifactId>mage-game-oathbreakerduel</artifactId>
@ -22,7 +22,7 @@
<dependency> <dependency>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-game-oathbreakerfreeforall</artifactId> <artifactId>mage-game-oathbreakerfreeforall</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-oathbreakerfreeforall</artifactId> <artifactId>mage-game-oathbreakerfreeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId> <artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-tinyleadersduel</artifactId> <artifactId>mage-game-tinyleadersduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-game-twoplayerduel</artifactId> <artifactId>mage-game-twoplayerduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-player-ai-draftbot</artifactId> <artifactId>mage-player-ai-draftbot</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-player-ai-ma</artifactId> <artifactId>mage-player-ai-ma</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-player-ai</artifactId> <artifactId>mage-player-ai</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-player-ai-mcts</artifactId> <artifactId>mage-player-ai-mcts</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-player-aiminimax</artifactId> <artifactId>mage-player-aiminimax</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-player-human</artifactId> <artifactId>mage-player-human</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-tournament-boosterdraft</artifactId> <artifactId>mage-tournament-boosterdraft</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-tournament-constructed</artifactId> <artifactId>mage-tournament-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-tournament-sealed</artifactId> <artifactId>mage-tournament-sealed</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-server-plugins</artifactId> <artifactId>mage-server-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-server</artifactId> <artifactId>mage-server</artifactId>

View file

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-sets</artifactId> <artifactId>mage-sets</artifactId>

View file

@ -1,8 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
@ -17,22 +14,24 @@ import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.ElementalToken; import mage.game.permanent.token.ElementalToken;
import mage.players.Player; import mage.players.Player;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author fireshoes * @author fireshoes
*/ */
public final class ChandraFlamecaller extends CardImpl { public final class ChandraFlamecaller extends CardImpl {
public ChandraFlamecaller(UUID ownerId, CardSetInfo setInfo) { public ChandraFlamecaller(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{4}{R}{R}"); super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{R}{R}");
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA); this.subtype.add(SubType.CHANDRA);
@ -78,7 +77,7 @@ class ChandraElementalEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
CreateTokenEffect effect = new CreateTokenEffect(new ElementalToken("OGW", 1, true), 2); CreateTokenEffect effect = new CreateTokenEffect(new ElementalToken("OGW", 2, true), 2);
effect.apply(game, source); effect.apply(game, source);
effect.exileTokensCreatedAtNextEndStep(game, source); effect.exileTokensCreatedAtNextEndStep(game, source);
return true; return true;

View file

@ -1,5 +1,6 @@
package mage.cards.d; package mage.cards.d;
import java.util.HashMap;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
@ -15,8 +16,7 @@ import mage.game.events.GameEvent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import java.util.HashSet; import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
@ -45,13 +45,18 @@ class DeafeningSilenceEffect extends ContinuousRuleModifyingEffectImpl {
DeafeningSilenceEffect() { DeafeningSilenceEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment); super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "each player can't cast more than one noncreature spell each turn"; staticText = "Each player can't cast more than one noncreature spell each turn";
} }
private DeafeningSilenceEffect(final DeafeningSilenceEffect effect) { private DeafeningSilenceEffect(final DeafeningSilenceEffect effect) {
super(effect); super(effect);
} }
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
return "Each player can't cast more than one noncreature spell each turn";
}
@Override @Override
public DeafeningSilenceEffect copy() { public DeafeningSilenceEffect copy() {
return new DeafeningSilenceEffect(this); return new DeafeningSilenceEffect(this);
@ -69,18 +74,20 @@ class DeafeningSilenceEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
Card card = game.getCard(event.getTargetId()); Card card = game.getCard(event.getSourceId());
if (card == null || card.isCreature()) { if (card == null
|| card.isCreature()) {
return false; return false;
} }
DeafeningSilenceWatcher watcher = game.getState().getWatcher(DeafeningSilenceWatcher.class); DeafeningSilenceWatcher watcher = game.getState().getWatcher(DeafeningSilenceWatcher.class);
return watcher != null && watcher.castSpell(event.getPlayerId()); return watcher != null
&& watcher.spellsCastByPlayerThisTurnNonCreature(event.getPlayerId()) > 1;
} }
} }
class DeafeningSilenceWatcher extends Watcher { class DeafeningSilenceWatcher extends Watcher {
private final Set<UUID> castSpell = new HashSet<>(); private final Map<UUID, Integer> spellsCastByPlayerThisTurnNonCreature = new HashMap<>();
DeafeningSilenceWatcher() { DeafeningSilenceWatcher() {
super(WatcherScope.GAME); super(WatcherScope.GAME);
@ -88,7 +95,9 @@ class DeafeningSilenceWatcher extends Watcher {
private DeafeningSilenceWatcher(final DeafeningSilenceWatcher watcher) { private DeafeningSilenceWatcher(final DeafeningSilenceWatcher watcher) {
super(watcher); super(watcher);
this.castSpell.addAll(watcher.castSpell); for (Map.Entry<UUID, Integer> entry : watcher.spellsCastByPlayerThisTurnNonCreature.entrySet()) {
spellsCastByPlayerThisTurnNonCreature.put(entry.getKey(), entry.getValue());
}
} }
@Override @Override
@ -97,19 +106,29 @@ class DeafeningSilenceWatcher extends Watcher {
return; return;
} }
Spell spell = game.getSpell(event.getTargetId()); Spell spell = game.getSpell(event.getTargetId());
if (spell == null || spell.isCreature()) { if (spell == null
|| spell.isCreature()) {
return; return;
} }
castSpell.add(event.getPlayerId()); UUID playerId = event.getPlayerId();
if (playerId != null) {
spellsCastByPlayerThisTurnNonCreature.putIfAbsent(playerId, 0);
spellsCastByPlayerThisTurnNonCreature.compute(playerId, (k, v) -> v + 1);
}
} }
@Override @Override
public void reset() { public void reset() {
super.reset(); super.reset();
castSpell.clear(); spellsCastByPlayerThisTurnNonCreature.clear();
} }
boolean castSpell(UUID playerId) { public int spellsCastByPlayerThisTurnNonCreature(UUID playerId) {
return castSpell.contains(playerId); return spellsCastByPlayerThisTurnNonCreature.getOrDefault(playerId, 0);
}
@Override
public DeafeningSilenceWatcher copy() {
return new DeafeningSilenceWatcher(this);
} }
} }

View file

@ -7,7 +7,6 @@ import mage.abilities.effects.common.continuous.CastAsThoughItHadFlashAllEffect;
import mage.abilities.effects.common.continuous.LookAtTopCardOfLibraryAnyTimeEffect; import mage.abilities.effects.common.continuous.LookAtTopCardOfLibraryAnyTimeEffect;
import mage.abilities.effects.common.continuous.PlayTheTopCardEffect; import mage.abilities.effects.common.continuous.PlayTheTopCardEffect;
import mage.abilities.keyword.ProwessAbility; import mage.abilities.keyword.ProwessAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -16,11 +15,8 @@ import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard; import mage.filter.common.FilterNonlandCard;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID; import java.util.UUID;
@ -33,7 +29,6 @@ public final class ElshaOfTheInfinite extends CardImpl {
static { static {
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
filter.add(ElshaOfTheInfinitePredicate.instance);
} }
public ElshaOfTheInfinite(UUID ownerId, CardSetInfo setInfo) { public ElshaOfTheInfinite(UUID ownerId, CardSetInfo setInfo) {
@ -72,13 +67,3 @@ public final class ElshaOfTheInfinite extends CardImpl {
return new ElshaOfTheInfinite(this); return new ElshaOfTheInfinite(this);
} }
} }
enum ElshaOfTheInfinitePredicate implements Predicate<Card> {
instance;
@Override
public boolean apply(Card input, Game game) {
Player player = game.getPlayer(input.getOwnerId());
return player != null && player.getLibrary().getFromTop(game).equals(input);
}
}

View file

@ -72,7 +72,7 @@ class EscapedShapeshifterEffect extends ContinuousEffectImpl {
source.getControllerId(), source.getSourceId(), game source.getControllerId(), source.getSourceId(), game
).stream() ).stream()
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(permanent -> permanent.getName() != "Escaped Shapeshifter") .filter(permanent -> !permanent.getName().equals(sourcePermanent.getName()))
.map(Permanent::getAbilities) .map(Permanent::getAbilities)
.flatMap(Collection::stream).filter(EscapedShapeshifterEffect::checkAbility) .flatMap(Collection::stream).filter(EscapedShapeshifterEffect::checkAbility)
.forEach(ability -> sourcePermanent.addAbility(ability, source.getSourceId(), game)); .forEach(ability -> sourcePermanent.addAbility(ability, source.getSourceId(), game));

View file

@ -5,7 +5,6 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.AsTurnedFaceUpEffect; import mage.abilities.effects.AsTurnedFaceUpEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.EnchantAbility;
@ -17,23 +16,33 @@ import mage.constants.AttachmentType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID; import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import static mage.constants.Outcome.Benefit; import static mage.constants.Outcome.Benefit;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.target.targetadjustment.TargetAdjuster;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public final class GiftOfDoom extends CardImpl { public final class GiftOfDoom extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
static {
filter.add(AnotherPredicate.instance);
}
public GiftOfDoom(UUID ownerId, CardSetInfo setInfo) { public GiftOfDoom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}");
@ -42,26 +51,30 @@ public final class GiftOfDoom extends CardImpl {
// Enchant creature // Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent(); TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
this.getSpellAbility().setTargetAdjuster(GiftOfDoomAdjuster.instance); // to remove the target set if Morph casting cost is paid
Ability ability = new EnchantAbility(auraTarget.getTargetName()); Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability); this.addAbility(ability);
// Enchanted creature has deathtouch and indestructible. // Enchanted creature has deathtouch and indestructible.
ability = new SimpleStaticAbility(new GainAbilityAttachedEffect( Ability ability2 = new SimpleStaticAbility(new GainAbilityAttachedEffect(
DeathtouchAbility.getInstance(), AttachmentType.AURA DeathtouchAbility.getInstance(), AttachmentType.AURA
)); ));
ability.addEffect(new GainAbilityAttachedEffect( ability2.addEffect(new GainAbilityAttachedEffect(
IndestructibleAbility.getInstance(), AttachmentType.AURA IndestructibleAbility.getInstance(), AttachmentType.AURA
)); ));
this.addAbility(ability); this.addAbility(ability2);
// MorphSacrifice another creature. // MorphSacrifice another creature.
this.addAbility(new MorphAbility(this, new SacrificeTargetCost( this.addAbility(new MorphAbility(this, new SacrificeTargetCost(
new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE) new TargetControlledPermanent(filter)
))); )));
// As Gift of Doom is turned face up, you may attach it to a creature. // As Gift of Doom is turned face up, you may attach it to a creature.
this.addAbility(new SimpleStaticAbility(new AsTurnedFaceUpEffect(new GiftOfDoomEffect(), true))); Effect effect = new AsTurnedFaceUpEffect(new GiftOfDoomEffect(), true);
Ability ability3 = new SimpleStaticAbility(effect);
ability3.setWorksFaceDown(true);
this.addAbility(ability3);
} }
private GiftOfDoom(final GiftOfDoom card) { private GiftOfDoom(final GiftOfDoom card) {
@ -74,8 +87,26 @@ public final class GiftOfDoom extends CardImpl {
} }
} }
enum GiftOfDoomAdjuster implements TargetAdjuster {
instance;
@Override
public void adjustTargets(Ability ability, Game game) {
// if the Morph casting cost is paid, clear the target of Enchant Creature
if (game.getState().getValue("MorphAbility" + ability.getSourceId()) == "activated") {
ability.getTargets().clear();
}
}
}
class GiftOfDoomEffect extends OneShotEffect { class GiftOfDoomEffect extends OneShotEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
static {
filter.add(AnotherPredicate.instance);
}
GiftOfDoomEffect() { GiftOfDoomEffect() {
super(Benefit); super(Benefit);
staticText = "attach it to a creature"; staticText = "attach it to a creature";
@ -93,16 +124,20 @@ class GiftOfDoomEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent giftOfDoom = game.getPermanent(source.getSourceId());
if (player == null || permanent == null) { if (player == null || giftOfDoom == null) {
return false; return false;
} }
TargetCreaturePermanent target = new TargetCreaturePermanent(0, 1); TargetCreaturePermanent target = new TargetCreaturePermanent(filter);
target.setNotTarget(true); target.setNotTarget(true);
if (!player.choose(outcome, target, source.getSourceId(), game)) { if (player.choose(outcome, target, source.getSourceId(), game)
return false; && game.getPermanent(target.getFirstTarget()) != null
} && !game.getPermanent(target.getFirstTarget()).cantBeAttachedBy(giftOfDoom, game)) {
permanent.attachTo(target.getFirstTarget(), game); game.getState().setValue("attachTo:" + giftOfDoom.getId(), target.getFirstTarget());
game.getPermanent(target.getFirstTarget()).addAttachment(giftOfDoom.getId(), game);
return true; return true;
} }
player.moveCardToGraveyardWithInfo(giftOfDoom, source.getId(), game, Zone.BATTLEFIELD); //no legal target
return false;
}
} }

View file

@ -6,7 +6,6 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CopyEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect; import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -105,21 +104,21 @@ class IdentityThiefEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget()); Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget());
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && permanent != null && sourcePermanent != null) { if (controller != null
CopyEffect copyEffect = new CopyEffect(Duration.EndOfTurn, permanent, source.getSourceId()); && permanent != null
if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.BATTLEFIELD, true)) { && sourcePermanent != null) {
// Copy exiled permanent game.copyPermanent(permanent, sourcePermanent.getId(), source, null);
game.addEffect(copyEffect, source); if (controller.moveCardToExileWithInfo(permanent, source.getSourceId(), sourcePermanent.getIdName(),
// Create delayed triggered ability source.getSourceId(), game, Zone.BATTLEFIELD, true)) {
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(); Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return the exiled card to the battlefield under its owner's control at the beginning of the next end step"); effect.setText("Return the exiled card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game)); effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source); game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
} }
return true;
} }
return false; return false;
} }

View file

@ -1,10 +1,9 @@
package mage.cards.k; package mage.cards.k;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -12,25 +11,22 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone; import mage.filter.common.FilterControlledPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.permanent.token.GoblinToken; import mage.game.permanent.token.GoblinToken;
import java.util.UUID;
/** /**
*
* @author North * @author North
*/ */
public final class KrenkoMobBoss extends CardImpl { public final class KrenkoMobBoss extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("the number of Goblins you control"); private static final FilterControlledPermanent filter
= new FilterControlledPermanent(SubType.GOBLIN, "the number of Goblins you control");
static { private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(filter);
filter.add(new SubtypePredicate(SubType.GOBLIN));
}
public KrenkoMobBoss(UUID ownerId, CardSetInfo setInfo) { public KrenkoMobBoss(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
addSuperType(SuperType.LEGENDARY); addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.GOBLIN); this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.WARRIOR); this.subtype.add(SubType.WARRIOR);
@ -39,12 +35,12 @@ public final class KrenkoMobBoss extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// {tap}: create X 1/1 red Goblin creature tokens, where X is the number of Goblins you control. // {tap}: create X 1/1 red Goblin creature tokens, where X is the number of Goblins you control.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, this.addAbility(new SimpleActivatedAbility(
new CreateTokenEffect(new GoblinToken(), new PermanentsOnBattlefieldCount(filter)), new CreateTokenEffect(new GoblinToken(), xValue), new TapSourceCost()
new TapSourceCost())); ));
} }
public KrenkoMobBoss(final KrenkoMobBoss card) { private KrenkoMobBoss(final KrenkoMobBoss card) {
super(card); super(card);
} }

View file

@ -71,9 +71,9 @@ class LeadershipVacuumEffect extends OneShotEffect {
if (player == null) { if (player == null) {
return false; return false;
} }
return player.moveCards(game.getBattlefield()
.getAllActivePermanents(filter, source.getFirstTarget(), game) return game.getBattlefield().getAllActivePermanents(filter, source.getFirstTarget(), game).stream()
.stream() .map(commander -> commander.moveToZone(Zone.COMMAND, source.getId(), game, true))
.collect(Collectors.toSet()), Zone.COMMAND, source, game); .reduce(true, Boolean::logicalAnd);
} }
} }

View file

@ -15,7 +15,7 @@ import mage.constants.SetTargetPointer;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import java.util.UUID; import java.util.UUID;
@ -24,7 +24,7 @@ import java.util.UUID;
*/ */
public final class LeylineOfAbundance extends CardImpl { public final class LeylineOfAbundance extends CardImpl {
private static final FilterPermanent filter = new FilterCreaturePermanent("you tap a creature"); private static final FilterPermanent filter = new FilterControlledCreaturePermanent("you tap a creature");
public LeylineOfAbundance(UUID ownerId, CardSetInfo setInfo) { public LeylineOfAbundance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");

View file

@ -0,0 +1,129 @@
package mage.cards.m;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TurnPhase;
import mage.game.Game;
import mage.game.combat.Combat;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
/**
*
* @author goesta
*/
public final class MandateOfPeace extends CardImpl {
public MandateOfPeace(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}");
// Cast this spell only during combat.
this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(TurnPhase.COMBAT));
// Your opponents can't cast spells this turn.
this.getSpellAbility().addEffect(new MandateOfPeaceOpponentsCantCastSpellsEffect());
// End the combat phase.
this.getSpellAbility().addEffect(new MandateOfPeaceEndCombatEffect());
}
private MandateOfPeace(final MandateOfPeace card) {
super(card);
}
@Override
public MandateOfPeace copy() {
return new MandateOfPeace(this);
}
}
class MandateOfPeaceOpponentsCantCastSpellsEffect extends ContinuousRuleModifyingEffectImpl {
public MandateOfPeaceOpponentsCantCastSpellsEffect() {
super(Duration.EndOfTurn, Outcome.Benefit);
staticText = "Your opponents can't cast spells this turn.";
}
public MandateOfPeaceOpponentsCantCastSpellsEffect(final MandateOfPeaceOpponentsCantCastSpellsEffect effect) {
super(effect);
}
@Override
public MandateOfPeaceOpponentsCantCastSpellsEffect copy() {
return new MandateOfPeaceOpponentsCantCastSpellsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) {
return "You can't cast spells this turn (" + mageObject.getIdName() + ").";
}
return null;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CAST_SPELL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return game.getOpponents(source.getControllerId()).contains(event.getPlayerId());
}
}
class MandateOfPeaceEndCombatEffect extends OneShotEffect {
public MandateOfPeaceEndCombatEffect() {
super(Outcome.Benefit);
this.staticText = "End the combat phase. <i>(Remove all attackers and blockers from combat. Exile all spells and abilities from the stack, including this spell.)</i>";
}
public MandateOfPeaceEndCombatEffect(OneShotEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Combat combat = game.getCombat();
List<UUID> attackerIds = combat.getAttackers();
List<UUID> blockerIds = combat.getBlockers();
Stream.concat(blockerIds.stream(), attackerIds.stream())
.map(id -> game.getPermanent(id))
.filter(e -> e != null)
.forEach(permanent -> permanent.removeFromCombat(game));
game.getStack().stream()
.filter(stackObject -> stackObject instanceof Spell)
.forEach(stackObject -> ((Spell) stackObject).moveToExile(null, "", null, game));
game.getStack().stream()
.filter(stackObject -> stackObject instanceof Ability)
.forEach(stackObject -> game.getStack().counter(stackObject.getId(), source.getSourceId(), game));
combat.endCombat(game);
return true;
}
@Override
public Effect copy() {
return new MandateOfPeaceEndCombatEffect(this);
}
}

View file

@ -76,7 +76,7 @@ class MesmericFiendExileEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget()); Player opponent = game.getPlayer(source.getFirstTarget());
Permanent sourcePermanent = (Permanent) source.getSourceObject(game); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null if (controller != null
&& opponent != null && opponent != null
&& sourcePermanent != null) { && sourcePermanent != null) {

View file

@ -5,7 +5,6 @@ import mage.ObjectColor;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect; import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.keyword.DeathtouchAbility; import mage.abilities.keyword.DeathtouchAbility;
@ -13,13 +12,12 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import java.util.UUID; import java.util.UUID;
import mage.abilities.condition.common.OpponentControlsPermanentCondition;
import mage.constants.ComparisonType;
/** /**
* @author TheElk801 * @author TheElk801
@ -30,11 +28,10 @@ public final class OakhameAdversary extends CardImpl {
= new FilterPermanent("your opponent controls a green permanent"); = new FilterPermanent("your opponent controls a green permanent");
static { static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
filter.add(new ColorPredicate(ObjectColor.GREEN)); filter.add(new ColorPredicate(ObjectColor.GREEN));
} }
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(filter); private static final Condition condition = new OpponentControlsPermanentCondition(filter, ComparisonType.MORE_THAN, 0);
public OakhameAdversary(UUID ownerId, CardSetInfo setInfo) { public OakhameAdversary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");

View file

@ -1,4 +1,3 @@
package mage.cards.p; package mage.cards.p;
import java.util.UUID; import java.util.UUID;
@ -7,6 +6,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -18,18 +18,15 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
/** /**
* @author Plopman * @author Plopman
*/ */
public final class PerniciousDeed extends CardImpl { public final class PerniciousDeed extends CardImpl {
public PerniciousDeed(UUID ownerId, CardSetInfo setInfo) { public PerniciousDeed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{G}");
// {X}, Sacrifice Pernicious Deed: Destroy each artifact, creature, and enchantment with converted mana cost X or less. // {X}, Sacrifice Pernicious Deed: Destroy each artifact, creature, and enchantment with converted mana cost X or less.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PerniciousDeedEffect(), new VariableManaCost()); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PerniciousDeedEffect(), new VariableManaCost());
ability.addCost(new SacrificeSourceCost()); ability.addCost(new SacrificeSourceCost());
@ -46,16 +43,13 @@ public final class PerniciousDeed extends CardImpl {
} }
} }
class PerniciousDeedEffect extends OneShotEffect { class PerniciousDeedEffect extends OneShotEffect {
public PerniciousDeedEffect() { public PerniciousDeedEffect() {
super(Outcome.DestroyPermanent); super(Outcome.DestroyPermanent);
staticText = "Destroy each artifact, creature, and enchantment with converted mana cost X or less"; staticText = "Destroy each artifact, creature, and enchantment with converted mana cost X or less";
} }
public PerniciousDeedEffect(final PerniciousDeedEffect effect) { public PerniciousDeedEffect(final PerniciousDeedEffect effect) {
super(effect); super(effect);
} }
@ -68,21 +62,15 @@ class PerniciousDeedEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
FilterPermanent filter = new FilterPermanent("artifacts, creatures, and enchantments"); FilterPermanent filter = new FilterPermanent("artifacts, creatures, and enchantments");
filter.add(Predicates.or( filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE), new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.ENCHANTMENT))); new CardTypePredicate(CardType.ENCHANTMENT)));
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, source.getManaCostsToPay().getX() + 1)); filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, source.getManaCostsToPay().getX() + 1));
return new DestroyAllEffect(filter).apply(game, source);
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
permanent.destroy(source.getSourceId(), game, false);
}
return true;
} }
} }

View file

@ -66,7 +66,6 @@ class PollenbrightWingsAbility extends TriggeredAbilityImpl {
public PollenbrightWingsAbility() { public PollenbrightWingsAbility() {
super(Zone.BATTLEFIELD, new PollenbrightWingsEffect()); super(Zone.BATTLEFIELD, new PollenbrightWingsEffect());
this.addEffect(new UntapAllLandsControllerEffect());
} }
public PollenbrightWingsAbility(final PollenbrightWingsAbility ability) { public PollenbrightWingsAbility(final PollenbrightWingsAbility ability) {

View file

@ -96,8 +96,8 @@ class RepeatedReverberationTriggeredAbility extends DelayedTriggeredAbility {
@Override @Override
public String getRule() { public String getRule() {
return "When you next cast an instant spell, cast a sorcery spell, or activate a loyalty ability this turn, " + return "When you next cast an instant spell, cast a sorcery spell, or activate a loyalty ability this turn, "
"copy that spell or ability twice. You may choose new targets for the copies."; + "copy that spell or ability twice. You may choose new targets for the copies.";
} }
} }
@ -118,7 +118,7 @@ class RepeatedReverberationEffect extends OneShotEffect {
return false; return false;
} }
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(stackAbility.getStackAbility().getSourceId()); Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(stackAbility.getStackAbility().getSourceId());
if (controller == null || sourcePermanent == null) { if (controller == null || sourcePermanent == null) {
return false; return false;
} }

View file

@ -1,23 +1,20 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HexproofAbility; import mage.abilities.keyword.HexproofAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.PermanentCard; import mage.game.permanent.Permanent;
import mage.game.stack.Spell; import mage.players.Player;
import mage.game.stack.StackAbility;
import java.util.UUID;
/** /**
* @author noxx * @author noxx
@ -72,28 +69,12 @@ class SigardaHostOfHeronsEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getPlayerId().equals(source.getControllerId())) { Player controller = game.getPlayer(source.getControllerId());
MageObject object = game.getObject(event.getSourceId()); UUID eventSourceControllerId = game.getControllerId(event.getSourceId());
if (object instanceof PermanentCard) { Permanent permanent = game.getPermanent(event.getTargetId());
if (game.getOpponents(source.getControllerId()).contains(((PermanentCard) object).getControllerId())) {
return true; if (controller != null && permanent != null && permanent.getControllerId() == source.getControllerId()) {
} return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
}
if (object instanceof Spell) {
if (game.getOpponents(source.getControllerId()).contains(((Spell) object).getControllerId())) {
return true;
}
}
if (object instanceof Card) {
if (game.getOpponents(source.getControllerId()).contains(((Card) object).getOwnerId())) {
return true;
}
}
if (object instanceof StackAbility) {
if (game.getOpponents(source.getControllerId()).contains(((StackAbility) object).getControllerId())) {
return true;
}
}
} }
return false; return false;
} }

View file

@ -1,8 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -16,11 +13,7 @@ import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AttachmentType; import mage.constants.*;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamagedPlayerEvent; import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
@ -28,18 +21,25 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/** /**
*
* @author Viserion * @author Viserion
*/ */
public final class SwordOfFeastAndFamine extends CardImpl { public final class SwordOfFeastAndFamine extends CardImpl {
public SwordOfFeastAndFamine(UUID ownerId, CardSetInfo setInfo) { public SwordOfFeastAndFamine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT); this.subtype.add(SubType.EQUIPMENT);
// Equip {2}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2))); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2)));
// Equipped creature gets +2/+2 and has protection from black and from green.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.GREEN, ObjectColor.BLACK), AttachmentType.EQUIPMENT))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ProtectionAbility.from(ObjectColor.GREEN, ObjectColor.BLACK), AttachmentType.EQUIPMENT)));
// Whenever equipped creature deals combat damage to a player, that player discards a card and you untap all lands you control.
this.addAbility(new SwordOfFeastAndFamineAbility()); this.addAbility(new SwordOfFeastAndFamineAbility());
} }
@ -76,7 +76,7 @@ class SwordOfFeastAndFamineAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event;
Permanent p = game.getPermanent(event.getSourceId()); Permanent p = game.getPermanent(event.getSourceId());
if (damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId())) { if (damageEvent.isCombatDamage() && p != null && p.getAttachments().contains(this.getSourceId())) {
for (Effect effect : this.getEffects()) { for (Effect effect : this.getEffects()) {

View file

@ -1,9 +1,6 @@
package mage.cards.t; package mage.cards.t;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.ReplacementEffectImpl;
@ -13,8 +10,9 @@ import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard; import mage.players.Player;
import mage.game.stack.Spell;
import java.util.UUID;
/** /**
* @author noxx * @author noxx
@ -22,7 +20,7 @@ import mage.game.stack.Spell;
public final class TajuruPreserver extends CardImpl { public final class TajuruPreserver extends CardImpl {
public TajuruPreserver(UUID ownerId, CardSetInfo setInfo) { public TajuruPreserver(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.ELF); this.subtype.add(SubType.ELF);
this.subtype.add(SubType.SHAMAN); this.subtype.add(SubType.SHAMAN);
@ -71,20 +69,14 @@ class TajuruPreserverEffect extends ReplacementEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
UUID eventSourceControllerId = game.getControllerId(event.getSourceId());
Permanent permanent = game.getPermanent(event.getTargetId()); Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && permanent.isControlledBy(source.getControllerId())) {
MageObject object = game.getObject(event.getSourceId()); if (controller != null && permanent != null && permanent.getControllerId() == source.getControllerId()) {
if (object instanceof PermanentCard) { return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
if (game.getOpponents(source.getControllerId()).contains(((PermanentCard)object).getControllerId())) {
return true;
}
}
if (object instanceof Spell) {
if (game.getOpponents(source.getControllerId()).contains(((Spell)object).getControllerId())) {
return true;
}
}
} }
return false; return false;
} }

View file

@ -1,6 +1,5 @@
package mage.cards.t; package mage.cards.t;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
@ -15,9 +14,7 @@ import mage.choices.ChoiceImpl;
import mage.constants.*; import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.PermanentCard; import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.game.stack.StackAbility;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
@ -63,8 +60,8 @@ class TamiyoCollectorOfTalesRuleEffect extends ContinuousRuleModifyingEffectImpl
TamiyoCollectorOfTalesRuleEffect() { TamiyoCollectorOfTalesRuleEffect() {
super(Duration.WhileOnBattlefield, Benefit); super(Duration.WhileOnBattlefield, Benefit);
staticText = "Spells and abilities your opponents control can't " + staticText = "Spells and abilities your opponents control can't "
"cause you to discard cards or sacrifice permanents"; + "cause you to discard cards or sacrifice permanents";
} }
private TamiyoCollectorOfTalesRuleEffect(final TamiyoCollectorOfTalesRuleEffect effect) { private TamiyoCollectorOfTalesRuleEffect(final TamiyoCollectorOfTalesRuleEffect effect) {
@ -84,28 +81,17 @@ class TamiyoCollectorOfTalesRuleEffect extends ContinuousRuleModifyingEffectImpl
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getPlayerId().equals(source.getControllerId())) { Player controller = game.getPlayer(source.getControllerId());
MageObject object = game.getObject(event.getSourceId()); UUID eventSourceControllerId = game.getControllerId(event.getSourceId());
if (object instanceof PermanentCard) {
if (game.getOpponents(source.getControllerId()).contains(((PermanentCard) object).getControllerId())) { Permanent permanent = game.getPermanent(event.getTargetId());
return true; if (controller != null && permanent != null && permanent.getControllerId() == source.getControllerId()) {
} return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
}
if (object instanceof Spell) {
if (game.getOpponents(source.getControllerId()).contains(((Spell) object).getControllerId())) {
return true;
}
}
if (object instanceof Card) {
if (game.getOpponents(source.getControllerId()).contains(((Card) object).getOwnerId())) {
return true;
}
}
if (object instanceof StackAbility) {
if (game.getOpponents(source.getControllerId()).contains(((StackAbility) object).getControllerId())) {
return true;
}
} }
Card cardInHand = game.getCard(event.getTargetId());
if (controller != null && cardInHand != null && cardInHand.getOwnerId() == source.getControllerId()) {
return game.getOpponents(source.getControllerId()).contains(eventSourceControllerId);
} }
return false; return false;
} }
@ -115,8 +101,8 @@ class TamiyoCollectorOfTalesEffect extends OneShotEffect {
TamiyoCollectorOfTalesEffect() { TamiyoCollectorOfTalesEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
staticText = "Choose a nonland card name, then reveal the top four cards of your library. " + staticText = "Choose a nonland card name, then reveal the top four cards of your library. "
"Put all cards with the chosen name from among them into your hand and the rest into your graveyard."; + "Put all cards with the chosen name from among them into your hand and the rest into your graveyard.";
} }
private TamiyoCollectorOfTalesEffect(final TamiyoCollectorOfTalesEffect effect) { private TamiyoCollectorOfTalesEffect(final TamiyoCollectorOfTalesEffect effect) {
@ -145,9 +131,9 @@ class TamiyoCollectorOfTalesEffect extends OneShotEffect {
Cards cards2 = new CardsImpl(); Cards cards2 = new CardsImpl();
player.revealCards(source, cards, game); player.revealCards(source, cards, game);
for (Card card : cards.getCards(game)) { for (Card card : cards.getCards(game)) {
if(card.isSplitCard()){ if (card.isSplitCard()) {
if(((SplitCard) card).getLeftHalfCard().getName().equals(choice.getChoice()) || if (((SplitCard) card).getLeftHalfCard().getName().equals(choice.getChoice())
((SplitCard) card).getRightHalfCard().getName().equals(choice.getChoice())){ || ((SplitCard) card).getRightHalfCard().getName().equals(choice.getChoice())) {
cards2.add(card); cards2.add(card);
} }
} }
@ -160,4 +146,5 @@ class TamiyoCollectorOfTalesEffect extends OneShotEffect {
player.moveCards(cards2, Zone.HAND, source, game); player.moveCards(cards2, Zone.HAND, source, game);
return true; return true;
} }
} }

View file

@ -1,6 +1,5 @@
package mage.cards.t; package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
@ -9,17 +8,8 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect; import mage.abilities.effects.common.continuous.AddCardTypeTargetEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect;
import mage.cards.Card; import mage.cards.*;
import mage.constants.SubType; import mage.constants.*;
import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -29,8 +19,9 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class TezzeretCruelMachinist extends CardImpl { public final class TezzeretCruelMachinist extends CardImpl {
@ -98,25 +89,29 @@ class TezzeretCruelMachinistEffect extends OneShotEffect {
return false; return false;
} }
Cards cardsToMove = new CardsImpl(); Cards cardsToMove = new CardsImpl();
for (UUID cardId : target.getTargets()) { for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
if (card == null) { if (card == null) {
continue; continue;
} }
cardsToMove.add(card); cardsToMove.add(card);
ContinuousEffect effect = new TezzeretCruelMachinistCardTypeEffect();
effect.setTargetPointer(new FixedTarget( ContinuousEffect effectCardType = new TezzeretCruelMachinistCardTypeEffect();
effectCardType.setTargetPointer(new FixedTarget(
card.getId(), card.getId(),
card.getZoneChangeCounter(game) + 1 card.getZoneChangeCounter(game) + 1
)); ));
game.addEffect(effect, source); game.addEffect(effectCardType, source);
effect = new TezzeretCruelMachinistPowerToughnessEffect();
effect.setTargetPointer(new FixedTarget( ContinuousEffect effectPowerToughness = new TezzeretCruelMachinistPowerToughnessEffect();
effectPowerToughness.setTargetPointer(new FixedTarget(
card.getId(), card.getId(),
card.getZoneChangeCounter(game) + 1 card.getZoneChangeCounter(game) + 1
)); ));
game.addEffect(effect, source); game.addEffect(effectPowerToughness, source);
} }
return player.moveCards(cardsToMove.getCards(game), Zone.BATTLEFIELD, source, game, false, true, true, null); return player.moveCards(cardsToMove.getCards(game), Zone.BATTLEFIELD, source, game, false, true, true, null);
} }
} }
@ -137,13 +132,24 @@ class TezzeretCruelMachinistCardTypeEffect extends AddCardTypeTargetEffect {
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getFirstTarget()); for (UUID targetId : targetPointer.getTargets(game, source)) {
if (permanent == null || !permanent.isFaceDown(game)) { Permanent target = game.getPermanent(targetId);
this.discard(); if (target != null
return false; && target.isFaceDown(game)) {
switch (layer) {
case TypeChangingEffects_4:
target.getSuperType().clear();
target.getCardType().clear();
target.getSubtype(game).clear();
target.addCardType(CardType.ARTIFACT);
target.addCardType(CardType.CREATURE);
break;
} }
return super.apply(game, source); return true;
}
}
return false;
} }
} }
@ -164,11 +170,15 @@ class TezzeretCruelMachinistPowerToughnessEffect extends SetPowerToughnessTarget
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget()); for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
if (permanent == null || !permanent.isFaceDown(game)) { Permanent target = game.getPermanent(targetId);
this.discard(); if (target != null
&& target.isFaceDown(game)) {
target.getPower().setValue(5);
target.getToughness().setValue(5);
return true;
}
}
return false; return false;
} }
return super.apply(game, source);
}
} }

View file

@ -3,36 +3,39 @@ package mage.cards.w;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CopyPermanentEffect;
import mage.abilities.effects.common.SendOptionUsedEventEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.ApplyToPermanent;
import mage.watchers.Watcher;
import java.util.UUID; import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.ContinuousRuleModifyingEffect;
import mage.abilities.effects.EntersBattlefieldEffect;
import mage.abilities.effects.common.DontUntapInControllersUntapStepSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.Target;
import mage.target.targetpointer.FixedTarget;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public final class WallOfStolenIdentity extends CardImpl { public final class WallOfStolenIdentity extends CardImpl {
final static private String rule = "You may have Wall of Stolen Identity enter the battlefield as a copy of any "
+ "creature on the battlefield, except it's a wall in addition to its other types and it has defender. "
+ "When you do, tap the copied creature and it doesn't untap during its "
+ "controller's untap step for as long as you control {this}";
public WallOfStolenIdentity(UUID ownerId, CardSetInfo setInfo) { public WallOfStolenIdentity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
@ -42,9 +45,13 @@ public final class WallOfStolenIdentity extends CardImpl {
this.toughness = new MageInt(0); this.toughness = new MageInt(0);
// You may have Wall of Stolen Identity enter the battlefield as a copy of any creature on the battlefield, except it's a wall in addition to its other types and it has defender. When you do, tap the copied creature and it doesn't untap during its controller's untap step for as long as you control Wall of Stolen Identity. // You may have Wall of Stolen Identity enter the battlefield as a copy of any creature on the battlefield, except it's a wall in addition to its other types and it has defender. When you do, tap the copied creature and it doesn't untap during its controller's untap step for as long as you control Wall of Stolen Identity.
this.addAbility(new EntersBattlefieldAbility( Ability ability = new SimpleStaticAbility(
new WallOfStolenIdentityETBEffect(), true Zone.BATTLEFIELD,
), new WallOfStolenIdentityWatcher()); new EntersBattlefieldEffect(
new WallOfStolenIdentityCopyEffect(),
rule,
true));
this.addAbility(ability);
} }
private WallOfStolenIdentity(final WallOfStolenIdentity card) { private WallOfStolenIdentity(final WallOfStolenIdentity card) {
@ -57,203 +64,103 @@ public final class WallOfStolenIdentity extends CardImpl {
} }
} }
class WallOfStolenIdentityETBEffect extends OneShotEffect { class WallOfStolenIdentityCopyEffect extends OneShotEffect {
private static final ApplyToPermanent applier = new ApplyToPermanent() { private static final String rule2 = "When you do, tap the copied creature and it doesn't untap during its "
+ "controller's untap step for as long as you control {this}.";
@Override public WallOfStolenIdentityCopyEffect() {
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { super(Outcome.Copy);
return this.apply(game, (MageObject) permanent, source, copyToObjectId); staticText = rule2;
} }
@Override public WallOfStolenIdentityCopyEffect(final WallOfStolenIdentityCopyEffect effect) {
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
mageObject.getAbilities().add(DefenderAbility.getInstance());
mageObject.getSubtype(game).add(SubType.WALL);
return true;
}
};
private static final Effect activater = new SendOptionUsedEventEffect();
WallOfStolenIdentityETBEffect() {
super(Outcome.Benefit);
staticText = "as a copy of any creature on the battlefield, except it's a Wall in addition to its other types " +
"and it has defender. When you do, tap the copied creature and it doesn't untap during " +
"its controller's untap step for as long as you control {this}.";
}
private WallOfStolenIdentityETBEffect(final WallOfStolenIdentityETBEffect effect) {
super(effect); super(effect);
} }
@Override
public WallOfStolenIdentityETBEffect copy() {
return new WallOfStolenIdentityETBEffect(this);
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (player == null) { Permanent permanent = game.getPermanent(source.getSourceId());
return false; if (permanent == null) {
permanent = game.getPermanentEntering(source.getSourceId());
} }
TargetPermanent target = new TargetCreaturePermanent(0, 1); final Permanent sourcePermanent = permanent;
if (controller != null
&& sourcePermanent != null) {
Target target = new TargetPermanent(new FilterCreaturePermanent("target creature (you copy from)"));
target.setRequired(true);
if (source instanceof SimpleStaticAbility) {
target = new TargetPermanent(new FilterCreaturePermanent("creature (you copy from)"));
target.setRequired(false);
target.setNotTarget(true); target.setNotTarget(true);
if (!player.choose(outcome, target, source.getSourceId(), game)) { }
if (target.canChoose(source.getSourceId(), source.getControllerId(), game)) {
controller.choose(Outcome.Copy, target, source.getSourceId(), game);
Permanent copyFromPermanent = game.getPermanent(target.getFirstTarget());
if (copyFromPermanent != null) {
game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, new ApplyToPermanent() {
@Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
permanent.getSubtype(game).add(SubType.WALL);
permanent.getAbilities().add(DefenderAbility.getInstance());
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
mageObject.getSubtype(game).add(SubType.WALL);
mageObject.getAbilities().add(DefenderAbility.getInstance());
return true;
}
});
copyFromPermanent.tap(game);
// Incredibly, you can't just add a fixed target to a continuousrulemodifyingeffect, thus the workaround.
ContinuousRuleModifyingEffect effect = new DontUntapInControllersUntapStepSourceEffect();
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
ContinuousEffect effect2 = new GainAbilityTargetEffect(ability, Duration.Custom);
ConditionalContinuousEffect conditionalEffect = new ConditionalContinuousEffect(
effect2, new WallOfStolenIdentityCondition(
source,
source.getControllerId(),
sourcePermanent.getZoneChangeCounter(game)), "");
conditionalEffect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
game.addEffect(conditionalEffect, source);
return true;
}
}
}
return false; return false;
} }
Effect effect = new CopyPermanentEffect(null, applier, true);
effect.setTargetPointer(new FixedTarget(target.getFirstTarget(), game)); @Override
effect.apply(game, source); public WallOfStolenIdentityCopyEffect copy() {
DelayedTriggeredAbility ability = new WallOfStolenIdentityReflexiveTriggeredAbility(); return new WallOfStolenIdentityCopyEffect(this);
ability.getEffects()
.stream()
.forEach(e -> e.setTargetPointer(new FixedTarget(target.getFirstTarget(), game)));
game.addDelayedTriggeredAbility(ability, source);
return activater.apply(game, source);
} }
} }
class WallOfStolenIdentityCondition implements Condition {
class WallOfStolenIdentityReflexiveTriggeredAbility extends DelayedTriggeredAbility { // Checks for when it leaves play or changes control
private final Ability ability;
private final UUID controllerId;
private final int zcc;
WallOfStolenIdentityReflexiveTriggeredAbility() { public WallOfStolenIdentityCondition(Ability ability, UUID controllerId, int zcc) {
super(new TapTargetEffect(), Duration.OneUse, true); this.ability = ability;
this.addEffect(new WallOfStolenIdentityUntapEffect()); this.controllerId = controllerId;
} this.zcc = zcc;
private WallOfStolenIdentityReflexiveTriggeredAbility(final WallOfStolenIdentityReflexiveTriggeredAbility ability) {
super(ability);
} }
@Override @Override
public WallOfStolenIdentityReflexiveTriggeredAbility copy() { public boolean apply(Game game, Ability source) {
return new WallOfStolenIdentityReflexiveTriggeredAbility(this); Permanent permanentSource = game.getPermanent(ability.getSourceId());
} if (permanentSource != null) {
return permanentSource.getZoneChangeCounter(game) == zcc + 1
@Override && permanentSource.getControllerId() == controllerId;
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.OPTION_USED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(this.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "When you do, tap the copied creature and it doesn't untap during " +
"its controller's untap step for as long as you control {this}.";
}
}
class WallOfStolenIdentityUntapEffect extends ContinuousRuleModifyingEffectImpl {
WallOfStolenIdentityUntapEffect() {
super(Duration.Custom, Outcome.Detriment, false, false);
}
private WallOfStolenIdentityUntapEffect(final WallOfStolenIdentityUntapEffect effect) {
super(effect);
}
@Override
public WallOfStolenIdentityUntapEffect copy() {
return new WallOfStolenIdentityUntapEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.UNTAP
|| event.getType() == GameEvent.EventType.ZONE_CHANGE
|| event.getType() == GameEvent.EventType.LOST_CONTROL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
// Source must be on the battlefield (it's neccessary to check here because if as response to the enter
// the battlefield triggered ability the source dies (or will be exiled), then the ZONE_CHANGE or LOST_CONTROL
// event will happen before this effect is applied ever)
MageObject sourceObject = source.getSourceObjectIfItStillExists(game);
if (!(sourceObject instanceof Permanent)
|| !((Permanent) sourceObject).isControlledBy(source.getControllerId())) {
discard();
return false;
}
switch (event.getType()) {
case ZONE_CHANGE:
// end effect if source does a zone move
if (event.getTargetId().equals(source.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
discard();
return false;
}
}
break;
case UNTAP:
// prevent to untap the target creature
if (game.getTurn().getStepType() == PhaseStep.UNTAP
&& event.getTargetId().equals(targetPointer.getFirst(game, source))) {
Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source));
if (targetCreature != null) {
return targetCreature.isControlledBy(game.getActivePlayerId());
} else {
discard();
return false;
}
}
break;
case LOST_CONTROL:
// end effect if source control is changed
if (event.getTargetId().equals(source.getSourceId())) {
discard();
return false;
}
break;
} }
return false; return false;
} }
} }
class WallOfStolenIdentityWatcher extends Watcher {
WallOfStolenIdentityWatcher() {
super(WatcherScope.CARD);
}
private WallOfStolenIdentityWatcher(WallOfStolenIdentityWatcher watcher) {
super(watcher);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.LOST_CONTROL
&& event.getPlayerId().equals(controllerId)
&& event.getTargetId().equals(sourceId)) {
condition = true;
game.replaceEvent(event);
return;
}
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& event.getTargetId().equals(sourceId)) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
condition = true;
game.replaceEvent(event);
}
}
}
@Override
public void reset() {
//don't reset condition each turn - only when this leaves the battlefield
}
@Override
public WallOfStolenIdentityWatcher copy() {
return new WallOfStolenIdentityWatcher(this);
}
}

View file

@ -19,6 +19,7 @@ import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID; import java.util.UUID;
import mage.game.permanent.Permanent;
/** /**
* @author TheElk801 * @author TheElk801
@ -72,7 +73,11 @@ class WatcherForTomorrowEffect extends OneShotEffect {
if (player == null) { if (player == null) {
return false; return false;
} }
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source.getSourceId(), true)); Permanent permanentLeftBattlefield = (Permanent) getValue("permanentLeftBattlefield");
if (permanentLeftBattlefield == null) {
return false;
}
ExileZone zone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), permanentLeftBattlefield.getZoneChangeCounter(game)));
if (zone == null) { if (zone == null) {
return false; return false;
} }

View file

@ -75,7 +75,8 @@ class YaroksFenlurkerEffect extends OneShotEffect {
Map<UUID, Cards> cardsToExile = new HashMap<>(); Map<UUID, Cards> cardsToExile = new HashMap<>();
for (UUID opponentId : game.getOpponents(source.getControllerId())) { for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId); Player opponent = game.getPlayer(opponentId);
if (opponent == null) { if (opponent == null
|| opponent.getHand().isEmpty()) {
continue; continue;
} }
int numberOfCardsToExile = Math.min(1, opponent.getHand().size()); int numberOfCardsToExile = Math.min(1, opponent.getHand().size());

View file

@ -173,6 +173,7 @@ public final class Commander2019Edition extends ExpansionSet {
cards.add(new SetCardInfo("Magmaquake", 148, Rarity.RARE, mage.cards.m.Magmaquake.class)); cards.add(new SetCardInfo("Magmaquake", 148, Rarity.RARE, mage.cards.m.Magmaquake.class));
cards.add(new SetCardInfo("Magus of the Wheel", 149, Rarity.RARE, mage.cards.m.MagusOfTheWheel.class)); cards.add(new SetCardInfo("Magus of the Wheel", 149, Rarity.RARE, mage.cards.m.MagusOfTheWheel.class));
cards.add(new SetCardInfo("Malevolent Whispers", 150, Rarity.UNCOMMON, mage.cards.m.MalevolentWhispers.class)); cards.add(new SetCardInfo("Malevolent Whispers", 150, Rarity.UNCOMMON, mage.cards.m.MalevolentWhispers.class));
cards.add(new SetCardInfo("Mandate of Peace", 4, Rarity.RARE, mage.cards.m.MandateOfPeace.class));
cards.add(new SetCardInfo("Marisi, Breaker of the Coil", 46, Rarity.MYTHIC, mage.cards.m.MarisiBreakerOfTheCoil.class)); cards.add(new SetCardInfo("Marisi, Breaker of the Coil", 46, Rarity.MYTHIC, mage.cards.m.MarisiBreakerOfTheCoil.class));
cards.add(new SetCardInfo("Mass Diminish", 10, Rarity.RARE, mage.cards.m.MassDiminish.class)); cards.add(new SetCardInfo("Mass Diminish", 10, Rarity.RARE, mage.cards.m.MassDiminish.class));
cards.add(new SetCardInfo("Memorial to Folly", 259, Rarity.UNCOMMON, mage.cards.m.MemorialToFolly.class)); cards.add(new SetCardInfo("Memorial to Folly", 259, Rarity.UNCOMMON, mage.cards.m.MemorialToFolly.class));

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-tests</artifactId> <artifactId>mage-tests</artifactId>

View file

@ -1,9 +1,8 @@
package org.mage.test.cards.enchantments; package org.mage.test.cards.enchantments;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import org.junit.Test; import org.junit.Ignore;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
/** /**
@ -26,11 +25,14 @@ public class SkullclampTest extends CardTestPlayerBase {
* 704.5n.) * 704.5n.)
* *
*/ */
@Test
// This test does not work, but the example works in the game fine.
@Ignore
public void testPerniciousDeed() { public void testPerniciousDeed() {
// Equipped creature gets +1/-1. // Equipped creature gets +1/-1.
// Whenever equipped creature dies, draw two cards. // Whenever equipped creature dies, draw two cards.
// Equip {1} // Equip {1}
addCard(Zone.LIBRARY, playerA, "Memnite", 2);
addCard(Zone.BATTLEFIELD, playerA, "Skullclamp", 1); addCard(Zone.BATTLEFIELD, playerA, "Skullclamp", 1);
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1); addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1); addCard(Zone.BATTLEFIELD, playerA, "Pillarfield Ox", 1);

View file

@ -0,0 +1,37 @@
package org.mage.test.cards.mana;
import mage.constants.ManaType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author apetresc
*/
public class LeylineOfAbundanceTest extends CardTestPlayerBase {
/**
* Creatures an opponent controls shouldn't trigger Leyline's ability to
* generate additional mana.
*/
@Test
public void testOpponentsManaCreatures() {
addCard(Zone.BATTLEFIELD, playerA, "Upwelling", 1);
addCard(Zone.BATTLEFIELD, playerA, "Leyline of Abundance");
addCard(Zone.BATTLEFIELD, playerB, "Llanowar Elves");
addCard(Zone.BATTLEFIELD, playerB, "Leyline of Abundance");
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerB, "{T}: Add {G}");
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
execute();
assertManaPool(playerB, ManaType.GREEN, 2);
assertManaPool(playerA, ManaType.GREEN, 0);
}
}

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage-verify</artifactId> <artifactId>mage-verify</artifactId>
@ -49,7 +49,7 @@
<dependency> <dependency>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-client</artifactId> <artifactId>mage-client</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</dependency> </dependency>
</dependencies> </dependencies>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.mage</groupId> <groupId>org.mage</groupId>
<artifactId>mage-root</artifactId> <artifactId>mage-root</artifactId>
<version>1.4.39</version> <version>1.4.40</version>
</parent> </parent>
<artifactId>mage</artifactId> <artifactId>mage</artifactId>

View file

@ -2,6 +2,7 @@ package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.cards.Card;
import mage.constants.SetTargetPointer; import mage.constants.SetTargetPointer;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
@ -33,7 +34,8 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
this(effect, attachedDescription, optional, diesRuleText, SetTargetPointer.NONE); this(effect, attachedDescription, optional, diesRuleText, SetTargetPointer.NONE);
} }
public DiesAttachedTriggeredAbility(Effect effect, String attachedDescription, boolean optional, boolean diesRuleText, SetTargetPointer setTargetPointer) { public DiesAttachedTriggeredAbility(Effect effect, String attachedDescription, boolean optional,
boolean diesRuleText, SetTargetPointer setTargetPointer) {
super(Zone.ALL, effect, optional); // because the trigger only triggers if the object was attached, it doesn't matter where the Attachment was moved to (e.g. by replacement effect) after the trigger triggered, so Zone.all super(Zone.ALL, effect, optional); // because the trigger only triggers if the object was attached, it doesn't matter where the Attachment was moved to (e.g. by replacement effect) after the trigger triggered, so Zone.all
this.attachedDescription = attachedDescription; this.attachedDescription = attachedDescription;
this.diesRuleText = diesRuleText; this.diesRuleText = diesRuleText;
@ -62,18 +64,27 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
if (((ZoneChangeEvent) event).isDiesEvent()) { if (((ZoneChangeEvent) event).isDiesEvent()) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event; ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
boolean triggered = false; boolean triggered = false;
if (zEvent.getTarget() != null && zEvent.getTarget().getAttachments() != null && zEvent.getTarget().getAttachments().contains(this.getSourceId())) { if (zEvent.getTarget() != null
&& zEvent.getTarget().getAttachments() != null
&& zEvent.getTarget().getAttachments().contains(this.getSourceId())) {
triggered = true; triggered = true;
} else { } else {
// If both (attachment and attached went to graveyard at the same time, the attachemnets can be already removed from the attached object.) // If the attachment and attachedTo went to graveyard at the same time, the trigger applies.
// So check here with the LKI of the enchantment // If the attachment is removed beforehand, the trigger fails.
// IE: A player cast Planar Clensing. The attachment is Disenchanted in reponse
// and successfully removed from the attachedTo. The trigger fails.
Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId()); Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId());
Card attachmentCard = game.getCard(getSourceId());
if (attachment != null if (attachment != null
&& zEvent.getTargetId() != null && attachment.getAttachedTo() != null && zEvent.getTargetId() != null
&& attachment.getAttachedTo() != null
&& zEvent.getTargetId().equals(attachment.getAttachedTo())) { && zEvent.getTargetId().equals(attachment.getAttachedTo())) {
Permanent attachedTo = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo()); Permanent attachedTo = game.getPermanentOrLKIBattlefield(attachment.getAttachedTo());
if (attachedTo != null if (attachedTo != null
&& attachment.getAttachedToZoneChangeCounter() == attachedTo.getZoneChangeCounter(game)) { // zoneChangeCounter is stored in Permanent && game.getState().getZone(attachedTo.getId()) == (Zone.GRAVEYARD) // Demonic Vigor
&& attachmentCard != null
&& attachment.getAttachedToZoneChangeCounter() == attachedTo.getZoneChangeCounter(game)
&& attachment.getZoneChangeCounter(game) == attachmentCard.getZoneChangeCounter(game)) {
triggered = true; triggered = true;
} }
} }
@ -82,10 +93,13 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
for (Effect effect : getEffects()) { for (Effect effect : getEffects()) {
if (zEvent.getTarget() != null) { if (zEvent.getTarget() != null) {
effect.setValue("attachedTo", zEvent.getTarget()); effect.setValue("attachedTo", zEvent.getTarget());
effect.setValue("zcc", zEvent.getTarget().getZoneChangeCounter(game) + 1); // zone change info from battlefield
if (setTargetPointer == SetTargetPointer.ATTACHED_TO_CONTROLLER) { if (setTargetPointer == SetTargetPointer.ATTACHED_TO_CONTROLLER) {
Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId()); Permanent attachment = game.getPermanentOrLKIBattlefield(getSourceId());
if (attachment != null && attachment.getAttachedTo() != null) { if (attachment != null
Permanent attachedTo = (Permanent) game.getLastKnownInformation(attachment.getAttachedTo(), Zone.BATTLEFIELD, attachment.getAttachedToZoneChangeCounter()); && attachment.getAttachedTo() != null) {
Permanent attachedTo = (Permanent) game.getLastKnownInformation(attachment.getAttachedTo(),
Zone.BATTLEFIELD, attachment.getAttachedToZoneChangeCounter());
if (attachedTo != null) { if (attachedTo != null) {
effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId())); effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId()));
} }
@ -95,7 +109,6 @@ public class DiesAttachedTriggeredAbility extends TriggeredAbilityImpl {
} }
return true; return true;
} }
} }
return false; return false;
} }

View file

@ -1,4 +1,3 @@
package mage.abilities.common; package mage.abilities.common;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;

View file

@ -9,6 +9,7 @@ import mage.cards.Card;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.ExileZone; import mage.game.ExileZone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
@ -34,8 +35,14 @@ public class HideawayPlayEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); ExileZone zone = null;
if (zone == null || zone.isEmpty()) { Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (permanent != null) {
zone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), permanent.getZoneChangeCounter(game)));
}
if (zone == null
|| zone.isEmpty()) {
return true; return true;
} }
Card card = zone.getCards(game).iterator().next(); Card card = zone.getCards(game).iterator().next();

View file

@ -1,5 +1,3 @@
package mage.abilities.effects.common; package mage.abilities.effects.common;
import mage.constants.Outcome; import mage.constants.Outcome;
@ -34,8 +32,9 @@ public class ReturnToHandAttachedEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Object object = getValue("attachedTo"); Object object = getValue("attachedTo");
if (object instanceof Permanent) { if (object instanceof Permanent) {
Card card = game.getCard(((Permanent)object).getId()); Card card = game.getCard(((Permanent) object).getId());
if (card != null) { if (card != null
&& getValue("zcc").equals(game.getState().getZoneChangeCounter(card.getId()))) { // Necrogenesis, etc.
if (card.moveToZone(Zone.HAND, source.getSourceId(), game, false)) { if (card.moveToZone(Zone.HAND, source.getSourceId(), game, false)) {
return true; return true;
} }

View file

@ -83,6 +83,7 @@ public class BecomesCreatureTargetEffect extends ContinuousEffectImpl {
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
if (loseAllAbilities) { if (loseAllAbilities) {
permanent.getSubtype(game).retainAll(SubType.getLandTypes()); permanent.getSubtype(game).retainAll(SubType.getLandTypes());
permanent.getCardType().clear(); // remove all CardTypes
permanent.getSubtype(game).addAll(token.getSubtype(game)); permanent.getSubtype(game).addAll(token.getSubtype(game));
} else { } else {
for (SubType t : token.getSubtype(game)) { for (SubType t : token.getSubtype(game)) {

View file

@ -1,4 +1,3 @@
package mage.abilities.keyword; package mage.abilities.keyword;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -16,8 +15,9 @@ import mage.game.events.GameEvent.EventType;
import mage.players.Player; import mage.players.Player;
/** /**
* If you would draw a card, instead you may put exactly X cards from the top of your library into your graveyard. If * If you would draw a card, instead you may put exactly X cards from the top of
* you do, return this card from your graveyard to your hand. Otherwise, draw a card. * your library into your graveyard. If you do, return this card from your
* graveyard to your hand. Otherwise, draw a card.
* *
* @author North * @author North
*/ */
@ -42,7 +42,7 @@ class DredgeEffect extends ReplacementEffectImpl {
private final int amount; private final int amount;
public DredgeEffect(int value) { public DredgeEffect(int value) {
super(Duration.WhileInGraveyard, Outcome.ReturnToHand); super(Duration.WhileInGraveyard, Outcome.AIDontUseIt);
this.amount = value; this.amount = value;
this.staticText = new StringBuilder("Dredge ").append(Integer.toString(value)).append(" <i>(If you would draw a card, instead you may put exactly ").append(value).append(" card(s) from the top of your library into your graveyard. If you do, return this card from your graveyard to your hand. Otherwise, draw a card.)</i>").toString(); this.staticText = new StringBuilder("Dredge ").append(Integer.toString(value)).append(" <i>(If you would draw a card, instead you may put exactly ").append(value).append(" card(s) from the top of your library into your graveyard. If you do, return this card from your graveyard to your hand. Otherwise, draw a card.)</i>").toString();
} }
@ -68,17 +68,18 @@ class DredgeEffect extends ReplacementEffectImpl {
if (sourceCard == null) { if (sourceCard == null) {
return false; return false;
} }
Player player = game.getPlayer(source.getControllerId()); Player owner = game.getPlayer(game.getCard(source.getSourceId()).getOwnerId());
if (player != null && player.getLibrary().size() >= amount if (owner != null
&& player.chooseUse(outcome, new StringBuilder("Dredge ").append(sourceCard.getLogName()). && owner.getLibrary().size() >= amount
&& owner.chooseUse(outcome, new StringBuilder("Dredge ").append(sourceCard.getLogName()).
append("? (").append(amount).append(" cards go from top of library to graveyard)").toString(), source, game)) { append("? (").append(amount).append(" cards go from top of library to graveyard)").toString(), source, game)) {
if (!game.isSimulation()) { if (!game.isSimulation()) {
game.informPlayers(new StringBuilder(player.getLogName()).append(" dredges ").append(sourceCard.getLogName()).toString()); game.informPlayers(new StringBuilder(owner.getLogName()).append(" dredges ").append(sourceCard.getLogName()).toString());
} }
Cards cardsToGrave = new CardsImpl(); Cards cardsToGrave = new CardsImpl();
cardsToGrave.addAll(player.getLibrary().getTopCards(game, amount)); cardsToGrave.addAll(owner.getLibrary().getTopCards(game, amount));
player.moveCards(cardsToGrave, Zone.GRAVEYARD, source, game); owner.moveCards(cardsToGrave, Zone.GRAVEYARD, source, game);
player.moveCards(sourceCard, Zone.HAND, source, game); owner.moveCards(sourceCard, Zone.HAND, source, game);
return true; return true;
} }
return false; return false;
@ -89,13 +90,11 @@ class DredgeEffect extends ReplacementEffectImpl {
return event.getType() == EventType.DRAW_CARD; return event.getType() == EventType.DRAW_CARD;
} }
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getPlayerId().equals(source.getControllerId())) { Player owner = game.getPlayer(game.getCard(source.getSourceId()).getOwnerId());
Player controller = game.getPlayer(source.getControllerId()); return (owner != null
return controller != null && controller.getLibrary().size() >= amount; && event.getPlayerId().equals(owner.getId())
} && owner.getLibrary().size() >= amount);
return false;
} }
} }

View file

@ -1,4 +1,3 @@
package mage.abilities.keyword; package mage.abilities.keyword;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -105,7 +104,8 @@ class HideawayExileEffect extends OneShotEffect {
Card card = cards.get(target1.getFirstTarget(), game); Card card = cards.get(target1.getFirstTarget(), game);
if (card != null) { if (card != null) {
cards.remove(card); cards.remove(card);
controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
controller.moveCardToExileWithInfo(card, exileId,
"Hideaway (" + hideawaySource.getIdName() + ')', source.getSourceId(), game, Zone.LIBRARY, false); "Hideaway (" + hideawaySource.getIdName() + ')', source.getSourceId(), game, Zone.LIBRARY, false);
card.setFaceDown(true, game); card.setFaceDown(true, game);
} }

View file

@ -186,6 +186,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
spell.setFaceDown(true, game); // so only the back is visible spell.setFaceDown(true, game); // so only the back is visible
if (alternateCosts.canPay(ability, sourceId, controllerId, game)) { if (alternateCosts.canPay(ability, sourceId, controllerId, game)) {
if (player.chooseUse(Outcome.Benefit, "Cast this card as a 2/2 face-down creature for " + getCosts().getText() + " ?", ability, game)) { if (player.chooseUse(Outcome.Benefit, "Cast this card as a 2/2 face-down creature for " + getCosts().getText() + " ?", ability, game)) {
game.getState().setValue("MorphAbility" + ability.getSourceId(), "activated"); // Gift of Doom
activateMorph(game); activateMorph(game);
// change mana costs // change mana costs
ability.getManaCostsToPay().clear(); ability.getManaCostsToPay().clear();

View file

@ -35,7 +35,7 @@ public enum CardRepository {
// raise this if db structure was changed // raise this if db structure was changed
private static final long CARD_DB_VERSION = 51; private static final long CARD_DB_VERSION = 51;
// raise this if new cards were added to the server // raise this if new cards were added to the server
private static final long CARD_CONTENT_VERSION = 226; private static final long CARD_CONTENT_VERSION = 227;
private Dao<CardInfo, Object> cardDao; private Dao<CardInfo, Object> cardDao;
private Set<String> classNames; private Set<String> classNames;
private RepositoryEventSource eventSource = new RepositoryEventSource(); private RepositoryEventSource eventSource = new RepositoryEventSource();

View file

@ -1,4 +1,3 @@
package mage.game.command.emblems; package mage.game.command.emblems;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -15,13 +14,12 @@ import mage.game.command.Emblem;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class GideonOfTheTrialsEmblem extends Emblem { public final class GideonOfTheTrialsEmblem extends Emblem {
public GideonOfTheTrialsEmblem() { public GideonOfTheTrialsEmblem() {
this.setName("Emblem - Gideon"); this.setName("Emblem Gideon");
Ability ability = new SimpleStaticAbility(Zone.COMMAND, new GideonOfTheTrialsCantLoseEffect()); Ability ability = new SimpleStaticAbility(Zone.COMMAND, new GideonOfTheTrialsCantLoseEffect());
this.getAbilities().add(ability); this.getAbilities().add(ability);
} }
@ -53,9 +51,7 @@ class GideonOfTheTrialsCantLoseEffect extends ContinuousRuleModifyingEffectImpl
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
if ((event.getType() == GameEvent.EventType.WINS && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) if ((event.getType() == GameEvent.EventType.WINS && game.getOpponents(source.getControllerId()).contains(event.getPlayerId()))
|| (event.getType() == GameEvent.EventType.LOSES && event.getPlayerId().equals(source.getControllerId()))) { || (event.getType() == GameEvent.EventType.LOSES && event.getPlayerId().equals(source.getControllerId()))) {
if (game.getBattlefield().contains(filter, source.getControllerId(), 1, game)) { return game.getBattlefield().contains(filter, source.getControllerId(), 1, game);
return true;
}
} }
return false; return false;
} }

View file

@ -24,6 +24,10 @@ public final class AkoumStonewakerElementalToken extends TokenImpl {
this.addAbility(HasteAbility.getInstance()); this.addAbility(HasteAbility.getInstance());
availableImageSetCodes.addAll(Arrays.asList("BFZ", "MH1")); availableImageSetCodes.addAll(Arrays.asList("BFZ", "MH1"));
if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("BFZ")) {
setTokenType(2);
}
if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("MH1")) { if (getOriginalExpansionSetCode() != null && getOriginalExpansionSetCode().equals("MH1")) {
setTokenType(2); setTokenType(2);
} }

View file

@ -1,15 +1,14 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.MageInt; import mage.MageInt;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class BeastToken extends TokenImpl { public final class BeastToken extends TokenImpl {
@ -17,7 +16,7 @@ public final class BeastToken extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>(); static final private List<String> tokenImageSets = new ArrayList<>();
static { static {
tokenImageSets.addAll(Arrays.asList("C14", "LRW", "M15", "M14", "DDL", "M13", "M12", "DD3GVL", "NPH", "M11", "M10", "EVE", "MM3", "CMA", "E01")); tokenImageSets.addAll(Arrays.asList("C14", "LRW", "M15", "M14", "DDL", "M13", "M12", "DD3GVL", "NPH", "M11", "M10", "EVE", "MM3", "CMA", "E01", "C19"));
} }
public BeastToken() { public BeastToken() {

View file

@ -1,15 +1,14 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.MageInt; import mage.MageInt;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
*
* @author LoneFox * @author LoneFox
*/ */
public final class BeastToken2 extends TokenImpl { public final class BeastToken2 extends TokenImpl {
@ -17,7 +16,7 @@ public final class BeastToken2 extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>(); static final private List<String> tokenImageSets = new ArrayList<>();
static { static {
tokenImageSets.addAll(Arrays.asList("ZEN", "C14", "DDD", "C15", "DD3GVL", "MM3", "CMA", "E01")); tokenImageSets.addAll(Arrays.asList("ZEN", "C14", "DDD", "C15", "DD3GVL", "MM3", "CMA", "E01", "C19"));
} }
public BeastToken2() { public BeastToken2() {

View file

@ -17,7 +17,7 @@ public final class CentaurToken extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>(); static final private List<String> tokenImageSets = new ArrayList<>();
static { static {
tokenImageSets.addAll(Arrays.asList("RTR", "MM3", "RNA")); tokenImageSets.addAll(Arrays.asList("RTR", "MM3", "RNA", "C19"));
} }
public CentaurToken() { public CentaurToken() {

View file

@ -1,16 +1,15 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.MageInt; import mage.MageInt;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
*
* @author LoneFox * @author LoneFox
*/ */
public final class DragonToken2 extends TokenImpl { public final class DragonToken2 extends TokenImpl {
@ -18,11 +17,11 @@ public final class DragonToken2 extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>(); static final private List<String> tokenImageSets = new ArrayList<>();
static { static {
tokenImageSets.addAll(Arrays.asList("WWK", "10E", "BFZ", "C15", "CN2", "CMA")); tokenImageSets.addAll(Arrays.asList("WWK", "10E", "BFZ", "C15", "CN2", "CMA", "C19"));
} }
public DragonToken2() { public DragonToken2() {
this((String)null); this((String) null);
} }
public DragonToken2(String setCode) { public DragonToken2(String setCode) {

View file

@ -18,7 +18,7 @@ public final class HumanToken extends TokenImpl {
subtype.add(SubType.HUMAN); subtype.add(SubType.HUMAN);
power = new MageInt(1); power = new MageInt(1);
toughness = new MageInt(1); toughness = new MageInt(1);
availableImageSetCodes.addAll(Arrays.asList("DKA", "AVR", "FNMP", "RNA", "ELD")); availableImageSetCodes.addAll(Arrays.asList("DKA", "AVR", "FNMP", "RNA", "ELD", "C19"));
} }
public HumanToken(final HumanToken token) { public HumanToken(final HumanToken token) {

View file

@ -1,19 +1,17 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.MageInt;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class OmnathElementalToken extends TokenImpl { public final class OmnathElementalToken extends TokenImpl {
public OmnathElementalToken() { public OmnathElementalToken() {
super("Elemental", "5/5 red and green Elemental creature token"); super("Elemental", "5/5 red and green Elemental creature token");
setTokenType(2); setTokenType(1);
setOriginalExpansionSetCode("BFZ"); setOriginalExpansionSetCode("BFZ");
cardType.add(CardType.CREATURE); cardType.add(CardType.CREATURE);
subtype.add(SubType.ELEMENTAL); subtype.add(SubType.ELEMENTAL);
@ -23,6 +21,7 @@ public final class OmnathElementalToken extends TokenImpl {
power = new MageInt(5); power = new MageInt(5);
toughness = new MageInt(5); toughness = new MageInt(5);
} }
public OmnathElementalToken(final OmnathElementalToken token) { public OmnathElementalToken(final OmnathElementalToken token) {
super(token); super(token);
} }

View file

@ -21,7 +21,7 @@ public final class RhinoToken extends TokenImpl {
toughness = new MageInt(4); toughness = new MageInt(4);
addAbility(TrampleAbility.getInstance()); addAbility(TrampleAbility.getInstance());
availableImageSetCodes.addAll(Arrays.asList("DGM", "RTR", "MH1")); availableImageSetCodes.addAll(Arrays.asList("DGM", "RTR", "MH1", "C19"));
} }
public RhinoToken(final RhinoToken token) { public RhinoToken(final RhinoToken token) {

View file

@ -1,17 +1,15 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.MageInt; import mage.MageInt;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class SaprolingToken extends TokenImpl { public final class SaprolingToken extends TokenImpl {
@ -39,7 +37,8 @@ public final class SaprolingToken extends TokenImpl {
"VMA", // 2 different token, one with DIFFERENT stats, "Saproling Burst" create different token, see https://scryfall.com/card/tvma/12 "VMA", // 2 different token, one with DIFFERENT stats, "Saproling Burst" create different token, see https://scryfall.com/card/tvma/12
"E02", "E02",
"RIX", "RIX",
"DOM" // 3 different token images "DOM", // 3 different token images
"C19"
)); ));
} }

View file

@ -1,12 +1,10 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.MageInt;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class SeedGuardianToken extends TokenImpl { public final class SeedGuardianToken extends TokenImpl {
@ -14,9 +12,10 @@ public final class SeedGuardianToken extends TokenImpl {
public SeedGuardianToken() { public SeedGuardianToken() {
this(1); this(1);
} }
public SeedGuardianToken(int xValue) { public SeedGuardianToken(int xValue) {
super("Elemental", "X/X green Elemental creature token"); super("Elemental", "X/X green Elemental creature token");
setTokenType(2); setTokenType(1);
setOriginalExpansionSetCode("OGW"); setOriginalExpansionSetCode("OGW");
cardType.add(CardType.CREATURE); cardType.add(CardType.CREATURE);
color.setGreen(true); color.setGreen(true);

View file

@ -1,16 +1,14 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import mage.MageInt; import mage.MageInt;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class SnakeToken extends TokenImpl { public final class SnakeToken extends TokenImpl {
@ -18,11 +16,11 @@ public final class SnakeToken extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>(); static final private List<String> tokenImageSets = new ArrayList<>();
static { static {
tokenImageSets.addAll(Arrays.asList("ZEN", "KTK", "MM2", "C15")); tokenImageSets.addAll(Arrays.asList("ZEN", "KTK", "MM2", "C15", "C19"));
} }
public SnakeToken() { public SnakeToken() {
this((String)null); this((String) null);
} }
public SnakeToken(String setCode) { public SnakeToken(String setCode) {

View file

@ -1,12 +1,12 @@
package mage.game.permanent.token; package mage.game.permanent.token;
import mage.MageInt;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import mage.MageInt;
import mage.constants.CardType;
import mage.constants.SubType;
/** /**
* @author Loki * @author Loki
@ -16,7 +16,7 @@ public final class SpiritToken extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>(); static final private List<String> tokenImageSets = new ArrayList<>();
static { static {
tokenImageSets.addAll(Arrays.asList("CHK", "EMA", "C16")); tokenImageSets.addAll(Arrays.asList("CHK", "EMA", "C16", "C19"));
} }
public SpiritToken() { public SpiritToken() {

View file

@ -21,7 +21,7 @@ public final class TreasureToken extends TokenImpl {
static final private List<String> tokenImageSets = new ArrayList<>(); static final private List<String> tokenImageSets = new ArrayList<>();
static { static {
tokenImageSets.addAll(Arrays.asList("XLN", "RNA", "M20")); tokenImageSets.addAll(Arrays.asList("XLN", "RNA", "M20", "C19"));
} }
public TreasureToken() { public TreasureToken() {

View file

@ -18,7 +18,7 @@ public final class ZombieToken extends TokenImpl {
static { static {
tokenImageSets.addAll(Arrays.asList("10E", "M10", "M11", "M12", "M13", "M14", "M15", "MBS", "ALA", "ISD", "C14", "C15", "C16", "C17", "CNS", tokenImageSets.addAll(Arrays.asList("10E", "M10", "M11", "M12", "M13", "M14", "M15", "MBS", "ALA", "ISD", "C14", "C15", "C16", "C17", "CNS",
"MMA", "BNG", "KTK", "DTK", "ORI", "OGW", "SOI", "EMN", "EMA", "MM3", "AKH", "CMA", "E01", "RNA", "WAR", "MH1", "M20")); "MMA", "BNG", "KTK", "DTK", "ORI", "OGW", "SOI", "EMN", "EMA", "MM3", "AKH", "CMA", "E01", "RNA", "WAR", "MH1", "M20", "C19"));
} }
public ZombieToken() { public ZombieToken() {
@ -34,6 +34,7 @@ public final class ZombieToken extends TokenImpl {
@Override @Override
public void setExpansionSetCodeForImage(String code) { public void setExpansionSetCodeForImage(String code) {
super.setExpansionSetCodeForImage(code); super.setExpansionSetCodeForImage(code);
if (getOriginalExpansionSetCode().equals("ISD")) { if (getOriginalExpansionSetCode().equals("ISD")) {
this.setTokenType(RandomUtil.nextInt(3) + 1); this.setTokenType(RandomUtil.nextInt(3) + 1);
} }
@ -43,6 +44,9 @@ public final class ZombieToken extends TokenImpl {
if (getOriginalExpansionSetCode().equals("EMN")) { if (getOriginalExpansionSetCode().equals("EMN")) {
this.setTokenType(RandomUtil.nextInt(4) + 1); this.setTokenType(RandomUtil.nextInt(4) + 1);
} }
if (getOriginalExpansionSetCode().equals("C19")) {
this.setTokenType(RandomUtil.nextInt(2) + 1);
}
} }
public ZombieToken(final ZombieToken token) { public ZombieToken(final ZombieToken token) {

Some files were not shown because too many files have changed in this diff Show more