Merge pull request 'master' (#24) from External/mage:master into master

Reviewed-on: #24
This commit is contained in:
Failure 2025-04-07 13:17:51 -07:00
commit bbdd326d3a
148 changed files with 4758 additions and 1072 deletions

View file

@ -204,7 +204,7 @@ public enum GrabbagImageSource implements CardImageSource {
singleLinks.put("SWS/Hazard Trooper", "ZOutamG.jpeg"); singleLinks.put("SWS/Hazard Trooper", "ZOutamG.jpeg");
singleLinks.put("SWS/Head Hunting", "7OT1bGZ.jpeg"); singleLinks.put("SWS/Head Hunting", "7OT1bGZ.jpeg");
singleLinks.put("SWS/Heavy Trooper", "HhZWs2N.jpeg"); singleLinks.put("SWS/Heavy Trooper", "HhZWs2N.jpeg");
singleLinks.put("SWS/Hot Pursuit", "ih1GT5Z.jpeg"); singleLinks.put("SWS/Hot Pursuit (Star Wars)", "ih1GT5Z.jpeg");
singleLinks.put("SWS/Hungry Dragonsnake", "23v7RTm.jpeg"); singleLinks.put("SWS/Hungry Dragonsnake", "23v7RTm.jpeg");
singleLinks.put("SWS/Hunt to Extinction", "3eJyfzZ.jpeg"); singleLinks.put("SWS/Hunt to Extinction", "3eJyfzZ.jpeg");
singleLinks.put("SWS/Hutt Crime Lord", "NAzK7Hp.jpeg"); singleLinks.put("SWS/Hutt Crime Lord", "NAzK7Hp.jpeg");

View file

@ -439,7 +439,7 @@ public class ScryfallImageSupportCards {
add("ELD"); // Throne of Eldraine add("ELD"); // Throne of Eldraine
//add("PTG"); // Ponies: The Galloping //add("PTG"); // Ponies: The Galloping
add("CMB1"); // Mystery Booster Playtest Cards 2019 add("CMB1"); // Mystery Booster Playtest Cards 2019
//add("MB1"); // Mystery Booster add("MB1"); // Mystery Booster
add("GN2"); // Game Night 2019 add("GN2"); // Game Night 2019
add("HA1"); // Historic Anthology 1 add("HA1"); // Historic Anthology 1
//add("HHO"); // Happy Holidays //add("HHO"); // Happy Holidays
@ -534,7 +534,7 @@ public class ScryfallImageSupportCards {
add("ONE"); // Phyrexia: All Will Be One add("ONE"); // Phyrexia: All Will Be One
add("ONC"); // Phyrexia: All Will Be One Commander add("ONC"); // Phyrexia: All Will Be One Commander
add("PL23"); // Year of the Rabbit 2023 add("PL23"); // Year of the Rabbit 2023
add("DA1"); // Unknown Event add("UNK"); // Unknown Event
add("SIS"); // Shadows of the Past add("SIS"); // Shadows of the Past
add("SIR"); // Shadows over Innistrad Remastered add("SIR"); // Shadows over Innistrad Remastered
add("SLP"); // Secret Lair Showdown add("SLP"); // Secret Lair Showdown
@ -683,8 +683,16 @@ public class ScryfallImageSupportCards {
// CALC - custom alchemy version of cards. // CALC - custom alchemy version of cards.
put("CALC/C-Pillar of the Paruns", "https://api.scryfall.com/cards/dis/176/"); put("CALC/C-Pillar of the Paruns", "https://api.scryfall.com/cards/dis/176/");
// MB1
put("MB1/Goblin Trenches", "https://api.scryfall.com/cards/plst/EMA-203/");
put("MB1/Prophetic Bolt", "https://api.scryfall.com/cards/plst/C15-231/");
// LTR - 0 number for tokens only // LTR - 0 number for tokens only
put("LTR/The One Ring/001", "https://api.scryfall.com/cards/ltr/0/"); // Scryfall has a bug, for some reason this link doesn't work with ?format=image even though it works with ?format=json
// and ?format=text. Base url fails because language is qya and not en and alternate url fails because of this bug
// TODO: This should be reverted when Scryfall fixes the bug
// put("LTR/The One Ring/001", "https://api.scryfall.com/cards/ltr/0/");
put("LTR/The One Ring/001", "https://api.scryfall.com/cards/ltr/0/qya?format=image");
// REX - double faced lands (xmage uses two diff lands for it) // REX - double faced lands (xmage uses two diff lands for it)
put("REX/Command Tower/26b", "https://api.scryfall.com/cards/rex/26/en?format=image&face=back"); put("REX/Command Tower/26b", "https://api.scryfall.com/cards/rex/26/en?format=image&face=back");

View file

@ -39,7 +39,8 @@ public class ScryfallImageSupportTokens {
putAll(TokenRepository.instance.prepareScryfallDownloadList()); putAll(TokenRepository.instance.prepareScryfallDownloadList());
// RIX // RIX
put("RIX/City's Blessing", "https://api.scryfall.com/cards/trix/6/en?format=image"); // TODO: missing from tokens data // TODO: this should be readded when condition tokens are implemented
// put("RIX/City's Blessing", "https://api.scryfall.com/cards/trix/6/en?format=image");
put("RIX/Elemental/1", "https://api.scryfall.com/cards/trix/1/en?format=image"); put("RIX/Elemental/1", "https://api.scryfall.com/cards/trix/1/en?format=image");
put("RIX/Elemental/2", "https://api.scryfall.com/cards/trix/2/en?format=image"); put("RIX/Elemental/2", "https://api.scryfall.com/cards/trix/2/en?format=image");
put("RIX/Golem", "https://api.scryfall.com/cards/trix/4/en?format=image"); put("RIX/Golem", "https://api.scryfall.com/cards/trix/4/en?format=image");
@ -117,22 +118,6 @@ public class ScryfallImageSupportTokens {
put("AKH/Warrior", "https://api.scryfall.com/cards/takh/17/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/Wurm", "https://api.scryfall.com/cards/takh/24/en?format=image");
put("AKH/Zombie", "https://api.scryfall.com/cards/takh/20/en?format=image"); put("AKH/Zombie", "https://api.scryfall.com/cards/takh/20/en?format=image");
// AKH - embalm ability (token from card)
put("AKH/Angel of Sanctions", "https://api.scryfall.com/cards/takh/1/en?format=image");
put("AKH/Anointer Priest", "https://api.scryfall.com/cards/takh/2/en?format=image");
put("AKH/Aven Initiate", "https://api.scryfall.com/cards/takh/3/en?format=image");
put("AKH/Aven Wind Guide", "https://api.scryfall.com/cards/takh/4/en?format=image");
put("AKH/Glyph Keeper", "https://api.scryfall.com/cards/takh/5/en?format=image");
put("AKH/Heart-Piercer Manticore", "https://api.scryfall.com/cards/takh/6/en?format=image");
put("AKH/Honored Hydra", "https://api.scryfall.com/cards/takh/7/en?format=image");
put("AKH/Labyrinth Guardian", "https://api.scryfall.com/cards/takh/8/en?format=image");
put("AKH/Oketra's Attendant", "https://api.scryfall.com/cards/takh/9/en?format=image");
put("AKH/Sacred Cat", "https://api.scryfall.com/cards/takh/10/en?format=image");
put("AKH/Tah-Crop Skirmisher", "https://api.scryfall.com/cards/takh/11/en?format=image");
put("AKH/Temmet, Vizier of Naktamun", "https://api.scryfall.com/cards/takh/12/en?format=image");
put("AKH/Trueheart Duelist", "https://api.scryfall.com/cards/takh/13/en?format=image");
put("AKH/Unwavering Initiate", "https://api.scryfall.com/cards/takh/14/en?format=image");
put("AKH/Vizier of Many Faces", "https://api.scryfall.com/cards/takh/15/en?format=image");
// AER // AER
put("AER/Etherium Cell", "https://api.scryfall.com/cards/taer/3/en?format=image"); put("AER/Etherium Cell", "https://api.scryfall.com/cards/taer/3/en?format=image");
@ -501,7 +486,7 @@ public class ScryfallImageSupportTokens {
put("ZNC/Elemental/1", "https://api.scryfall.com/cards/tznc/10/en?format=image"); // 5/5 put("ZNC/Elemental/1", "https://api.scryfall.com/cards/tznc/10/en?format=image"); // 5/5
put("ZNC/Elemental/2", "https://api.scryfall.com/cards/tznc/8/en?format=image"); // 2/2 put("ZNC/Elemental/2", "https://api.scryfall.com/cards/tznc/8/en?format=image"); // 2/2
put("ZNC/Faerie Rogue", "https://api.scryfall.com/cards/tznc/3/en?format=image"); put("ZNC/Faerie Rogue", "https://api.scryfall.com/cards/tznc/3/en?format=image");
put("ZNC/Germ", "https://api.scryfall.com/cards/tznc/4/en?format=image"); // must be in chest or antology put("ZNC/Phyrexian Germ", "https://api.scryfall.com/cards/tznc/4/en?format=image"); // must be in chest or antology
put("ZNC/Goblin Rogue", "https://api.scryfall.com/cards/tznc/5/en?format=image"); put("ZNC/Goblin Rogue", "https://api.scryfall.com/cards/tznc/5/en?format=image");
put("ZNC/Kor Ally", "https://api.scryfall.com/cards/tznc/2/en?format=image"); put("ZNC/Kor Ally", "https://api.scryfall.com/cards/tznc/2/en?format=image");
put("ZNC/Rat", "https://api.scryfall.com/cards/tznc/6/en?format=image"); put("ZNC/Rat", "https://api.scryfall.com/cards/tznc/6/en?format=image");
@ -596,7 +581,6 @@ public class ScryfallImageSupportTokens {
put("C21/Beast/1", "https://api.scryfall.com/cards/tc21/10/en?format=image"); // 3/3 put("C21/Beast/1", "https://api.scryfall.com/cards/tc21/10/en?format=image"); // 3/3
put("C21/Beast/2", "https://api.scryfall.com/cards/tc21/11/en?format=image"); // 4/4 put("C21/Beast/2", "https://api.scryfall.com/cards/tc21/11/en?format=image"); // 4/4
put("C21/Boar", "https://api.scryfall.com/cards/tc21/12/en?format=image"); put("C21/Boar", "https://api.scryfall.com/cards/tc21/12/en?format=image");
put("C21/Champion of Wits", "https://api.scryfall.com/cards/tc21/6/en?format=image");
put("C21/Construct/1", "https://api.scryfall.com/cards/tc21/22/en?format=image"); // x/x put("C21/Construct/1", "https://api.scryfall.com/cards/tc21/22/en?format=image"); // x/x
put("C21/Construct/2", "https://api.scryfall.com/cards/tc21/23/en?format=image"); // 0/0 put("C21/Construct/2", "https://api.scryfall.com/cards/tc21/23/en?format=image"); // 0/0
put("C21/Demon", "https://api.scryfall.com/cards/tc21/7/en?format=image"); put("C21/Demon", "https://api.scryfall.com/cards/tc21/7/en?format=image");
@ -829,17 +813,45 @@ public class ScryfallImageSupportTokens {
put("NEC/Thopter", "https://api.scryfall.com/cards/tnec/12/en?format=image"); put("NEC/Thopter", "https://api.scryfall.com/cards/tnec/12/en?format=image");
// SLD // SLD
put("SLD/Angel", "https://api.scryfall.com/cards/sld/1340?format=image");
put("SLD/Cat/1", "https://api.scryfall.com/cards/sld/1517?format=image");
put("SLD/Cat/2", "https://api.scryfall.com/cards/sld/27?format=image");
put("SLD/Cat/3", "https://api.scryfall.com/cards/sld/28?format=image");
put("SLD/Clue", "https://api.scryfall.com/cards/sld/348/en?format=image"); put("SLD/Clue", "https://api.scryfall.com/cards/sld/348/en?format=image");
put("SLD/Dog", "https://api.scryfall.com/cards/sld/1516?format=image");
put("SLD/Egg", "https://api.scryfall.com/cards/sld/1398?format=image");
put("SLD/Faerie Rogue/1", "https://api.scryfall.com/cards/sld/13/en?format=image"); put("SLD/Faerie Rogue/1", "https://api.scryfall.com/cards/sld/13/en?format=image");
put("SLD/Faerie Rogue/2", "https://api.scryfall.com/cards/sld/14/en?format=image"); put("SLD/Faerie Rogue/2", "https://api.scryfall.com/cards/sld/14/en?format=image");
put("SLD/Faerie Rogue/3", "https://api.scryfall.com/cards/sld/15/en?format=image"); put("SLD/Faerie Rogue/3", "https://api.scryfall.com/cards/sld/15/en?format=image");
put("SLD/Faerie Rogue/4", "https://api.scryfall.com/cards/sld/16/en?format=image"); put("SLD/Faerie Rogue/4", "https://api.scryfall.com/cards/sld/16/en?format=image");
put("SLD/Treasure", "https://api.scryfall.com/cards/sld/153/en?format=image"); put("SLD/Food/1", "https://api.scryfall.com/cards/sld/1938?format=image");
put("SLD/Food/2", "https://api.scryfall.com/cards/sld/2010?format=image");
put("SLD/Food/3", "https://api.scryfall.com/cards/sld/2011?format=image");
put("SLD/Food/4", "https://api.scryfall.com/cards/sld/2012?format=image");
put("SLD/Food/5", "https://api.scryfall.com/cards/sld/2013?format=image");
put("SLD/Goblin", "https://api.scryfall.com/cards/sld/219?format=image");
put("SLD/Hydra", "https://api.scryfall.com/cards/sld/1334?format=image");
put("SLD/Icingdeath, Frost Tongue", "https://api.scryfall.com/cards/sld/1018?format=image");
put("SLD/Marit Lage", "https://api.scryfall.com/cards/sld/1681?format=image");
put("SLD/Mechtitan", "https://api.scryfall.com/cards/sld/1969?format=image");
put("SLD/Saproling", "https://api.scryfall.com/cards/sld/1139?format=image");
put("SLD/Shrine", "https://api.scryfall.com/cards/sld/1835?format=image");
put("SLD/Spirit/1", "https://api.scryfall.com/cards/sld/1341?format=image");
put("SLD/Spirit/2", "https://api.scryfall.com/cards/sld/1852?format=image");
put("SLD/Squirrel", "https://api.scryfall.com/cards/sld/200?format=image");
put("SLD/Treasure/1", "https://api.scryfall.com/cards/sld/1432/en?format=image");
put("SLD/Treasure/2", "https://api.scryfall.com/cards/sld/1736/en?format=image");
put("SLD/Treasure/3", "https://api.scryfall.com/cards/sld/1507/en?format=image");
put("SLD/Treasure/4", "https://api.scryfall.com/cards/sld/153/en?format=image");
put("SLD/Walker/1", "https://api.scryfall.com/cards/sld/148/en?format=image"); put("SLD/Walker/1", "https://api.scryfall.com/cards/sld/148/en?format=image");
put("SLD/Walker/2", "https://api.scryfall.com/cards/sld/149/en?format=image"); put("SLD/Walker/2", "https://api.scryfall.com/cards/sld/149/en?format=image");
put("SLD/Walker/3", "https://api.scryfall.com/cards/sld/150/en?format=image"); put("SLD/Walker/3", "https://api.scryfall.com/cards/sld/150/en?format=image");
put("SLD/Walker/4", "https://api.scryfall.com/cards/sld/151/en?format=image"); put("SLD/Walker/4", "https://api.scryfall.com/cards/sld/151/en?format=image");
put("SLD/Walker/5", "https://api.scryfall.com/cards/sld/152/en?format=image"); put("SLD/Walker/5", "https://api.scryfall.com/cards/sld/152/en?format=image");
put("SLD/Warrior", "https://api.scryfall.com/cards/sld/1752?format=image");
put("SLD/Wolf", "https://api.scryfall.com/cards/sld/1613?format=image");
put("SLD/Wurm", "https://api.scryfall.com/cards/sld/1306?format=image");
put("SLD/Zombie", "https://api.scryfall.com/cards/sld/1357?format=image");
// 2XM // 2XM
put("2XM/Angel", "https://api.scryfall.com/cards/t2xm/3/en?format=image"); put("2XM/Angel", "https://api.scryfall.com/cards/t2xm/3/en?format=image");
@ -1707,6 +1719,7 @@ public class ScryfallImageSupportTokens {
put("CLB/Squid", "https://api.scryfall.com/cards/tclb/29/en?format=image"); put("CLB/Squid", "https://api.scryfall.com/cards/tclb/29/en?format=image");
put("CLB/Squirrel", "https://api.scryfall.com/cards/tclb/15/en?format=image"); put("CLB/Squirrel", "https://api.scryfall.com/cards/tclb/15/en?format=image");
put("CLB/Treasure", "https://api.scryfall.com/cards/tclb/17/en?format=image"); put("CLB/Treasure", "https://api.scryfall.com/cards/tclb/17/en?format=image");
put("CLB/Undercity", "https://api.scryfall.com/cards/tclb/20/en?format=image");
put("CLB/Volo's Journal", "https://api.scryfall.com/cards/tclb/18/en?format=image"); put("CLB/Volo's Journal", "https://api.scryfall.com/cards/tclb/18/en?format=image");
put("CLB/Warrior", "https://api.scryfall.com/cards/tclb/32/en?format=image"); put("CLB/Warrior", "https://api.scryfall.com/cards/tclb/32/en?format=image");
put("CLB/Emblem Will Kenrith", "https://api.scryfall.com/cards/tclb/50/en?format=image"); put("CLB/Emblem Will Kenrith", "https://api.scryfall.com/cards/tclb/50/en?format=image");
@ -2168,12 +2181,33 @@ public class ScryfallImageSupportTokens {
put("WOC/Virtuous", "https://api.scryfall.com/cards/twoc/3/en?format=image"); put("WOC/Virtuous", "https://api.scryfall.com/cards/twoc/3/en?format=image");
// WHO // WHO
put("WHO/Alien", "https://api.scryfall.com/cards/twho/2?format=image");
put("WHO/Alien Insect", "https://api.scryfall.com/cards/twho/19/en?format=image"); put("WHO/Alien Insect", "https://api.scryfall.com/cards/twho/19/en?format=image");
put("WHO/Human Noble", "https://api.scryfall.com/cards/twho/7/en?format=image"); put("WHO/Alien Salamander", "https://api.scryfall.com/cards/twho/16?format=image");
put("WHO/Alien Warrior", "https://api.scryfall.com/cards/twho/14?format=image");
put("WHO/Beast", "https://api.scryfall.com/cards/twho/17?format=image");
put("WHO/Clue/1", "https://api.scryfall.com/cards/twho/21?format=image");
put("WHO/Clue/2", "https://api.scryfall.com/cards/twho/22?format=image");
put("WHO/Clue/3", "https://api.scryfall.com/cards/twho/23?format=image");
put("WHO/Dalek", "https://api.scryfall.com/cards/twho/12?format=image");
put("WHO/Dinosaur", "https://api.scryfall.com/cards/twho/20?format=image");
put("WHO/Fish", "https://api.scryfall.com/cards/twho/10?format=image");
put("WHO/Food/1", "https://api.scryfall.com/cards/twho/25?format=image");
put("WHO/Food/2", "https://api.scryfall.com/cards/twho/26?format=image");
put("WHO/Food/3", "https://api.scryfall.com/cards/twho/27?format=image");
put("WHO/Horse", "https://api.scryfall.com/cards/twho/4/en?format=image"); put("WHO/Horse", "https://api.scryfall.com/cards/twho/4/en?format=image");
put("WHO/Human", "https://api.scryfall.com/cards/twho/5?format=image");
put("WHO/Human Noble", "https://api.scryfall.com/cards/twho/7/en?format=image");
put("WHO/Mark of the Rani", "https://api.scryfall.com/cards/twho/15?format=image");
put("WHO/Soldier", "https://api.scryfall.com/cards/twho/8?format=image");
put("WHO/Treasure/1", "https://api.scryfall.com/cards/twho/28?format=image");
put("WHO/Treasure/2", "https://api.scryfall.com/cards/twho/29?format=image");
put("WHO/Treasure/3", "https://api.scryfall.com/cards/twho/30?format=image");
put("WHO/Treasure/4", "https://api.scryfall.com/cards/twho/31?format=image");
put("WHO/Warrior", "https://api.scryfall.com/cards/twho/9?format=image");
// 8ED // 8ED
put("8ED/Rukh", "https://api.scryfall.com/cards/p03/7/en?format=image"); put("8ED/Bird", "https://api.scryfall.com/cards/p03/7/en?format=image");
// LCI // LCI
put("LCI/Angel", "https://api.scryfall.com/cards/tlci/2/en?format=image"); put("LCI/Angel", "https://api.scryfall.com/cards/tlci/2/en?format=image");
@ -2494,7 +2528,18 @@ public class ScryfallImageSupportTokens {
put("BLC/Wolf/2", "https://api.scryfall.com/cards/tblc/32/en?format=image"); put("BLC/Wolf/2", "https://api.scryfall.com/cards/tblc/32/en?format=image");
// DSK // DSK
put("DSK/Beast", "https://api.scryfall.com/cards/tdsk/3?format=image");
put("DSK/Emblem Kaito", "https://api.scryfall.com/cards/tdsk/17/en?format=image"); put("DSK/Emblem Kaito", "https://api.scryfall.com/cards/tdsk/17/en?format=image");
put("DSK/Everywhere", "https://api.scryfall.com/cards/tdsk/16?format=image");
put("DSK/Glimmer", "https://api.scryfall.com/cards/tdsk/4?format=image");
put("DSK/Gremlin", "https://api.scryfall.com/cards/tdsk/11?format=image");
put("DSK/Insect/1", "https://api.scryfall.com/cards/tdsk/13?format=image");
put("DSK/Insect/2", "https://api.scryfall.com/cards/tdsk/5?format=image");
put("DSK/Primo, the Indivisible", "https://api.scryfall.com/cards/tdsk/14?format=image");
put("DSK/Shard", "https://api.scryfall.com/cards/tdsk/2?format=image");
put("DSK/Spider", "https://api.scryfall.com/cards/tdsk/12?format=image");
put("DSK/Spirit", "https://api.scryfall.com/cards/tdsk/8?format=image");
put("DSK/Treasure", "https://api.scryfall.com/cards/tdsk/15?format=image");
// DSC // DSC
put("DSC/Angel", "https://api.scryfall.com/cards/tdsc/2/en?format=image"); put("DSC/Angel", "https://api.scryfall.com/cards/tdsc/2/en?format=image");
@ -2615,20 +2660,43 @@ public class ScryfallImageSupportTokens {
put("DRC/Zombie Army", "https://api.scryfall.com/cards/tdrc/8/en?format=image"); put("DRC/Zombie Army", "https://api.scryfall.com/cards/tdrc/8/en?format=image");
put("DRC/Zombie Warrior", "https://api.scryfall.com/cards/tdrc/9/en?format=image"); put("DRC/Zombie Warrior", "https://api.scryfall.com/cards/tdrc/9/en?format=image");
// TDM
put("TDM/Bird", "https://api.scryfall.com/cards/ttdm/2/en?format=image");
put("TDM/Dragon", "https://api.scryfall.com/cards/ttdm/11/en?format=image");
put("TDM/Elephant", "https://api.scryfall.com/cards/ttdm/14/en?format=image");
put("TDM/Goblin", "https://api.scryfall.com/cards/ttdm/12/en?format=image");
put("TDM/Monk", "https://api.scryfall.com/cards/ttdm/3/en?format=image");
put("TDM/Reliquary Dragon", "https://api.scryfall.com/cards/ttdm/15/en?format=image");
put("TDM/Soldier/1", "https://api.scryfall.com/cards/ttdm/4/en?format=image");
put("TDM/Soldier/2", "https://api.scryfall.com/cards/ttdm/5/en?format=image");
put("TDM/Spirit/1", "https://api.scryfall.com/cards/ttdm/9/en?format=image");
put("TDM/Spirit/2", "https://api.scryfall.com/cards/ttdm/6/en?format=image");
// TODO: 2/2 and 3/3 Spirit tokens (no relevant cards revealed, token not implemented)
put("TDM/Treasure", "https://api.scryfall.com/cards/ttdm/16/en?format=image");
put("TDM/Warrior", "https://api.scryfall.com/cards/ttdm/13/en?format=image");
put("TDM/Zombie Druid", "https://api.scryfall.com/cards/ttdm/10/en?format=image");
// TDC // TDC
put("TDC/Angel", "https://api.scryfall.com/cards/ttdc/2/en?format=image"); put("TDC/Angel", "https://api.scryfall.com/cards/ttdc/2/en?format=image");
put("TDC/Beast", "https://api.scryfall.com/cards/ttdc/20?format=image");
put("TDC/Citizen", "https://api.scryfall.com/cards/ttdc/26/en?format=image"); put("TDC/Citizen", "https://api.scryfall.com/cards/ttdc/26/en?format=image");
put("TDC/Dog", "https://api.scryfall.com/cards/ttdc/3/en?format=image"); put("TDC/Dog", "https://api.scryfall.com/cards/ttdc/3/en?format=image");
put("TDC/Dragon/1", "https://api.scryfall.com/cards/ttdc/13?format=image");
put("TDC/Dragon/2", "https://api.scryfall.com/cards/ttdc/14?format=image");
put("TDC/Dragon Egg", "https://api.scryfall.com/cards/ttdc/12?format=image");
put("TDC/Dragon Illusion", "https://api.scryfall.com/cards/ttdc/15/en?format=image"); put("TDC/Dragon Illusion", "https://api.scryfall.com/cards/ttdc/15/en?format=image");
put("TDC/Eldrazi", "https://api.scryfall.com/cards/ttdc/1/en?format=image"); put("TDC/Eldrazi", "https://api.scryfall.com/cards/ttdc/1/en?format=image");
put("TDC/Elemental/1", "https://api.scryfall.com/cards/ttdc/16/en?format=image"); put("TDC/Elemental/1", "https://api.scryfall.com/cards/ttdc/16/en?format=image");
put("TDC/Elemental/2", "https://api.scryfall.com/cards/ttdc/17/en?format=image"); put("TDC/Elemental/2", "https://api.scryfall.com/cards/ttdc/17/en?format=image");
put("TDC/Elemental/3", "https://api.scryfall.com/cards/ttdc/27/en?format=image"); put("TDC/Elemental/3", "https://api.scryfall.com/cards/ttdc/27/en?format=image");
put("TDC/First Mate Ragavan", "https://api.scryfall.com/cards/ttdc/18/en?format=image"); put("TDC/First Mate Ragavan", "https://api.scryfall.com/cards/ttdc/18/en?format=image");
put("TDC/Frog Lizard", "https://api.scryfall.com/cards/ttdc/21?format=image");
put("TDC/Goat", "https://api.scryfall.com/cards/ttdc/4/en?format=image"); put("TDC/Goat", "https://api.scryfall.com/cards/ttdc/4/en?format=image");
put("TDC/Gold", "https://api.scryfall.com/cards/ttdc/29/en?format=image"); put("TDC/Gold", "https://api.scryfall.com/cards/ttdc/29/en?format=image");
put("TDC/Human", "https://api.scryfall.com/cards/ttdc/5/en?format=image"); put("TDC/Human", "https://api.scryfall.com/cards/ttdc/5/en?format=image");
put("TDC/Inkling", "https://api.scryfall.com/cards/ttdc/28?format=image");
put("TDC/Insect", "https://api.scryfall.com/cards/ttdc/22/en?format=image"); put("TDC/Insect", "https://api.scryfall.com/cards/ttdc/22/en?format=image");
put("TDC/Karox Bladewing", "https://api.scryfall.com/cards/ttdc/19?format=image");
put("TDC/Myr", "https://api.scryfall.com/cards/ttdc/30/en?format=image"); put("TDC/Myr", "https://api.scryfall.com/cards/ttdc/30/en?format=image");
put("TDC/Plant", "https://api.scryfall.com/cards/ttdc/24/en?format=image"); put("TDC/Plant", "https://api.scryfall.com/cards/ttdc/24/en?format=image");
put("TDC/Rat", "https://api.scryfall.com/cards/ttdc/9/en?format=image"); put("TDC/Rat", "https://api.scryfall.com/cards/ttdc/9/en?format=image");
@ -2636,9 +2704,136 @@ public class ScryfallImageSupportTokens {
put("TDC/Servo", "https://api.scryfall.com/cards/ttdc/31/en?format=image"); put("TDC/Servo", "https://api.scryfall.com/cards/ttdc/31/en?format=image");
put("TDC/Snake", "https://api.scryfall.com/cards/ttdc/10/en?format=image"); put("TDC/Snake", "https://api.scryfall.com/cards/ttdc/10/en?format=image");
put("TDC/Soldier", "https://api.scryfall.com/cards/ttdc/32/en?format=image"); put("TDC/Soldier", "https://api.scryfall.com/cards/ttdc/32/en?format=image");
put("TDC/Spider", "https://api.scryfall.com/cards/ttdc/25?format=image");
put("TDC/Spirit", "https://api.scryfall.com/cards/ttdc/6/en?format=image"); put("TDC/Spirit", "https://api.scryfall.com/cards/ttdc/6/en?format=image");
put("TDC/Thopter", "https://api.scryfall.com/cards/ttdc/33/en?format=image"); put("TDC/Thopter", "https://api.scryfall.com/cards/ttdc/33/en?format=image");
// ACR
put("ACR/Assassin", "https://api.scryfall.com/cards/tacr/4?format=image");
put("ACR/Emblem Capitoline Triad", "https://api.scryfall.com/cards/tacr/7/en?format=image");
put("ACR/Human Rogue", "https://api.scryfall.com/cards/tacr/3?format=image");
put("ACR/Phobos", "https://api.scryfall.com/cards/tacr/5?format=image");
put("ACR/Shapeshifter", "https://api.scryfall.com/cards/tacr/2?format=image");
put("ACR/Treasure", "https://api.scryfall.com/cards/tacr/6?format=image");
// DD2
put("DD2/Elemental Shaman", "https://api.scryfall.com/cards/tdd2/1?format=image");
// FIN
put("FIN/Food", "https://api.scryfall.com/cards/tfin/22?format=image");
// JVC
put("JVC/Elemental Shaman", "https://api.scryfall.com/cards/tjvc/4?format=image");
// PIP
put("PIP/Alien", "https://api.scryfall.com/cards/tpip/6?format=image");
put("PIP/Clue", "https://api.scryfall.com/cards/tpip/11?format=image");
put("PIP/Food/1", "https://api.scryfall.com/cards/tpip/12?format=image");
put("PIP/Food/2", "https://api.scryfall.com/cards/tpip/13?format=image");
put("PIP/Food/3", "https://api.scryfall.com/cards/tpip/14?format=image");
put("PIP/Human Knight", "https://api.scryfall.com/cards/tpip/2?format=image");
put("PIP/Human Soldier", "https://api.scryfall.com/cards/tpip/3?format=image");
put("PIP/Junk", "https://api.scryfall.com/cards/tpip/15?format=image");
put("PIP/Robot", "https://api.scryfall.com/cards/tpip/16?format=image");
put("PIP/Settlement", "https://api.scryfall.com/cards/tpip/8?format=image");
put("PIP/Soldier/1", "https://api.scryfall.com/cards/tpip/10?format=image");
put("PIP/Soldier/2", "https://api.scryfall.com/cards/tpip/4?format=image");
put("PIP/Squirrel", "https://api.scryfall.com/cards/tpip/9?format=image");
put("PIP/Thopter", "https://api.scryfall.com/cards/tpip/17?format=image");
put("PIP/Treasure/1", "https://api.scryfall.com/cards/tpip/18?format=image");
put("PIP/Treasure/2", "https://api.scryfall.com/cards/tpip/19?format=image");
put("PIP/Warrior", "https://api.scryfall.com/cards/tpip/5?format=image");
put("PIP/Wasteland Survival Guide", "https://api.scryfall.com/cards/tpip/20?format=image");
put("PIP/Zombie Mutant", "https://api.scryfall.com/cards/tpip/7?format=image");
// REX
put("REX/Dinosaur", "https://api.scryfall.com/cards/trex/1?format=image");
put("REX/Treasure", "https://api.scryfall.com/cards/trex/2?format=image");
// UGL
put("UGL/Goblin", "https://api.scryfall.com/cards/tugl/4?format=image");
put("UGL/Pegasus", "https://api.scryfall.com/cards/tugl/1?format=image");
put("UGL/Soldier", "https://api.scryfall.com/cards/tugl/2?format=image");
put("UGL/Squirrel", "https://api.scryfall.com/cards/tugl/6?format=image");
put("UGL/Zombie", "https://api.scryfall.com/cards/tugl/3?format=image");
// UST
put("UST/Angel", "https://api.scryfall.com/cards/tust/1?format=image");
put("UST/Beast", "https://api.scryfall.com/cards/tust/13?format=image");
put("UST/Brainiac", "https://api.scryfall.com/cards/tust/10?format=image");
put("UST/Clue", "https://api.scryfall.com/cards/tust/18?format=image");
put("UST/Dragon", "https://api.scryfall.com/cards/tust/16?format=image");
put("UST/Elemental/1", "https://api.scryfall.com/cards/tust/11?format=image");
put("UST/Elemental/2", "https://api.scryfall.com/cards/tust/17?format=image");
put("UST/Gnome", "https://api.scryfall.com/cards/tust/20?format=image");
put("UST/Goat", "https://api.scryfall.com/cards/tust/2?format=image");
put("UST/Goblin", "https://api.scryfall.com/cards/tust/12?format=image");
put("UST/Saproling", "https://api.scryfall.com/cards/tust/14?format=image");
put("UST/Spirit", "https://api.scryfall.com/cards/tust/3?format=image");
put("UST/Squirrel", "https://api.scryfall.com/cards/tust/15?format=image");
put("UST/Storm Crow", "https://api.scryfall.com/cards/tust/5?format=image");
put("UST/Thopter", "https://api.scryfall.com/cards/tust/6?format=image");
put("UST/Vampire", "https://api.scryfall.com/cards/tust/8?format=image");
put("UST/Zombie", "https://api.scryfall.com/cards/tust/9?format=image");
// F12
put("F12/Human", "https://api.scryfall.com/cards/f12/1a?format=image");
put("F12/Wolf", "https://api.scryfall.com/cards/f12/1a?format=image&face=back");
// F17
put("F17/Dinosaur", "https://api.scryfall.com/cards/f17/11?format=image");
put("F17/Pirate", "https://api.scryfall.com/cards/f17/12?format=image");
put("F17/Vampire", "https://api.scryfall.com/cards/f17/10?format=image");
put("F17/Treasure/1", "https://api.scryfall.com/cards/f17/11?format=image&face=back");
put("F17/Treasure/2", "https://api.scryfall.com/cards/f17/12?format=image&face=back");
put("F17/Treasure/3", "https://api.scryfall.com/cards/f17/10?format=image&face=back");
// HHO
put("HHO/Treasure", "https://api.scryfall.com/cards/hho/21★?format=image");
// J12
put("J12/Centaur", "https://api.scryfall.com/cards/j12/9?format=image");
// J13
put("J13/Golem", "https://api.scryfall.com/cards/j13/9?format=image");
// MPR
put("MPR/Bear", "https://api.scryfall.com/cards/mpr/7?format=image");
put("MPR/Beast", "https://api.scryfall.com/cards/mpr/8?format=image");
put("MPR/Bird", "https://api.scryfall.com/cards/mpr/4?format=image");
put("MPR/Elephant", "https://api.scryfall.com/cards/mpr/3?format=image");
put("MPR/Goblin Soldier", "https://api.scryfall.com/cards/mpr/6?format=image");
put("MPR/Saproling", "https://api.scryfall.com/cards/mpr/2?format=image");
put("MPR/Spirit", "https://api.scryfall.com/cards/mpr/5?format=image");
// P03
put("P03/Bear", "https://api.scryfall.com/cards/p03/4?format=image");
put("P03/Demon", "https://api.scryfall.com/cards/p03/6?format=image");
put("P03/Goblin", "https://api.scryfall.com/cards/p03/5?format=image");
put("P03/Insect", "https://api.scryfall.com/cards/p03/2?format=image");
put("P03/Bird", "https://api.scryfall.com/cards/p03/7?format=image");
put("P03/Sliver", "https://api.scryfall.com/cards/p03/3?format=image");
// P04
put("P04/Angel", "https://api.scryfall.com/cards/p04/2?format=image");
put("P04/Beast", "https://api.scryfall.com/cards/p04/5?format=image");
put("P04/Myr", "https://api.scryfall.com/cards/p04/4?format=image");
put("P04/Pentavite", "https://api.scryfall.com/cards/p04/3?format=image");
put("P04/Spirit", "https://api.scryfall.com/cards/p04/6?format=image");
// PEMN
put("PEMN/Zombie/1", "https://api.scryfall.com/cards/pemn/1Z?format=image");
put("PEMN/Zombie/2", "https://api.scryfall.com/cards/pemn/1Z?format=image&face=back");
// PHEL
put("PHEL/Angel", "https://api.scryfall.com/cards/phel/1★?format=image");
// PL21
put("PL21/Minotaur", "https://api.scryfall.com/cards/pl21/2★?format=image");
// PL23
put("PL23/Food", "https://api.scryfall.com/cards/pl23/2?format=image");
// generate supported sets // generate supported sets
supportedSets.clear(); supportedSets.clear();
for (String cardName : this.keySet()) { for (String cardName : this.keySet()) {

View file

@ -43,7 +43,7 @@ public class ScryfallImagesDownloadTest {
.anyMatch(c -> c.getCardNumber().equals("001")) .anyMatch(c -> c.getCardNumber().equals("001"))
); );
urls = imageSource.generateCardUrl(new CardDownloadData("The One Ring", "LTR", "001", false, 0)); urls = imageSource.generateCardUrl(new CardDownloadData("The One Ring", "LTR", "001", false, 0));
Assert.assertEquals("https://api.scryfall.com/cards/ltr/0/en?format=image", urls.getBaseUrl()); Assert.assertEquals("https://api.scryfall.com/cards/ltr/0/qya?format=image", urls.getBaseUrl());
// added same tests for small images // added same tests for small images
@ -74,6 +74,6 @@ public class ScryfallImagesDownloadTest {
.anyMatch(c -> c.getCardNumber().equals("001")) .anyMatch(c -> c.getCardNumber().equals("001"))
); );
urls = imageSourceSmall.generateCardUrl(new CardDownloadData("The One Ring", "LTR", "001", false, 0)); urls = imageSourceSmall.generateCardUrl(new CardDownloadData("The One Ring", "LTR", "001", false, 0));
Assert.assertEquals("https://api.scryfall.com/cards/ltr/0/en?format=image&version=small", urls.getBaseUrl()); Assert.assertEquals("https://api.scryfall.com/cards/ltr/0/qya?format=image&version=small", urls.getBaseUrl());
} }
} }

View file

@ -40,7 +40,7 @@ public class CombatGroupView implements Serializable {
attackers.put(id, new PermanentView(attacker, game.getCard(attacker.getId()),null, game)); attackers.put(id, new PermanentView(attacker, game.getCard(attacker.getId()),null, game));
} }
} }
for (UUID id: combatGroup.getBlockerOrder()) { for (UUID id: combatGroup.getBlockers()) {
Permanent blocker = game.getPermanent(id); Permanent blocker = game.getPermanent(id);
if (blocker != null) { if (blocker != null) {
blockers.put(id, new PermanentView(blocker, game.getCard(blocker.getId()), null, game)); blockers.put(id, new PermanentView(blocker, game.getCard(blocker.getId()), null, game));

View file

@ -64,6 +64,7 @@ public class Legacy extends Constructed {
banned.add("Sensei's Divining Top"); banned.add("Sensei's Divining Top");
banned.add("Skullclamp"); banned.add("Skullclamp");
banned.add("Sol Ring"); banned.add("Sol Ring");
banned.add("Sowing Mycospawn");
banned.add("Strip Mine"); banned.add("Strip Mine");
banned.add("Survival of the Fittest"); banned.add("Survival of the Fittest");
banned.add("Time Vault"); banned.add("Time Vault");
@ -72,6 +73,7 @@ public class Legacy extends Constructed {
banned.add("Tinker"); banned.add("Tinker");
banned.add("Tolarian Academy"); banned.add("Tolarian Academy");
banned.add("Treasure Cruise"); banned.add("Treasure Cruise");
banned.add("Troll of Khazad-dum");
banned.add("Underworld Breach"); banned.add("Underworld Breach");
banned.add("Vampiric Tutor"); banned.add("Vampiric Tutor");
banned.add("Vexing Bauble"); banned.add("Vexing Bauble");

View file

@ -69,6 +69,7 @@ public class Modern extends Constructed {
banned.add("Treasure Cruise"); banned.add("Treasure Cruise");
banned.add("Tree of Tales"); banned.add("Tree of Tales");
banned.add("Umezawa's Jitte"); banned.add("Umezawa's Jitte");
banned.add("Underworld Breach");
banned.add("Up the Beanstalk"); banned.add("Up the Beanstalk");
banned.add("Uro, Titan of Nature's Wrath"); banned.add("Uro, Titan of Nature's Wrath");
banned.add("Vault of Whispers"); banned.add("Vault of Whispers");

View file

@ -29,6 +29,7 @@ public class Pauper extends Constructed {
banned.add("All That Glitters"); banned.add("All That Glitters");
banned.add("Arcum's Astrolabe"); banned.add("Arcum's Astrolabe");
banned.add("Atog"); banned.add("Atog");
banned.add("Basking Broodscale");
banned.add("Bonder's Ornament"); banned.add("Bonder's Ornament");
banned.add("Chatterstorm"); banned.add("Chatterstorm");
banned.add("Cloud of Faeries"); banned.add("Cloud of Faeries");
@ -36,6 +37,7 @@ public class Pauper extends Constructed {
banned.add("Cranial Plating"); banned.add("Cranial Plating");
banned.add("Cranial Ram"); banned.add("Cranial Ram");
banned.add("Daze"); banned.add("Daze");
banned.add("Deadly Dispute");
banned.add("Disciple of the Vault"); banned.add("Disciple of the Vault");
banned.add("Empty the Warrens"); banned.add("Empty the Warrens");
banned.add("Fall from Favor"); banned.add("Fall from Favor");
@ -44,13 +46,12 @@ public class Pauper extends Constructed {
banned.add("Gitaxian Probe"); banned.add("Gitaxian Probe");
banned.add("Grapeshot"); banned.add("Grapeshot");
banned.add("Gush"); banned.add("Gush");
banned.add("High Tide");
banned.add("Hymn to Tourach"); banned.add("Hymn to Tourach");
banned.add("Invigorate"); banned.add("Invigorate");
banned.add("Kuldotha Rebirth");
banned.add("Monastery Swiftspear"); banned.add("Monastery Swiftspear");
banned.add("Mystic Sanctuary"); banned.add("Mystic Sanctuary");
banned.add("Peregrine Drake"); banned.add("Peregrine Drake");
banned.add("Prophetic Prism");
banned.add("Sinkhole"); banned.add("Sinkhole");
banned.add("Stirring Bard"); banned.add("Stirring Bard");
banned.add("Sojourner's Companion"); banned.add("Sojourner's Companion");

View file

@ -13,10 +13,8 @@ import mage.constants.MultiAmountType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.RangeOfInfluence; import mage.constants.RangeOfInfluence;
import mage.game.Game; import mage.game.Game;
import mage.game.combat.CombatGroup;
import mage.game.draft.Draft; import mage.game.draft.Draft;
import mage.game.match.Match; import mage.game.match.Match;
import mage.game.permanent.Permanent;
import mage.game.tournament.Tournament; import mage.game.tournament.Tournament;
import mage.players.Player; import mage.players.Player;
import mage.target.Target; import mage.target.Target;
@ -287,24 +285,6 @@ public class ComputerPlayerControllableProxy extends ComputerPlayer7 {
} }
} }
@Override
public UUID chooseAttackerOrder(java.util.List<Permanent> attackers, Game game) {
if (isUnderMe(game)) {
return super.chooseAttackerOrder(attackers, game);
} else {
return getControllingPlayer(game).chooseAttackerOrder(attackers, game);
}
}
@Override
public UUID chooseBlockerOrder(java.util.List<Permanent> blockers, CombatGroup combatGroup, java.util.List<UUID> blockerOrder, Game game) {
if (isUnderMe(game)) {
return super.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
} else {
return getControllingPlayer(game).chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
}
}
@Override @Override
public int getAmount(int min, int max, String message, Game game) { public int getAmount(int min, int max, String message, Game game) {
if (isUnderMe(game)) { if (isUnderMe(game)) {

View file

@ -2177,9 +2177,6 @@ public class ComputerPlayer extends PlayerImpl {
// TODO: add AI support with outcome and replace random with min/max // TODO: add AI support with outcome and replace random with min/max
public int getAmount(int min, int max, String message, Game game) { public int getAmount(int min, int max, String message, Game game) {
log.debug("getAmount"); log.debug("getAmount");
if (message.startsWith("Assign damage to ")) {
return min;
}
if (min < max && min == 0) { if (min < max && min == 0) {
return RandomUtil.nextInt(CardUtil.overflowInc(max, 1)); return RandomUtil.nextInt(CardUtil.overflowInc(max, 1));
} }
@ -2192,7 +2189,7 @@ public class ComputerPlayer extends PlayerImpl {
log.debug("getMultiAmount"); log.debug("getMultiAmount");
int needCount = messages.size(); int needCount = messages.size();
List<Integer> defaultList = MultiAmountType.prepareDefaltValues(messages, totalMin, totalMax); List<Integer> defaultList = MultiAmountType.prepareDefaultValues(messages, totalMin, totalMax);
if (needCount == 0) { if (needCount == 0) {
return defaultList; return defaultList;
} }
@ -2210,18 +2207,6 @@ public class ComputerPlayer extends PlayerImpl {
return MultiAmountType.prepareMaxValues(messages, totalMin, totalMax); return MultiAmountType.prepareMaxValues(messages, totalMin, totalMax);
} }
@Override
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
//TODO: improve this
return attackers.iterator().next().getId();
}
@Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
//TODO: improve this
return blockers.iterator().next().getId();
}
@Override @Override
public List<MageObject> getAvailableManaProducers(Game game) { public List<MageObject> getAvailableManaProducers(Game game) {
return super.getAvailableManaProducers(game); return super.getAvailableManaProducers(game);

View file

@ -374,22 +374,6 @@ public final class SimulatedPlayerMCTS extends MCTSPlayer {
return super.chooseMode(modes, source, game); return super.chooseMode(modes, source, game);
} }
@Override
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
if (this.isHuman()) {
return attackers.get(RandomUtil.nextInt(attackers.size())).getId();
}
return super.chooseAttackerOrder(attackers, game);
}
@Override
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
if (this.isHuman()) {
return blockers.get(RandomUtil.nextInt(blockers.size())).getId();
}
return super.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
}
@Override @Override
public int getAmount(int min, int max, String message, Game game) { public int getAmount(int min, int max, String message, Game game) {
if (this.isHuman()) { if (this.isHuman()) {

View file

@ -2122,56 +2122,6 @@ public class HumanPlayer extends PlayerImpl {
} }
} }
@Override
public UUID chooseAttackerOrder(java.util.List<Permanent> attackers, Game game) {
if (gameInCheckPlayableState(game)) {
return null;
}
while (canRespond()) {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(playerId, "Pick attacker", attackers, true);
}
waitForResponse(game);
UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
for (Permanent perm : attackers) {
if (perm.getId().equals(responseId)) {
return perm.getId();
}
}
}
}
return null;
}
@Override
public UUID chooseBlockerOrder(java.util.List<Permanent> blockers, CombatGroup combatGroup, java.util.List<UUID> blockerOrder, Game game) {
if (gameInCheckPlayableState(game)) {
return null;
}
while (canRespond()) {
prepareForResponse(game);
if (!isExecutingMacro()) {
game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true);
}
waitForResponse(game);
UUID responseId = getFixedResponseUUID(game);
if (responseId != null) {
for (Permanent perm : blockers) {
if (perm.getId().equals(responseId)) {
return perm.getId();
}
}
}
}
return null;
}
protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) { protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
if (gameInCheckPlayableState(game)) { if (gameInCheckPlayableState(game)) {
return; return;
@ -2260,7 +2210,7 @@ public class HumanPlayer extends PlayerImpl {
Game game Game game
) { ) {
int needCount = messages.size(); int needCount = messages.size();
List<Integer> defaultList = MultiAmountType.prepareDefaltValues(messages, totalMin, totalMax); List<Integer> defaultList = MultiAmountType.prepareDefaultValues(messages, totalMin, totalMax);
if (needCount == 0 || (needCount == 1 && totalMin == totalMax) if (needCount == 0 || (needCount == 1 && totalMin == totalMax)
|| messages.stream().map(m -> m.min == m.max).reduce(true, Boolean::logicalAnd)) { || messages.stream().map(m -> m.min == m.max).reduce(true, Boolean::logicalAnd)) {
// nothing to choose // nothing to choose

View file

@ -0,0 +1,43 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.RenewAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.game.permanent.token.ZombieDruidToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AdornedCrocodile extends CardImpl {
public AdornedCrocodile(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.CROCODILE);
this.power = new MageInt(5);
this.toughness = new MageInt(3);
// When this creature dies, create a 2/2 black Zombie Druid creature token.
this.addAbility(new DiesSourceTriggeredAbility(new CreateTokenEffect(new ZombieDruidToken())));
// Renew -- {B}, Exile this card from your graveyard: Put a +1/+1 counter on target creature. Activate only as a sorcery.
this.addAbility(new RenewAbility("{B}", CounterType.P1P1.createInstance()));
}
private AdornedCrocodile(final AdornedCrocodile card) {
super(card);
}
@Override
public AdornedCrocodile copy() {
return new AdornedCrocodile(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.MillThenPutInHandEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AinokWayfarer extends CardImpl {
public AinokWayfarer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.DOG);
this.subtype.add(SubType.SCOUT);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// When this creature enters, mill three cards. You may put a land card from among them into your hand. If you don't, put a +1/+1 counter on this creature.
this.addAbility(new EntersBattlefieldTriggeredAbility(new MillThenPutInHandEffect(
1, StaticFilters.FILTER_CARD_LAND_A,
new AddCountersSourceEffect(CounterType.P1P1.createInstance(), true)
)));
}
private AinokWayfarer(final AinokWayfarer card) {
super(card);
}
@Override
public AinokWayfarer copy() {
return new AinokWayfarer(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.RenewAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class AlchemistsAssistant extends CardImpl {
public AlchemistsAssistant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.MONKEY);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// Renew -- {1}{B}, Exile this card from your graveyard: Put a lifelink counter on target creature. Activate only as a sorcery.
this.addAbility(new RenewAbility("{1}{B}", CounterType.LIFELINK.createInstance()));
}
private AlchemistsAssistant(final AlchemistsAssistant card) {
super(card);
}
@Override
public AlchemistsAssistant copy() {
return new AlchemistsAssistant(this);
}
}

View file

@ -0,0 +1,54 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCardInASingleGraveyard;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ArashinSunshield extends CardImpl {
public ArashinSunshield(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// When this creature enters, exile up to two target cards from a single graveyard.
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileTargetEffect());
ability.addTarget(new TargetCardInASingleGraveyard(0, 2, StaticFilters.FILTER_CARDS_NON_LAND));
this.addAbility(ability);
// {W}, {T}: Tap target creature.
ability = new SimpleActivatedAbility(new TapTargetEffect(), new ManaCostsImpl<>("{W}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
private ArashinSunshield(final ArashinSunshield card) {
super(card);
}
@Override
public ArashinSunshield copy() {
return new ArashinSunshield(this);
}
}

View file

@ -153,10 +153,6 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
game.fireEvent(new BlockerDeclaredEvent(chosenPermanent.getId(), permanent.getId(), permanent.getControllerId())); game.fireEvent(new BlockerDeclaredEvent(chosenPermanent.getId(), permanent.getId(), permanent.getControllerId()));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, permanent.getId(), source, null)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, permanent.getId(), source, null));
} }
CombatGroup blockGroup = findBlockingGroup(permanent, game); // a new blockingGroup is formed, so it's necessary to find it again
if (blockGroup != null) {
blockGroup.pickAttackerOrder(permanent.getControllerId(), game);
}
} }
} }
return true; return true;
@ -164,15 +160,4 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
} }
return false; return false;
} }
private CombatGroup findBlockingGroup(Permanent blocker, Game game) {
if (game.getCombat().blockingGroupsContains(blocker.getId())) { // if (blocker.getBlocking() > 1) {
for (CombatGroup group : game.getCombat().getBlockingGroups()) {
if (group.getBlockers().contains(blocker.getId())) {
return group;
}
}
}
return null;
}
} }

View file

@ -1,7 +1,6 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.common.AttacksTriggeredAbility;
@ -22,6 +21,8 @@ import mage.game.permanent.token.CatSoldierCreatureToken;
import mage.game.permanent.token.Token; import mage.game.permanent.token.Token;
import mage.players.Player; import mage.players.Player;
import java.util.UUID;
/** /**
* *
* @author LevelX2 * @author LevelX2
@ -99,7 +100,6 @@ class BrimazKingOfOreskosEffect extends OneShotEffect {
combatGroup.addBlocker(tokenId, source.getControllerId(), game); combatGroup.addBlocker(tokenId, source.getControllerId(), game);
game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game); game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game);
} }
combatGroup.pickBlockerOrder(attackingCreature.getControllerId(), game);
return true; return true;
} }

View file

@ -0,0 +1,46 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.common.RenewAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ChampionOfDusan extends CardImpl {
public ChampionOfDusan(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(4);
this.toughness = new MageInt(2);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Renew -- {1}{G}, Exile this card from your graveyard: Put a +1/+1 counter and a trample counter on target creature. Activate only as a sorcery.
this.addAbility(new RenewAbility(
"{1}{G}",
CounterType.P1P1.createInstance(),
CounterType.TRAMPLE.createInstance()
));
}
private ChampionOfDusan(final ChampionOfDusan card) {
super(card);
}
@Override
public ChampionOfDusan copy() {
return new ChampionOfDusan(this);
}
}

View file

@ -0,0 +1,59 @@
package mage.cards.c;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.ExileSourceFromGraveCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AbilityWord;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ConstrictorSage extends CardImpl {
public ConstrictorSage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}");
this.subtype.add(SubType.SNAKE);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When this creature enters, tap target creature an opponent controls and put a stun counter on it.
Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect());
ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance())
.setText("and put a stun counter on it"));
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
// Renew -- {2}{U}, Exile this card from your graveyard: Tap target creature an opponent controls and put a stun counter on it. Activate only as a sorcery.
ability = new ActivateAsSorceryActivatedAbility(Zone.GRAVEYARD, new TapTargetEffect(), new ManaCostsImpl<>("{2}{U}"));
ability.addCost(new ExileSourceFromGraveCost());
ability.addEffect(new AddCountersTargetEffect(CounterType.STUN.createInstance())
.setText("and put a stun counter on it"));
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability.setAbilityWord(AbilityWord.RENEW));
}
private ConstrictorSage(final ConstrictorSage card) {
super(card);
}
@Override
public ConstrictorSage copy() {
return new ConstrictorSage(this);
}
}

View file

@ -12,7 +12,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.common.FilterNonlandPermanent; import mage.filter.common.FilterNonlandPermanent;
import mage.game.permanent.token.CrushOfTentaclesToken; import mage.game.permanent.token.OctopusToken;
/** /**
* *
@ -25,7 +25,7 @@ public final class CrushOfTentacles extends CardImpl {
// Return all nonland permanents to their owners' hands. If Crush of Tentacles surge cost was paid, create an 8/8 blue Octopus creature token. // Return all nonland permanents to their owners' hands. If Crush of Tentacles surge cost was paid, create an 8/8 blue Octopus creature token.
getSpellAbility().addEffect(new ReturnToHandFromBattlefieldAllEffect(new FilterNonlandPermanent("nonland permanents"))); getSpellAbility().addEffect(new ReturnToHandFromBattlefieldAllEffect(new FilterNonlandPermanent("nonland permanents")));
Effect effect = new ConditionalOneShotEffect(new CreateTokenEffect(new CrushOfTentaclesToken()), SurgedCondition.instance); Effect effect = new ConditionalOneShotEffect(new CreateTokenEffect(new OctopusToken()), SurgedCondition.instance);
effect.setText("If this spell's surge cost was paid, create an 8/8 blue Octopus creature token"); effect.setText("If this spell's surge cost was paid, create an 8/8 blue Octopus creature token");
getSpellAbility().addEffect(effect); getSpellAbility().addEffect(effect);

View file

@ -17,7 +17,7 @@ import mage.constants.SuperType;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.SeedGuardianToken; import mage.game.permanent.token.ElementalXXGreenToken;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import java.util.UUID; import java.util.UUID;
@ -83,7 +83,7 @@ class DanceOfTheTumbleweedsEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return new SeedGuardianToken(LandsYouControlCount.instance.calculate(game, source, this)) return new ElementalXXGreenToken(LandsYouControlCount.instance.calculate(game, source, this))
.putOntoBattlefield(1, game, source); .putOntoBattlefield(1, game, source);
} }
} }

View file

@ -0,0 +1,45 @@
package mage.cards.d;
import mage.MageInt;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.ReachAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class DragonSniper extends CardImpl {
public DragonSniper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ARCHER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Reach
this.addAbility(ReachAbility.getInstance());
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
}
private DragonSniper(final DragonSniper card) {
super(card);
}
@Override
public DragonSniper copy() {
return new DragonSniper(this);
}
}

View file

@ -0,0 +1,74 @@
package mage.cards.e;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.effects.common.replacement.CreateTwiceThatManyTokensEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterOpponentsCreaturePermanent;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.permanent.token.SoldierToken;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ElspethStormSlayer extends CardImpl {
private static final FilterPermanent filter
= new FilterOpponentsCreaturePermanent("creature an opponent controls with mana value 3 or greater");
static {
filter.add(new ManaValuePredicate(ComparisonType.MORE_THAN, 2));
}
public ElspethStormSlayer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{3}{W}{W}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.ELSPETH);
this.setStartingLoyalty(5);
// If one or more tokens would be created under your control, twice that many of those tokens are created instead.
this.addAbility(new SimpleStaticAbility(new CreateTwiceThatManyTokensEffect()));
// +1: Create a 1/1 white Soldier creature token.
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new SoldierToken()), 1));
// 0: Put a +1/+1 counter on each creature you control. Those creatures gain flying until your next turn.
Ability ability = new LoyaltyAbility(new AddCountersAllEffect(
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
), 0);
ability.addEffect(new GainAbilityControlledEffect(
FlyingAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_CONTROLLED_CREATURE
).setText("those creatures gain flying until end of turn"));
this.addAbility(ability);
// -3: Destroy target creature an opponent controls with mana value 3 or greater.
ability = new LoyaltyAbility(new DestroyTargetEffect(), -3);
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
private ElspethStormSlayer(final ElspethStormSlayer card) {
super(card);
}
@Override
public ElspethStormSlayer copy() {
return new ElspethStormSlayer(this);
}
}

View file

@ -0,0 +1,64 @@
package mage.cards.e;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.Game;
import mage.game.permanent.token.ZombieDruidToken;
import mage.watchers.common.CardsLeftGraveyardWatcher;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class EssenceAnchor extends CardImpl {
public EssenceAnchor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}{U}");
// At the beginning of your upkeep, surveil 1.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SurveilEffect(1)));
// {T}: Create a 2/2 black Zombie Druid creature token. Activate only during your turn and only if a card left your graveyard this turn.
this.addAbility(new ActivateIfConditionActivatedAbility(
new CreateTokenEffect(new ZombieDruidToken()),
new TapSourceCost(), EssenceAnchorCondition.instance
), new CardsLeftGraveyardWatcher());
}
private EssenceAnchor(final EssenceAnchor card) {
super(card);
}
@Override
public EssenceAnchor copy() {
return new EssenceAnchor(this);
}
}
enum EssenceAnchorCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
return game.isActivePlayer(source.getControllerId())
&& !game
.getState()
.getWatcher(CardsLeftGraveyardWatcher.class)
.getCardsThatLeftGraveyard(source.getControllerId(), game)
.isEmpty();
}
@Override
public String toString() {
return "during your turn and only if a card left your graveyard this turn";
}
}

View file

@ -12,7 +12,7 @@ import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.FilterSpell; import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.ColorPredicate; import mage.filter.predicate.mageobject.ColorPredicate;
import mage.game.permanent.token.EyesOfTheWisentElementalToken; import mage.game.permanent.token.Elemental44GreenToken;
import java.util.UUID; import java.util.UUID;
@ -33,7 +33,7 @@ public final class EyesOfTheWisent extends CardImpl {
// Whenever an opponent casts a blue spell during your turn, you may create a 4/4 green Elemental creature token. // Whenever an opponent casts a blue spell during your turn, you may create a 4/4 green Elemental creature token.
this.addAbility(new ConditionalTriggeredAbility( this.addAbility(new ConditionalTriggeredAbility(
new SpellCastOpponentTriggeredAbility(new CreateTokenEffect(new EyesOfTheWisentElementalToken()), filter, true), new SpellCastOpponentTriggeredAbility(new CreateTokenEffect(new Elemental44GreenToken()), filter, true),
MyTurnCondition.instance, MyTurnCondition.instance,
"Whenever an opponent casts a blue spell during your turn, you may create a 4/4 green Elemental creature token." "Whenever an opponent casts a blue spell during your turn, you may create a 4/4 green Elemental creature token."
).addHint(MyTurnHint.instance)); ).addHint(MyTurnHint.instance));

View file

@ -169,21 +169,6 @@ class FalseOrdersUnblockEffect extends OneShotEffect {
game.fireEvent(new BlockerDeclaredEvent(chosenPermanent.getId(), permanent.getId(), permanent.getControllerId())); game.fireEvent(new BlockerDeclaredEvent(chosenPermanent.getId(), permanent.getId(), permanent.getControllerId()));
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, permanent.getId(), source, null)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, permanent.getId(), source, null));
} }
CombatGroup blockGroup = findBlockingGroup(permanent, game); // a new blockingGroup is formed, so it's necessary to find it again
if (blockGroup != null) {
blockGroup.pickAttackerOrder(permanent.getControllerId(), game);
}
return true; return true;
} }
private CombatGroup findBlockingGroup(Permanent blocker, Game game) {
if (game.getCombat().blockingGroupsContains(blocker.getId())) { // if (blocker.getBlocking() > 1) {
for (CombatGroup group : game.getCombat().getBlockingGroups()) {
if (group.getBlockers().contains(blocker.getId())) {
return group;
}
}
}
return null;
}
} }

View file

@ -0,0 +1,55 @@
package mage.cards.f;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FireRimForm extends CardImpl {
public FireRimForm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
this.subtype.add(SubType.AURA);
// Flash
this.addAbility(FlashAbility.getInstance());
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.addAbility(new EnchantAbility(auraTarget));
// When this Aura enters, enchanted creature gains first strike until end of turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainAbilityAttachedEffect(
FirstStrikeAbility.getInstance(), AttachmentType.AURA, Duration.EndOfTurn
)));
// Enchanted creature gets +2/+0.
this.addAbility(new SimpleStaticAbility(new BoostEnchantedEffect(2, 0)));
}
private FireRimForm(final FireRimForm card) {
super(card);
}
@Override
public FireRimForm copy() {
return new FireRimForm(this);
}
}

View file

@ -90,7 +90,6 @@ class FlashFoliageEffect extends OneShotEffect {
game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game); game.getCombat().addBlockingGroup(tokenId, attackingCreature.getId(), controller.getId(), game);
} }
} }
combatGroup.pickBlockerOrder(attackingCreature.getControllerId(), game);
} }
} }
return true; return true;

View file

@ -0,0 +1,50 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FleetingEffigy extends CardImpl {
public FleetingEffigy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Haste
this.addAbility(HasteAbility.getInstance());
// At the beginning of your end step, return this creature to its owner's hand.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new ReturnToHandSourceEffect()));
// {2}{R}: This creature gets +2/+0 until end of turn.
this.addAbility(new SimpleActivatedAbility(
new BoostSourceEffect(2, 0, Duration.EndOfTurn), new ManaCostsImpl<>("{2}{R}")
));
}
private FleetingEffigy(final FleetingEffigy card) {
super(card);
}
@Override
public FleetingEffigy copy() {
return new FleetingEffigy(this);
}
}

View file

@ -24,7 +24,7 @@ import mage.filter.StaticFilters;
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.token.FleshCarverHorrorToken; import mage.game.permanent.token.HorrorXXBlackToken;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
@ -110,7 +110,7 @@ class FleshCarverEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
int xValue = (Integer) getValue("power"); int xValue = (Integer) getValue("power");
return new CreateTokenEffect(new FleshCarverHorrorToken(xValue)).apply(game, source); return new CreateTokenEffect(new HorrorXXBlackToken(xValue)).apply(game, source);
} }
return false; return false;
} }

View file

@ -0,0 +1,41 @@
package mage.cards.f;
import mage.abilities.Mode;
import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.permanent.token.GoblinToken;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FrontlineRush extends CardImpl {
public FrontlineRush(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}{W}");
// Choose one --
// * Create two 1/1 red Goblin creature tokens.
this.getSpellAbility().addEffect(new CreateTokenEffect(new GoblinToken(), 2));
// * Target creature gets +X/+X until end of turn, where X is the number of creatures you control.
this.getSpellAbility().addMode(new Mode(new BoostTargetEffect(
CreaturesYouControlCount.instance, CreaturesYouControlCount.instance
)).addTarget(new TargetCreaturePermanent()));
}
private FrontlineRush(final FrontlineRush card) {
super(card);
}
@Override
public FrontlineRush copy() {
return new FrontlineRush(this);
}
}

View file

@ -1,10 +1,6 @@
package mage.cards.g; package mage.cards.g;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.common.IsStepCondition; import mage.abilities.condition.common.IsStepCondition;
@ -13,18 +9,18 @@ import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.combat.CombatGroup; import mage.game.combat.CombatGroup;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetAttackingCreature; import mage.target.common.TargetAttackingCreature;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/** /**
* *
* @author L_J * @author L_J
@ -138,11 +134,9 @@ class GeneralJarkeldSwitchBlockersEffect extends OneShotEffect {
// the ability doesn't unblock a group that loses all blockers, however it will newly block a previously unblocked group if it gains a blocker this way // the ability doesn't unblock a group that loses all blockers, however it will newly block a previously unblocked group if it gains a blocker this way
if (!(chosenGroup1.getBlockers().isEmpty())) { if (!(chosenGroup1.getBlockers().isEmpty())) {
chosenGroup1.setBlocked(true, game); chosenGroup1.setBlocked(true, game);
chosenGroup1.pickBlockerOrder(attacker1.getControllerId(), game);
} }
if (!(chosenGroup2.getBlockers().isEmpty())) { if (!(chosenGroup2.getBlockers().isEmpty())) {
chosenGroup2.setBlocked(true, game); chosenGroup2.setBlocked(true, game);
chosenGroup2.pickBlockerOrder(attacker2.getControllerId(), game);
} }
return true; return true;
} }
@ -197,7 +191,6 @@ class GeneralJarkeldSwitchBlockersEffect extends OneShotEffect {
// 10/4/2004 The new blocker does not trigger any abilities which trigger on creatures becoming blockers, because the creatures were already blockers and the simple change of who is blocking does not trigger such abilities. // 10/4/2004 The new blocker does not trigger any abilities which trigger on creatures becoming blockers, because the creatures were already blockers and the simple change of who is blocking does not trigger such abilities.
game.getCombat().addBlockingGroup(blocker.getId(), attacker, controller.getId(), game); game.getCombat().addBlockingGroup(blocker.getId(), attacker, controller.getId(), game);
} }
blockGroup.pickAttackerOrder(blocker.getControllerId(), game);
} }
} }
} }

View file

@ -54,7 +54,7 @@ public final class GlarbCalamitysAugur extends CardImpl {
this.addAbility(new SimpleStaticAbility(new PlayFromTopOfLibraryEffect(filter))); this.addAbility(new SimpleStaticAbility(new PlayFromTopOfLibraryEffect(filter)));
// {T}: Surveil 2. // {T}: Surveil 2.
this.addAbility(new SimpleActivatedAbility(new SurveilEffect(2), new TapSourceCost())); this.addAbility(new SimpleActivatedAbility(new SurveilEffect(2, false), new TapSourceCost()));
} }
private GlarbCalamitysAugur(final GlarbCalamitysAugur card) { private GlarbCalamitysAugur(final GlarbCalamitysAugur card) {

View file

@ -16,7 +16,7 @@ import mage.constants.SubType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.game.permanent.token.SpiritWhiteToken; import mage.game.permanent.token.NoFlyingSpiritWhiteToken;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID; import java.util.UUID;
@ -47,9 +47,9 @@ public final class GreatArashinCity extends CardImpl {
this.addAbility(new BlackManaAbility()); this.addAbility(new BlackManaAbility());
// {1}{B}, {T}, Exile a creature card from your graveyard: Create a 1/1 white Spirit creature token. // {1}{B}, {T}, Exile a creature card from your graveyard: Create a 1/1 white Spirit creature token.
Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new SpiritWhiteToken()), new ManaCostsImpl<>("{1}{B}")); Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new NoFlyingSpiritWhiteToken()), new ManaCostsImpl<>("{1}{B}"));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE))); ability.addCost(new ExileFromGraveCost(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE)).withSourceExileZone(false));
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -16,7 +16,7 @@ import mage.counters.CounterType;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.TokenPredicate; import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.permanent.token.GrismoldPlantToken; import mage.game.permanent.token.Plant11Token;
import java.util.UUID; import java.util.UUID;
@ -45,7 +45,7 @@ public final class GrismoldTheDreadsower extends CardImpl {
// At the beginning of your end step, each player creates a 1/1 green Plant creature token. // At the beginning of your end step, each player creates a 1/1 green Plant creature token.
this.addAbility(new BeginningOfEndStepTriggeredAbility( this.addAbility(new BeginningOfEndStepTriggeredAbility(
new CreateTokenAllEffect(new GrismoldPlantToken(), TargetController.EACH_PLAYER) new CreateTokenAllEffect(new Plant11Token(), TargetController.EACH_PLAYER)
)); ));
// Whenever a creature token dies, put a +1/+1 counter on Grismold, the Dreadsower. // Whenever a creature token dies, put a +1/+1 counter on Grismold, the Dreadsower.

View file

@ -9,7 +9,7 @@ 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.game.permanent.token.GrovetenderDruidsPlantToken; import mage.game.permanent.token.Plant11Token;
import java.util.UUID; import java.util.UUID;
@ -29,7 +29,7 @@ public final class GrovetenderDruids extends CardImpl {
// <i>Rally</i>-Whenever Grovetender Druids or another Ally you control enters, you may pay {1}. // <i>Rally</i>-Whenever Grovetender Druids or another Ally you control enters, you may pay {1}.
// If you do, create a 1/1 green Plant creature token. // If you do, create a 1/1 green Plant creature token.
this.addAbility(new AllyEntersBattlefieldTriggeredAbility(new DoIfCostPaid( this.addAbility(new AllyEntersBattlefieldTriggeredAbility(new DoIfCostPaid(
new CreateTokenEffect(new GrovetenderDruidsPlantToken()), new GenericManaCost(1) new CreateTokenEffect(new Plant11Token()), new GenericManaCost(1)
), false)); ), false));
} }

View file

@ -0,0 +1,51 @@
package mage.cards.g;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class GurmagRakshasa extends CardImpl {
public GurmagRakshasa(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
this.subtype.add(SubType.DEMON);
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Menace
this.addAbility(new MenaceAbility());
// When this creature enters, target creature an opponent controls gets -2/-2 until end of turn and target creature you control gets +2/+2 until end of turn.
Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(-2, -2));
ability.addTarget(new TargetOpponentsCreaturePermanent());
ability.addEffect(new BoostTargetEffect(2, 2)
.setTargetPointer(new SecondTargetPointer())
.concatBy("and"));
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
private GurmagRakshasa(final GurmagRakshasa card) {
super(card);
}
@Override
public GurmagRakshasa copy() {
return new GurmagRakshasa(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.h;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HumblingElder extends CardImpl {
public HumblingElder(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MONK);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// Flash
this.addAbility(FlashAbility.getInstance());
// When this creature enters, target creature an opponent controls gets -2/-0 until end of turn.
Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(-2, 0));
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
}
private HumblingElder(final HumblingElder card) {
super(card);
}
@Override
public HumblingElder copy() {
return new HumblingElder(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class IceridgeSerpent extends CardImpl {
public IceridgeSerpent(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}");
this.subtype.add(SubType.SERPENT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When this creature enters, return target creature an opponent controls to its owner's hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect());
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
}
private IceridgeSerpent(final IceridgeSerpent card) {
super(card);
}
@Override
public IceridgeSerpent copy() {
return new IceridgeSerpent(this);
}
}

View file

@ -10,7 +10,7 @@ import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.MinionToken2; import mage.game.permanent.token.MinionToken;
import mage.game.permanent.token.Token; import mage.game.permanent.token.Token;
import mage.players.Player; import mage.players.Player;
@ -42,7 +42,7 @@ public final class InfernalGenesis extends CardImpl {
class InfernalGenesisEffect extends OneShotEffect { class InfernalGenesisEffect extends OneShotEffect {
private static final Token token = new MinionToken2(); private static final Token token = new MinionToken();
InfernalGenesisEffect() { InfernalGenesisEffect() {
super(Outcome.PutCreatureInPlay); super(Outcome.PutCreatureInPlay);

View file

@ -0,0 +1,38 @@
package mage.cards.i;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
import mage.abilities.effects.keyword.EndureSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class InspiritedVanguard extends CardImpl {
public InspiritedVanguard(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Whenever this creature enters or attacks, it endures 2.
this.addAbility(new EntersBattlefieldOrAttacksSourceTriggeredAbility(new EndureSourceEffect(2)));
}
private InspiritedVanguard(final InspiritedVanguard card) {
super(card);
}
@Override
public InspiritedVanguard copy() {
return new InspiritedVanguard(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.i;
import mage.MageInt;
import mage.Mana;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class IridescentTiger extends CardImpl {
public IridescentTiger(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
this.subtype.add(SubType.CAT);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// When this creature enters, if you cast it, add {W}{U}{B}{R}{G}.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new BasicManaEffect(new Mana(1, 1, 1, 1, 1, 0, 0, 0))
).withInterveningIf(CastFromEverywhereSourceCondition.instance));
}
private IridescentTiger(final IridescentTiger card) {
super(card);
}
@Override
public IridescentTiger copy() {
return new IridescentTiger(this);
}
}

View file

@ -0,0 +1,42 @@
package mage.cards.k;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.keyword.EndureSourceEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class KinTreeNurturer extends CardImpl {
public KinTreeNurturer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Lifelink
this.addAbility(LifelinkAbility.getInstance());
// When this creature enters, it endures 1.
this.addAbility(new EntersBattlefieldTriggeredAbility(new EndureSourceEffect(1)));
}
private KinTreeNurturer(final KinTreeNurturer card) {
super(card);
}
@Override
public KinTreeNurturer copy() {
return new KinTreeNurturer(this);
}
}

View file

@ -0,0 +1,37 @@
package mage.cards.k;
import mage.abilities.effects.common.DamageWithPowerFromOneToAnotherTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class KnockoutManeuver extends CardImpl {
public KnockoutManeuver(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}");
// Put a +1/+1 counter on target creature you control, then it deals damage equal to its power to target creature an opponent controls.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
this.getSpellAbility().addEffect(new DamageWithPowerFromOneToAnotherTargetEffect(", then it"));
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent());
}
private KnockoutManeuver(final KnockoutManeuver card) {
super(card);
}
@Override
public KnockoutManeuver copy() {
return new KnockoutManeuver(this);
}
}

View file

@ -0,0 +1,87 @@
package mage.cards.k;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.dynamicvalue.common.GetXValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class KotisTheFangkeeper extends CardImpl {
public KotisTheFangkeeper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{G}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.ZOMBIE);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Indestructible
this.addAbility(IndestructibleAbility.getInstance());
// Whenever Kotis deals combat damage to a player, exile the top X cards of their library, where X is the amount of damage dealt. You may cast any number of spells with mana value X or less from among them without paying their mana costs.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(
new KotisTheFangkeeperEffect(), false, true
));
}
private KotisTheFangkeeper(final KotisTheFangkeeper card) {
super(card);
}
@Override
public KotisTheFangkeeper copy() {
return new KotisTheFangkeeper(this);
}
}
class KotisTheFangkeeperEffect extends OneShotEffect {
KotisTheFangkeeperEffect() {
super(Outcome.Benefit);
staticText = "exile the top X cards of their library, where X is the amount of damage dealt. You may " +
"cast any number of spells with mana value X or less from among them without paying their mana costs";
}
private KotisTheFangkeeperEffect(final KotisTheFangkeeperEffect effect) {
super(effect);
}
@Override
public KotisTheFangkeeperEffect copy() {
return new KotisTheFangkeeperEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
int xValue = GetXValue.instance.calculate(game, source, this);
if (controller == null || player == null || xValue < 1) {
return false;
}
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, xValue));
controller.moveCards(cards, Zone.EXILED, source, game);
FilterCard filter = new FilterCard();
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, xValue + 1));
CardUtil.castMultipleWithAttributeForFree(controller, source, game, cards, filter);
return true;
}
}

View file

@ -15,6 +15,7 @@ import mage.abilities.dynamicvalue.common.ManaSpentToCastCount;
import mage.abilities.dynamicvalue.common.GetXValue; import mage.abilities.dynamicvalue.common.GetXValue;
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.CreateTokenEffect;
import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect; import mage.abilities.effects.common.counter.AddCountersTargetEffect;
@ -27,11 +28,10 @@ import mage.constants.SuperType;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.token.MarathWillOfTheWildElementalToken;
import mage.game.permanent.token.Token;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetAnyTarget; import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.game.permanent.token.ElementalXXGreenToken;
import java.util.UUID; import java.util.UUID;
@ -110,12 +110,8 @@ class MarathWillOfTheWildCreateTokenEffect extends OneShotEffect {
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());
if (player != null) { if (player != null) {
int amount = GetXValue.instance.calculate(game, source, this); int xvalue = GetXValue.instance.calculate(game, source, this);
Token token = new MarathWillOfTheWildElementalToken(); return new CreateTokenEffect(new ElementalXXGreenToken(xvalue)).apply(game, source);
token.setPower(amount);
token.setToughness(amount);
token.putOntoBattlefield(1, game, source, source.getControllerId());
return true;
} }
return false; return false;
} }

View file

@ -0,0 +1,54 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MarshalOfTheLost extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_ATTACKING_CREATURES, null);
private static final Hint hint = new ValueHint("Attacking creatures", xValue);
public MarshalOfTheLost(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{B}");
this.subtype.add(SubType.ORC);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// Whenever you attack, target creature gets +X/+X until end of turn, where X is the number of attacking creatures.
Ability ability = new AttacksWithCreaturesTriggeredAbility(new BoostTargetEffect(xValue, xValue), 1);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability.addHint(hint));
}
private MarshalOfTheLost(final MarshalOfTheLost card) {
super(card);
}
@Override
public MarshalOfTheLost copy() {
return new MarshalOfTheLost(this);
}
}

View file

@ -1,13 +1,12 @@
package mage.cards.m; package mage.cards.m;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility; import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect; import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -20,6 +19,8 @@ import mage.players.Player;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.target.targetpointer.FixedTargets; import mage.target.targetpointer.FixedTargets;
import java.util.UUID;
/** /**
* *
* @author LevelX2 * @author LevelX2
@ -75,20 +76,15 @@ class MirrorMatchEffect extends OneShotEffect {
effect.setTargetPointer(new FixedTarget(attacker, game)); effect.setTargetPointer(new FixedTarget(attacker, game));
effect.apply(game, source); effect.apply(game, source);
CombatGroup group = game.getCombat().findGroup(attacker.getId()); CombatGroup group = game.getCombat().findGroup(attacker.getId());
boolean isCreature = false;
if (group != null) { if (group != null) {
for (Permanent addedToken : effect.getAddedPermanents()) { for (Permanent addedToken : effect.getAddedPermanents()) {
if (addedToken.isCreature(game)) { if (addedToken.isCreature(game)) {
group.addBlockerToGroup(addedToken.getId(), attackerId, game); group.addBlockerToGroup(addedToken.getId(), attackerId, game);
isCreature = true;
} }
} }
ExileTargetEffect exileEffect = new ExileTargetEffect("Exile those tokens at end of combat"); ExileTargetEffect exileEffect = new ExileTargetEffect("Exile those tokens at end of combat");
exileEffect.setTargetPointer(new FixedTargets(effect.getAddedPermanents(), game)); exileEffect.setTargetPointer(new FixedTargets(effect.getAddedPermanents(), game));
game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source); game.addDelayedTriggeredAbility(new AtTheEndOfCombatDelayedTriggeredAbility(exileEffect), source);
if (isCreature) {
group.pickBlockerOrder(attacker.getControllerId(), game);
}
} }
} }
} }

View file

@ -0,0 +1,40 @@
package mage.cards.m;
import mage.abilities.common.PayMoreToCastAsThoughtItHadFlashAbility;
import mage.abilities.costs.common.BeholdDragonCost;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreatureOrPlaneswalker;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MoltenExhale extends CardImpl {
public MoltenExhale(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{R}");
// You may cast this spell as though it had flash if you behold a Dragon as an additional cost to cast it.
this.addAbility(new PayMoreToCastAsThoughtItHadFlashAbility(
this, new BeholdDragonCost(), "you may cast this spell as though " +
"it had flash if you behold a Dragon as an additional cost to cast it"
));
// Molten Exhale deals 4 damage to target creature or planeswalker.
this.getSpellAbility().addEffect(new DamageTargetEffect(4));
this.getSpellAbility().addTarget(new TargetCreatureOrPlaneswalker());
}
private MoltenExhale(final MoltenExhale card) {
super(card);
}
@Override
public MoltenExhale copy() {
return new MoltenExhale(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.n;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.keyword.SurveilEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.MobilizeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class NightbladeBrigade extends CardImpl {
public NightbladeBrigade(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// Mobilize 1
this.addAbility(new MobilizeAbility(1));
// When this creature enters, surveil 1.
this.addAbility(new EntersBattlefieldTriggeredAbility(new SurveilEffect(1)));
}
private NightbladeBrigade(final NightbladeBrigade card) {
super(card);
}
@Override
public NightbladeBrigade copy() {
return new NightbladeBrigade(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.o;
import mage.abilities.Mode;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class OverwhelmingSurge extends CardImpl {
public OverwhelmingSurge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{R}");
// Choose one or both --
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(2);
// * Overwhelming Surge deals 3 damage to target creature.
this.getSpellAbility().addEffect(new DamageTargetEffect(3));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// * Destroy target noncreature artifact.
this.getSpellAbility().addMode(new Mode(new DestroyTargetEffect())
.addTarget(new TargetPermanent(StaticFilters.FILTER_ARTIFACT_NON_CREATURE)));
}
private OverwhelmingSurge(final OverwhelmingSurge card) {
super(card);
}
@Override
public OverwhelmingSurge copy() {
return new OverwhelmingSurge(this);
}
}

View file

@ -8,6 +8,7 @@ import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -15,7 +16,7 @@ import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.token.MinionToken; import mage.game.permanent.token.PhyrexianMinionToken;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
@ -110,12 +111,8 @@ class PhyrexianProcessorCreateTokenEffect extends OneShotEffect {
String key = CardUtil.getCardZoneString("lifePaid", source.getSourceId(), game, true); String key = CardUtil.getCardZoneString("lifePaid", source.getSourceId(), game, true);
Object object = game.getState().getValue(key); Object object = game.getState().getValue(key);
if (object instanceof Integer) { if (object instanceof Integer) {
int lifePaid = (int) object; int xvalue = (int) object;
MinionToken token = new MinionToken(); return new CreateTokenEffect(new PhyrexianMinionToken(xvalue)).apply(game, source);
token.setPower(lifePaid);
token.setToughness(lifePaid);
token.putOntoBattlefield(1, game, source, source.getControllerId());
return true;
} }
return false; return false;
} }

View file

@ -0,0 +1,43 @@
package mage.cards.p;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.FlurryAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class PoisedPractitioner extends CardImpl {
public PoisedPractitioner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MONK);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Flurry -- Whenever you cast your second spell each turn, put a +1/+1 counter on this creature. Scry 1.
Ability ability = new FlurryAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()));
ability.addEffect(new ScryEffect(1));
this.addAbility(ability);
}
private PoisedPractitioner(final PoisedPractitioner card) {
super(card);
}
@Override
public PoisedPractitioner copy() {
return new PoisedPractitioner(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.r;
import mage.MageInt;
import mage.Mana;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue;
import mage.abilities.effects.common.MillCardsControllerEffect;
import mage.abilities.mana.DynamicManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RainveilRejuvenator extends CardImpl {
public RainveilRejuvenator(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.ELEPHANT);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// When this creature enters, you may mill three cards.
this.addAbility(new EntersBattlefieldTriggeredAbility(new MillCardsControllerEffect(3), true));
// {T}: Add an amount of {G} equal to this creature's power.
this.addAbility(new DynamicManaAbility(
Mana.GreenMana(1), SourcePermanentPowerValue.NOT_NEGATIVE, "Add an amount of {G} equal to {this}'s power."
));
}
private RainveilRejuvenator(final RainveilRejuvenator card) {
super(card);
}
@Override
public RainveilRejuvenator copy() {
return new RainveilRejuvenator(this);
}
}

View file

@ -12,7 +12,7 @@ import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.RallyTheHordeWarriorToken; import mage.game.permanent.token.RedWarriorToken;
import mage.players.Player; import mage.players.Player;
/** /**
@ -72,7 +72,7 @@ class RallyTheHordeEffect extends OneShotEffect {
nonLandCardsExiled += nonLands; nonLandCardsExiled += nonLands;
} }
} }
return new CreateTokenEffect(new RallyTheHordeWarriorToken(), nonLandCardsExiled).apply(game, source); return new CreateTokenEffect(new RedWarriorToken(), nonLandCardsExiled).apply(game, source);
} }
return false; return false;

View file

@ -0,0 +1,86 @@
package mage.cards.r;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RediscoverTheWay extends CardImpl {
public RediscoverTheWay(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{R}{W}");
this.subtype.add(SubType.SAGA);
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
SagaAbility sagaAbility = new SagaAbility(this);
// I, II -- Look at the top three cards of your library. Put one of them into your hand and the rest on the bottom of your library in any order.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II,
new LookLibraryAndPickControllerEffect(3, 1, PutCards.HAND, PutCards.BOTTOM_ANY)
);
// III -- Whenever you cast a noncreature spell this turn, target creature you control gains double strike until end of turn.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_III,
new CreateDelayedTriggeredAbilityEffect(new RediscoverTheWayTriggeredAbility())
);
this.addAbility(sagaAbility);
}
private RediscoverTheWay(final RediscoverTheWay card) {
super(card);
}
@Override
public RediscoverTheWay copy() {
return new RediscoverTheWay(this);
}
}
class RediscoverTheWayTriggeredAbility extends DelayedTriggeredAbility {
RediscoverTheWayTriggeredAbility() {
super(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance()), Duration.EndOfTurn, false, false);
this.addTarget(new TargetControlledCreaturePermanent());
this.setTriggerPhrase("Whenever you cast a noncreature spell this turn, ");
}
private RediscoverTheWayTriggeredAbility(final RediscoverTheWayTriggeredAbility ability) {
super(ability);
}
@Override
public RediscoverTheWayTriggeredAbility copy() {
return new RediscoverTheWayTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!isControlledBy(event.getPlayerId())) {
return false;
}
Spell spell = game.getSpell(event.getTargetId());
return spell != null && !spell.isCreature(game);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.r;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldOrDiesSourceTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ReputableMerchant extends CardImpl {
public ReputableMerchant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2/W}{2/B}{2/G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CITIZEN);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When this creature enters or dies, put a +1/+1 counter on target creature you control.
Ability ability = new EntersBattlefieldOrDiesSourceTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false
);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
}
private ReputableMerchant(final ReputableMerchant card) {
super(card);
}
@Override
public ReputableMerchant copy() {
return new ReputableMerchant(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.r;
import mage.MageInt;
import mage.abilities.common.BecomesTappedSourceTriggeredAbility;
import mage.abilities.costs.common.DiscardCardCost;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RescueLeopard extends CardImpl {
public RescueLeopard(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.CAT);
this.power = new MageInt(4);
this.toughness = new MageInt(2);
// Whenever this creature becomes tapped, you may discard a card. If you do, draw a card.
this.addAbility(new BecomesTappedSourceTriggeredAbility(
new DoIfCostPaid(new DrawCardSourceControllerEffect(1), new DiscardCardCost())
));
}
private RescueLeopard(final RescueLeopard card) {
super(card);
}
@Override
public RescueLeopard copy() {
return new RescueLeopard(this);
}
}

View file

@ -0,0 +1,70 @@
package mage.cards.r;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.counter.DistributeCountersEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.permanent.token.NoFlyingSpiritWhiteToken;
import mage.target.common.TargetCreaturePermanentAmount;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RevivalOfTheAncestors extends CardImpl {
public RevivalOfTheAncestors(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{B}{G}");
this.subtype.add(SubType.SAGA);
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
SagaAbility sagaAbility = new SagaAbility(this);
// I -- Create three 1/1 white Spirit creature tokens.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I,
new CreateTokenEffect(new NoFlyingSpiritWhiteToken(), 3)
);
// II -- Distribute three +1/+1 counters among one, two, or three target creatures you control.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_II,
new DistributeCountersEffect(CounterType.P1P1),
new TargetCreaturePermanentAmount(3)
);
// III -- Creatures you control gain trample and lifelink until end of turn.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_III,
new GainAbilityControlledEffect(
TrampleAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_PERMANENT_CREATURE
).setText("creatures you control gain trample"),
new GainAbilityControlledEffect(
LifelinkAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_PERMANENT_CREATURE
).setText("and lifelink until end of turn"));
this.addAbility(sagaAbility);
}
private RevivalOfTheAncestors(final RevivalOfTheAncestors card) {
super(card);
}
@Override
public RevivalOfTheAncestors copy() {
return new RevivalOfTheAncestors(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.r;
import mage.abilities.Mode;
import mage.abilities.effects.common.CounterTargetEffect;
import mage.abilities.effects.common.PutOnTopOrBottomLibraryTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.target.TargetSpell;
import mage.target.common.TargetNonlandPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class RiverwalkTechnique extends CardImpl {
public RiverwalkTechnique(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{U}");
// Choose one --
// * The owner of target nonland permanent puts it on their choice of the top or bottom of their library.
this.getSpellAbility().addEffect(new PutOnTopOrBottomLibraryTargetEffect(true));
this.getSpellAbility().addTarget(new TargetNonlandPermanent());
// * Counter target noncreature spell.
this.getSpellAbility().addMode(new Mode(new CounterTargetEffect())
.addTarget(new TargetSpell(StaticFilters.FILTER_SPELL_NON_CREATURE)));
}
private RiverwalkTechnique(final RiverwalkTechnique card) {
super(card);
}
@Override
public RiverwalkTechnique copy() {
return new RiverwalkTechnique(this);
}
}

View file

@ -0,0 +1,51 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.RenewAbility;
import mage.abilities.effects.common.DoubleCountersTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SageOfTheFang extends CardImpl {
public SageOfTheFang(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When this creature enters, put a +1/+1 counter on target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// Renew -- {3}{G}, Exile this card from your graveyard: Put a +1/+1 counter on target creature, then double the number of +1/+1 counters on that creature.
ability = new RenewAbility("{3}{G}", CounterType.P1P1.createInstance());
ability.addEffect(new DoubleCountersTargetEffect(CounterType.P1P1)
.setText(", then double the number of +1/+1 counters on that creature"));
this.addAbility(ability);
}
private SageOfTheFang(final SageOfTheFang card) {
super(card);
}
@Override
public SageOfTheFang copy() {
return new SageOfTheFang(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.RenewAbility;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SaguPummeler extends CardImpl {
public SaguPummeler(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Reach
this.addAbility(ReachAbility.getInstance());
// Renew -- {4}{G}, Exile this card from your graveyard: Put two +1/+1 counters and a reach counter on target creature. Activate only as a sorcery.
this.addAbility(new RenewAbility(
"{4}{G}",
CounterType.P1P1.createInstance(2),
CounterType.REACH.createInstance()
));
}
private SaguPummeler(final SaguPummeler card) {
super(card);
}
@Override
public SaguPummeler copy() {
return new SaguPummeler(this);
}
}

View file

@ -0,0 +1,73 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.token.RedWarriorToken;
import mage.game.permanent.token.Token;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTargets;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SaltRoadSkirmish extends CardImpl {
public SaltRoadSkirmish(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}");
// Destroy target creature. Create two 1/1 red Warrior creature tokens. They gain haste until end of turn. Sacrifice them at the beginning of the next end step.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new SaltRoadSkirmishEffect());
}
private SaltRoadSkirmish(final SaltRoadSkirmish card) {
super(card);
}
@Override
public SaltRoadSkirmish copy() {
return new SaltRoadSkirmish(this);
}
}
class SaltRoadSkirmishEffect extends OneShotEffect {
SaltRoadSkirmishEffect() {
super(Outcome.Benefit);
staticText = "";
}
private SaltRoadSkirmishEffect(final SaltRoadSkirmishEffect effect) {
super(effect);
}
@Override
public SaltRoadSkirmishEffect copy() {
return new SaltRoadSkirmishEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Token token = new RedWarriorToken();
token.putOntoBattlefield(2, game, source);
game.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance())
.setTargetPointer(new FixedTargets(token, game)), source);
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new SacrificeTargetEffect("sacrifice them").setTargetPointer(new FixedTargets(token, game))
), source);
return true;
}
}

View file

@ -0,0 +1,42 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.keyword.EndureSourceEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SandskitterOutrider extends CardImpl {
public SandskitterOutrider(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Menace
this.addAbility(new MenaceAbility());
// When this creature enters, it endures 2.
this.addAbility(new EntersBattlefieldTriggeredAbility(new EndureSourceEffect(2)));
}
private SandskitterOutrider(final SandskitterOutrider card) {
super(card);
}
@Override
public SandskitterOutrider copy() {
return new SandskitterOutrider(this);
}
}

View file

@ -0,0 +1,69 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.common.BeholdDragonCost;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.continuous.AddCardSubTypeSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.game.permanent.token.TreasureToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SarkhanDragonAscendant extends CardImpl {
private static final FilterPermanent filter = new FilterControlledPermanent(SubType.DRAGON, "a Dragon you control");
public SarkhanDragonAscendant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.DRUID);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Sarkhan enters, you may behold a Dragon. If you do, create a Treasure token.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new DoIfCostPaid(new CreateTokenEffect(new TreasureToken()), new BeholdDragonCost())
));
// Whenever a Dragon you control enters, put a +1/+1 counter on Sarkhan. Until end of turn, Sarkhan becomes a Dragon in addition to its other types and gains flying.
Ability ability = new EntersBattlefieldAllTriggeredAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), filter
);
ability.addEffect(new AddCardSubTypeSourceEffect(
Duration.EndOfTurn, SubType.DRAGON
).setText("until end of turn, {this} becomes a Dragon in addition to its other types"));
ability.addEffect(new GainAbilitySourceEffect(
FlyingAbility.getInstance(), Duration.EndOfTurn
).setText("and gains flying"));
this.addAbility(ability);
}
private SarkhanDragonAscendant(final SarkhanDragonAscendant card) {
super(card);
}
@Override
public SarkhanDragonAscendant copy() {
return new SarkhanDragonAscendant(this);
}
}

View file

@ -14,7 +14,7 @@ import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.SeedGuardianToken; import mage.game.permanent.token.ElementalXXGreenToken;
import mage.players.Player; import mage.players.Player;
/** /**
@ -66,7 +66,7 @@ class SeedGuardianEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
int creaturesInGraveyard = controller.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game); int creaturesInGraveyard = controller.getGraveyard().count(StaticFilters.FILTER_CARD_CREATURE, game);
return new CreateTokenEffect(new SeedGuardianToken(creaturesInGraveyard)).apply(game, source); return new CreateTokenEffect(new ElementalXXGreenToken(creaturesInGraveyard)).apply(game, source);
} }
return false; return false;
} }

View file

@ -0,0 +1,41 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.PutCards;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SibsigAppraiser extends CardImpl {
public SibsigAppraiser(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.ZOMBIE);
this.subtype.add(SubType.ADVISOR);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// When this creature enters, look at the top two cards of your library. Put one of them into your hand and the other into your graveyard.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
2, 1, PutCards.HAND, PutCards.GRAVEYARD
)));
}
private SibsigAppraiser(final SibsigAppraiser card) {
super(card);
}
@Override
public SibsigAppraiser copy() {
return new SibsigAppraiser(this);
}
}

View file

@ -0,0 +1,56 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
import mage.abilities.effects.common.continuous.SetBasePowerToughnessSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SnowmeltStag extends CardImpl {
public SnowmeltStag(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.ELEMENTAL);
this.subtype.add(SubType.ELK);
this.power = new MageInt(2);
this.toughness = new MageInt(5);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// During your turn, this creature has base power and toughness 5/2.
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new SetBasePowerToughnessSourceEffect(5, 2, Duration.WhileOnBattlefield),
MyTurnCondition.instance, "during your turn, this creature has base power and toughness 5/2"
)));
// {5}{U}{U}: This creature can't be blocked this turn.
this.addAbility(new SimpleActivatedAbility(
new CantBeBlockedSourceEffect(Duration.EndOfTurn), new ManaCostsImpl<>("{5}{U}{U}")
));
}
private SnowmeltStag(final SnowmeltStag card) {
super(card);
}
@Override
public SnowmeltStag copy() {
return new SnowmeltStag(this);
}
}

View file

@ -0,0 +1,80 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.HarmonizeAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SongcrafterMage extends CardImpl {
public SongcrafterMage(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{U}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.BARD);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Flash
this.addAbility(FlashAbility.getInstance());
// When this creature enters, target instant or sorcery card in your graveyard gains harmonize until end of turn. Its harmonize cost is equal to its mana cost.
Ability ability = new EntersBattlefieldTriggeredAbility(new SongcrafterMageEffect());
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY_FROM_YOUR_GRAVEYARD));
this.addAbility(ability);
}
private SongcrafterMage(final SongcrafterMage card) {
super(card);
}
@Override
public SongcrafterMage copy() {
return new SongcrafterMage(this);
}
}
class SongcrafterMageEffect extends ContinuousEffectImpl {
SongcrafterMageEffect() {
super(Duration.EndOfTurn, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.staticText = "target instant or sorcery card in your graveyard gains harmonize until end of turn. " +
"The harmonize cost is equal to its mana cost";
}
private SongcrafterMageEffect(final SongcrafterMageEffect effect) {
super(effect);
}
@Override
public SongcrafterMageEffect copy() {
return new SongcrafterMageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(getTargetPointer().getFirst(game, source));
if (card == null) {
return false;
}
Ability ability = new HarmonizeAbility(card, card.getManaCost().getText());
ability.setSourceId(card.getId());
ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(card, ability);
return true;
}
}

View file

@ -0,0 +1,93 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class SonicShrieker extends CardImpl {
public SonicShrieker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{W}{B}");
this.subtype.add(SubType.DRAGON);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Flying
this.addAbility(FlyingAbility.getInstance());
// When this creature enters, it deals 2 damage to any target and you gain 2 life. If a player is dealt damage this way, they discard a card.
Ability ability = new EntersBattlefieldTriggeredAbility(new SonicShriekerEffect());
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
private SonicShrieker(final SonicShrieker card) {
super(card);
}
@Override
public SonicShrieker copy() {
return new SonicShrieker(this);
}
}
class SonicShriekerEffect extends OneShotEffect {
SonicShriekerEffect() {
super(Outcome.Benefit);
staticText = "it deals 2 damage to any target and you gain 2 life. " +
"If a player is dealt damage this way, they discard a card";
}
private SonicShriekerEffect(final SonicShriekerEffect effect) {
super(effect);
}
@Override
public SonicShriekerEffect copy() {
return new SonicShriekerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = dealDamage(getTargetPointer().getFirst(game, source), game, source);
Optional.ofNullable(source.getControllerId())
.map(game::getPlayer)
.ifPresent(controller -> controller.gainLife(2, game, source));
if (player != null) {
player.discard(1, false, false, source, game);
}
return true;
}
private static Player dealDamage(UUID targetId, Game game, Ability source) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.damage(2, source, game);
return null;
}
Player player = game.getPlayer(targetId);
if (player != null && player.damage(2, source, game) > 0) {
return player;
}
return null;
}
}

View file

@ -17,7 +17,7 @@ import mage.constants.Duration;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.command.emblems.SorinSolemnVisitorEmblem; import mage.game.command.emblems.SorinSolemnVisitorEmblem;
import mage.game.permanent.token.SorinSolemnVisitorVampireToken; import mage.game.permanent.token.VampireToken;
/** /**
* *
@ -42,7 +42,7 @@ public final class SorinSolemnVisitor extends CardImpl {
this.addAbility(loyaltyAbility); this.addAbility(loyaltyAbility);
// -2: Create a 2/2 black Vampire creature token with flying. // -2: Create a 2/2 black Vampire creature token with flying.
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new SorinSolemnVisitorVampireToken()), -2)); this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new VampireToken()), -2));
// -6: You get an emblem with "At the beginning of each opponent's upkeep, that player sacrifices a creature." // -6: You get an emblem with "At the beginning of each opponent's upkeep, that player sacrifices a creature."
this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new SorinSolemnVisitorEmblem()), -6)); this.addAbility(new LoyaltyAbility(new GetEmblemEffect(new SorinSolemnVisitorEmblem()), -6));

View file

@ -176,14 +176,8 @@ class SorrowsPathSwitchBlockersEffect extends OneShotEffect {
group.addBlockerToGroup(blocker.getId(), blocker.getControllerId(), game); group.addBlockerToGroup(blocker.getId(), blocker.getControllerId(), game);
game.getCombat().addBlockingGroup(blocker.getId(), attacker.getId(), blocker.getControllerId(), game); game.getCombat().addBlockingGroup(blocker.getId(), attacker.getId(), blocker.getControllerId(), game);
game.fireEvent(new BlockerDeclaredEvent(attacker.getId(), blocker.getId(), blocker.getControllerId())); game.fireEvent(new BlockerDeclaredEvent(attacker.getId(), blocker.getId(), blocker.getControllerId()));
group.pickBlockerOrder(attacker.getControllerId(), game);
} }
} }
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, blocker.getId(), source, null)); game.fireEvent(GameEvent.getEvent(GameEvent.EventType.CREATURE_BLOCKS, blocker.getId(), source, null));
CombatGroup blockGroup = findBlockingGroup(blocker, game); // a new blockingGroup is formed, so it's necessary to find it again
if (blockGroup != null) {
blockGroup.pickAttackerOrder(blocker.getControllerId(), game);
}
} }
} }

View file

@ -12,7 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.SpoilsOfBloodHorrorToken; import mage.game.permanent.token.HorrorXXBlackToken;
import mage.players.Player; import mage.players.Player;
/** /**
@ -54,7 +54,7 @@ class SpoilsOfBloodEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller != null) {
new CreateTokenEffect( new CreateTokenEffect(
new SpoilsOfBloodHorrorToken(CreaturesDiedThisTurnCount.instance.calculate(game, source, this))) new HorrorXXBlackToken(CreaturesDiedThisTurnCount.instance.calculate(game, source, this)))
.apply(game, source); .apply(game, source);
return true; return true;
} }

View file

@ -0,0 +1,52 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.MobilizeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class StadiumHeadliner extends CardImpl {
public StadiumHeadliner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Mobilize 1
this.addAbility(new MobilizeAbility(1));
// {1}{R}, Sacrifice this creature: It deals damage equal to the number of creatures you control to target creature.
Ability ability = new SimpleActivatedAbility(new DamageTargetEffect(
SourcePermanentPowerValue.NOT_NEGATIVE, "it"
), new ManaCostsImpl<>("{1}{R}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
private StadiumHeadliner(final StadiumHeadliner card) {
super(card);
}
@Override
public StadiumHeadliner copy() {
return new StadiumHeadliner(this);
}
}

View file

@ -0,0 +1,55 @@
package mage.cards.s;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.ExileUntilSourceLeavesEffect;
import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class StaticSnare extends CardImpl {
private static final DynamicValue xValue = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_ATTACKING_CREATURE);
private static final Hint hint = new ValueHint("Attacking creatures", xValue);
public StaticSnare(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{W}");
// Flash
this.addAbility(FlashAbility.getInstance());
// This spell costs {1} less to cast for each attacking creature.
this.addAbility(new SimpleStaticAbility(
Zone.ALL, new SpellCostReductionForEachSourceEffect(1, xValue)
).addHint(hint));
// When this enchantment enters, exile target artifact or creature an opponent controls until this enchantment leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new ExileUntilSourceLeavesEffect());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_OPPONENTS_PERMANENT_ARTIFACT_OR_CREATURE));
this.addAbility(ability);
}
private StaticSnare(final StaticSnare card) {
super(card);
}
@Override
public StaticSnare copy() {
return new StaticSnare(this);
}
}

View file

@ -0,0 +1,57 @@
package mage.cards.s;
import mage.abilities.common.AttacksAttachedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class StormbeaconBlade extends CardImpl {
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
StaticFilters.FILTER_ATTACKING_CREATURE,
ComparisonType.MORE_THAN, 2, true
);
public StormbeaconBlade(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}{W}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +3/+0.
this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(3, 0)));
// Whenever equipped creature attacks, draw a card if you control three or more attacking creatures.
this.addAbility(new AttacksAttachedTriggeredAbility(new ConditionalOneShotEffect(
new DrawCardSourceControllerEffect(1), condition,
"draw a card if you control three or more attacking creatures"
), AttachmentType.EQUIPMENT, false));
// Equip {2}
this.addAbility(new EquipAbility(2));
}
private StormbeaconBlade(final StormbeaconBlade card) {
super(card);
}
@Override
public StormbeaconBlade copy() {
return new StormbeaconBlade(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.t;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.ReturnToHandSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.game.permanent.token.Soldier22Token;
import java.util.UUID;
/**
* @author PurpleCrowbar
*/
public final class TeemingDragonstorm extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.DRAGON, "a Dragon");
public TeemingDragonstorm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
// When this enchantment enters, create two 2/2 white Soldier creature tokens.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new Soldier22Token(), 2), false));
// When a Dragon you control enters, return this enchantment to its owner's hand.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new ReturnToHandSourceEffect(), filter));
}
private TeemingDragonstorm (final TeemingDragonstorm card) {
super(card);
}
@Override
public TeemingDragonstorm copy() {
return new TeemingDragonstorm(this);
}
}

View file

@ -0,0 +1,47 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.CardsLeaveGraveyardTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.permanent.token.TreasureToken;
import mage.game.permanent.token.ZombieDruidToken;
import java.util.UUID;
/**
* @author PurpleCrowbar
*/
public final class TevalsJudgment extends CardImpl {
public TevalsJudgment(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
// Whenever one or more cards leave your graveyard, choose one that hasnt been chosen this turn --
// * Draw a card.
Ability ability = new CardsLeaveGraveyardTriggeredAbility(
new DrawCardSourceControllerEffect(1)
);
ability.getModes().setLimitUsageByOnce(true);
// * Create a Treasure token.
ability.addMode(new Mode(new CreateTokenEffect(new TreasureToken())));
// * Create a 2/2 black Zombie Druid creature token.
ability.addMode(new Mode(new CreateTokenEffect(new ZombieDruidToken())));
this.addAbility(ability);
}
private TevalsJudgment(final TevalsJudgment card) {
super(card);
}
@Override
public TevalsJudgment copy() {
return new TevalsJudgment(this);
}
}

View file

@ -0,0 +1,141 @@
package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.continuous.MaximumHandSizeControllerEffect;
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author padfoothelix
*/
public final class TheSecondDoctor extends CardImpl {
public TheSecondDoctor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}{U}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.TIME_LORD);
this.subtype.add(SubType.DOCTOR);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// Players have no maximum hand size.
this.addAbility(new SimpleStaticAbility(new MaximumHandSizeControllerEffect(
Integer.MAX_VALUE, Duration.WhileOnBattlefield,
MaximumHandSizeControllerEffect.HandSizeModification.SET, TargetController.ANY
)));
// How Civil of You -- At the beginning of your end step, each player may draw a card. Each opponent who does can't attack you or permanents you control during their next turn.
this.addAbility(new BeginningOfEndStepTriggeredAbility(
new TheSecondDoctorEffect()).withFlavorWord("How Civil of You"));
}
private TheSecondDoctor(final TheSecondDoctor card) {
super(card);
}
@Override
public TheSecondDoctor copy() {
return new TheSecondDoctor(this);
}
}
class TheSecondDoctorEffect extends OneShotEffect {
TheSecondDoctorEffect() {
super(Outcome.Benefit);
this.staticText = "each player may draw a card. Each opponent who does can't attack you or permanents you control during their next turn.";
}
private TheSecondDoctorEffect(final TheSecondDoctorEffect effect) {
super(effect);
}
@Override
public TheSecondDoctorEffect copy() {
return new TheSecondDoctorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null
&& player.chooseUse(Outcome.DrawCard, "Draw a card ?", source, game)
&& player.drawCards(1, source, game) > 0
&& game.getOpponents(controller.getId()).contains(playerId)) {
RestrictionEffect effect = new TheSecondDoctorCantAttackEffect(player.getId());
game.addEffect(effect, source);
}
}
return true;
}
}
class TheSecondDoctorCantAttackEffect extends RestrictionEffect {
private final UUID opponentId;
public TheSecondDoctorCantAttackEffect(UUID opponentId) {
super(Duration.UntilEndOfYourNextTurn);
this.opponentId = opponentId;
staticText = "";
}
private TheSecondDoctorCantAttackEffect(final TheSecondDoctorCantAttackEffect effect) {
super(effect);
this.opponentId = effect.opponentId;
}
@Override
public TheSecondDoctorCantAttackEffect copy() {
return new TheSecondDoctorCantAttackEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
if (opponentId != null) {
setStartingControllerAndTurnNum(game, opponentId, game.getActivePlayerId());
} else {
discard();
}
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
return game.isActivePlayer(opponentId);
}
@Override
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game, boolean canUseChooseDialogs) {
UUID controllerId = source.getControllerId();
// defender is null
if (defenderId == null) {
return true;
}
// defender is a permanent
Permanent defender = game.getPermanent(defenderId);
if (defender != null) {
return !defender.isControlledBy(controllerId);
}
// defender is a player
return !defenderId.equals(controllerId);
}
}

View file

@ -0,0 +1,77 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAllTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SetTargetPointer;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.ZombieDruidToken;
import mage.game.stack.Spell;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class TheSibsigCeremony extends CardImpl {
private static final FilterCard filter = new FilterCreatureCard("creature spells");
private static final FilterPermanent filter2 = new FilterControlledCreaturePermanent();
static {
filter2.add(TheSibsigCeremonyPredicate.instance);
}
public TheSibsigCeremony(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}{B}{B}");
this.supertype.add(SuperType.LEGENDARY);
// Creature spells you cast cost {2} less to cast.
this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 2)));
// Whenever a creature you control enters, if you cast it, destroy that creature, then create a 2/2 black Zombie Druid creature token.
Ability ability = new EntersBattlefieldAllTriggeredAbility(
Zone.BATTLEFIELD, new DestroyTargetEffect()
.setText("if you cast it, destroy that creature"),
filter2, false, SetTargetPointer.PERMANENT
);
ability.addEffect(new CreateTokenEffect(new ZombieDruidToken()).concatBy(", then"));
this.addAbility(ability);
}
private TheSibsigCeremony(final TheSibsigCeremony card) {
super(card);
}
@Override
public TheSibsigCeremony copy() {
return new TheSibsigCeremony(this);
}
}
enum TheSibsigCeremonyPredicate implements Predicate<Permanent> {
instance;
@Override
public boolean apply(Permanent input, Game game) {
int zcc = input.getZoneChangeCounter(game);
Spell spell = game.getStack().getSpell(input.getId());
return (spell != null && spell.getZoneChangeCounter(game) == zcc - 1)
|| game.getLastKnownInformation(input.getId(), Zone.STACK, zcc - 1) != null;
}
}

View file

@ -0,0 +1,108 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ShuffleIntoLibraryTargetEffect;
import mage.cards.*;
import mage.choices.FaceVillainousChoice;
import mage.choices.VillainousChoice;
import mage.constants.*;
import mage.game.Game;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author padfoothelix
*/
public final class ThisIsHowItEnds extends CardImpl {
public ThisIsHowItEnds(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{B}");
// Target creature's owner shuffles it into their library, then faces a villainous choice -- They lose 5 life, or they shuffle another creature they own into their library.
this.getSpellAbility().addEffect(
new ShuffleIntoLibraryTargetEffect()
.setText("target creature's owner shuffles it into their library,")
);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new ThisIsHowItEndsEffect());
}
private ThisIsHowItEnds(final ThisIsHowItEnds card) {
super(card);
}
@Override
public ThisIsHowItEnds copy() {
return new ThisIsHowItEnds(this);
}
}
class ThisIsHowItEndsEffect extends OneShotEffect {
private static final FaceVillainousChoice choice = new FaceVillainousChoice(
Outcome.Removal, new ThisIsHowItEndsFirstChoice(), new ThisIsHowItEndsSecondChoice()
);
ThisIsHowItEndsEffect() {
super(Outcome.Benefit);
staticText = "then " + choice.generateRule();
}
private ThisIsHowItEndsEffect(final ThisIsHowItEndsEffect effect) {
super(effect);
}
@Override
public ThisIsHowItEndsEffect copy() {
return new ThisIsHowItEndsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
UUID targetOwnerId = game.getOwnerId(getTargetPointer().getFirst(game, source));
Player targetOwner = game.getPlayer(targetOwnerId);
choice.faceChoice(targetOwner, game, source);
return true;
}
}
class ThisIsHowItEndsFirstChoice extends VillainousChoice {
ThisIsHowItEndsFirstChoice() {
super("They lose 5 life","You lose 5 life");
}
@Override
public boolean doChoice(Player player, Game game, Ability source) {
player.loseLife(5, game, source, false);
return true;
}
}
class ThisIsHowItEndsSecondChoice extends VillainousChoice {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you own");
static {
filter.add(TargetController.YOU.getOwnerPredicate());
}
ThisIsHowItEndsSecondChoice() {
super("they shuffle another creature they own into their library", "you shuffle a creature you own into your library");
}
@Override
public boolean doChoice(Player player, Game game, Ability source) {
TargetCreaturePermanent target = new TargetCreaturePermanent(1, 1, filter, true);
target.withChooseHint("to shuffle into your library");
player.chooseTarget(Outcome.Detriment, target, source, game);
Cards cards = new CardsImpl(target.getTargets());
player.shuffleCardsToLibrary(cards, game, source);
return true;
}
}

View file

@ -0,0 +1,83 @@
package mage.cards.t;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.common.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ThunderOfUnity extends CardImpl {
public ThunderOfUnity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{W}{B}");
this.subtype.add(SubType.SAGA);
// (As this Saga enters step, add a lore counter. Sacrifice after III.)
SagaAbility sagaAbility = new SagaAbility(this);
// I -- You draw two cards and you lose 2 life.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I,
new DrawCardSourceControllerEffect(2, true),
new LoseLifeSourceControllerEffect(2).concatBy("and")
);
// II, III -- Whenever a creature you control enters this turn, each opponent loses 1 life and you gain 1 life.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_II, SagaChapter.CHAPTER_III,
new CreateDelayedTriggeredAbilityEffect(new ThunderOfUnityTriggeredAbility())
);
this.addAbility(sagaAbility);
}
private ThunderOfUnity(final ThunderOfUnity card) {
super(card);
}
@Override
public ThunderOfUnity copy() {
return new ThunderOfUnity(this);
}
}
class ThunderOfUnityTriggeredAbility extends DelayedTriggeredAbility {
ThunderOfUnityTriggeredAbility() {
super(new LoseLifeOpponentsEffect(1), Duration.EndOfTurn, false, false);
this.addEffect(new GainLifeEffect(1).concatBy("and"));
this.setTriggerPhrase("Whenever a creature you control enters this turn, ");
}
private ThunderOfUnityTriggeredAbility(final ThunderOfUnityTriggeredAbility ability) {
super(ability);
}
@Override
public ThunderOfUnityTriggeredAbility copy() {
return new ThunderOfUnityTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
return permanent != null && permanent.isCreature(game) && permanent.isControlledBy(getControllerId());
}
}

View file

@ -0,0 +1,84 @@
package mage.cards.t;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.CounterAnyPredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.Optional;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class TradeRouteEnvoy extends CardImpl {
public TradeRouteEnvoy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.DOG);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// When this creature enters, draw a card if you control a creature with a counter on it. If you don't draw a card this way, put a +1/+1 counter on this creature.
this.addAbility(new EntersBattlefieldTriggeredAbility(new TradeRouteEnvoyEffect()));
}
private TradeRouteEnvoy(final TradeRouteEnvoy card) {
super(card);
}
@Override
public TradeRouteEnvoy copy() {
return new TradeRouteEnvoy(this);
}
}
class TradeRouteEnvoyEffect extends OneShotEffect {
private static final FilterPermanent filter = new FilterControlledCreaturePermanent();
static {
filter.add(CounterAnyPredicate.instance);
}
TradeRouteEnvoyEffect() {
super(Outcome.Benefit);
staticText = "draw a card if you control a creature with a counter on it. " +
"If you don't draw a card this way, put a +1/+1 counter on this creature";
}
private TradeRouteEnvoyEffect(final TradeRouteEnvoyEffect effect) {
super(effect);
}
@Override
public TradeRouteEnvoyEffect copy() {
return new TradeRouteEnvoyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
if (game.getBattlefield().contains(filter, source, game, 1)) {
Player player = game.getPlayer(source.getControllerId());
if (player != null && player.drawCards(1, source, game) > 0) {
return true;
}
}
Optional.ofNullable(source.getSourcePermanentIfItStillExists(game))
.ifPresent(permanent -> permanent.addCounters(CounterType.P1P1.createInstance(), source, game));
return true;
}
}

View file

@ -0,0 +1,88 @@
package mage.cards.t;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BecomesTappedSourceTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class TravelingBotanist extends CardImpl {
public TravelingBotanist(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.DOG);
this.subtype.add(SubType.SCOUT);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Whenever this creature becomes tapped, look at the top card of your library. If it's a land card, you may reveal it and put it into your hand. If you don't put the card into your hand, you may put it into your graveyard.
this.addAbility(new BecomesTappedSourceTriggeredAbility(new TravelingBotanistEffect()));
}
private TravelingBotanist(final TravelingBotanist card) {
super(card);
}
@Override
public TravelingBotanist copy() {
return new TravelingBotanist(this);
}
}
class TravelingBotanistEffect extends OneShotEffect {
TravelingBotanistEffect() {
super(Outcome.Benefit);
staticText = "look at the top card of your library. If it's a land card, you may reveal it and " +
"put it into your hand. If you don't put the card into your hand, you may put it into your graveyard";
}
private TravelingBotanistEffect(final TravelingBotanistEffect effect) {
super(effect);
}
@Override
public TravelingBotanistEffect copy() {
return new TravelingBotanistEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Card card = player.getLibrary().getFromTop(game);
if (card == null) {
return false;
}
player.lookAtCards("Top card of library", card, game);
if (card.isLand(game) && player.chooseUse(
Outcome.DrawCard, "Reveal " + card.getName() +
" and put it into your hand?", source, game
)) {
player.revealCards(source, new CardsImpl(card), game);
player.moveCards(card, Zone.HAND, source, game);
return true;
}
if (player.chooseUse(Outcome.Neutral, "Put " + card.getName() + " into your graveyard?", source, game)) {
return player.moveCards(card, Zone.GRAVEYARD, source, game);
}
return true;
}
}

View file

@ -10,7 +10,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.token.SeedGuardianToken; import mage.game.permanent.token.ElementalXXGreenToken;
import java.util.UUID; import java.util.UUID;
@ -61,6 +61,6 @@ class TumbleweedRisingEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
int xvalue = GreatestPowerAmongControlledCreaturesValue.instance.calculate(game, source, this); int xvalue = GreatestPowerAmongControlledCreaturesValue.instance.calculate(game, source, this);
return new CreateTokenEffect(new SeedGuardianToken(xvalue)).apply(game, source); return new CreateTokenEffect(new ElementalXXGreenToken(xvalue)).apply(game, source);
} }
} }

View file

@ -0,0 +1,47 @@
package mage.cards.u;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class UnburiedEarthcarver extends CardImpl {
public UnburiedEarthcarver(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// {2}, Sacrifice another creature: Put a +1/+1 counter on this creature.
Ability ability = new SimpleActivatedAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance()), new GenericManaCost(2)
);
ability.addCost(new SacrificeTargetCost(StaticFilters.FILTER_ANOTHER_CREATURE));
this.addAbility(ability);
}
private UnburiedEarthcarver(final UnburiedEarthcarver card) {
super(card);
}
@Override
public UnburiedEarthcarver copy() {
return new UnburiedEarthcarver(this);
}
}

View file

@ -1,17 +1,15 @@
package mage.cards.v; package mage.cards.v;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SpellCastOpponentTriggeredAbility; import mage.abilities.common.SpellCastOpponentTriggeredAbility;
import mage.abilities.condition.common.SourceMatchesFilterCondition; import mage.abilities.condition.common.SourceMatchesFilterCondition;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.DoUnlessControllerPaysEffect; import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect; import mage.abilities.effects.common.continuous.BecomesCreatureSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -21,6 +19,8 @@ import mage.filter.FilterSpell;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.TokenImpl;
import java.util.UUID;
/** /**
* *
* @author jeffwadsworth * @author jeffwadsworth
@ -33,7 +33,7 @@ public final class VeiledApparition extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
// When an opponent casts a spell, if Veiled Apparition is an enchantment, Veiled Apparition becomes a 3/3 Illusion creature with flying and "At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}." // When an opponent casts a spell, if Veiled Apparition is an enchantment, Veiled Apparition becomes a 3/3 Illusion creature with flying and "At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}."
TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new VeilApparitionToken(), null, Duration.WhileOnBattlefield), TriggeredAbility ability = new SpellCastOpponentTriggeredAbility(new BecomesCreatureSourceEffect(new VeiledApparitionToken(), null, Duration.WhileOnBattlefield),
filter, false); filter, false);
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT), this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceMatchesFilterCondition(StaticFilters.FILTER_PERMANENT_ENCHANTMENT),
"When an opponent casts a spell, if {this} is an enchantment, {this} becomes a 3/3 Illusion creature with flying and \"At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}.\"")); "When an opponent casts a spell, if {this} is an enchantment, {this} becomes a 3/3 Illusion creature with flying and \"At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}.\""));
@ -50,23 +50,25 @@ public final class VeiledApparition extends CardImpl {
} }
} }
class VeilApparitionToken extends TokenImpl { class VeiledApparitionToken extends TokenImpl {
public VeilApparitionToken() { VeiledApparitionToken() {
super("Illusion", "3/3 Illusion creature with flying and \"At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}."); super("Illusion", "3/3 Illusion creature with flying and \"At the beginning of your upkeep, sacrifice Veiled Apparition unless you pay {1}{U}.");
cardType.add(CardType.CREATURE); cardType.add(CardType.CREATURE);
subtype.add(SubType.ILLUSION); subtype.add(SubType.ILLUSION);
power = new MageInt(3); power = new MageInt(3);
toughness = new MageInt(3); toughness = new MageInt(3);
Ability ability = new BeginningOfUpkeepTriggeredAbility(new DoUnlessControllerPaysEffect(new SacrificeSourceEffect(), new ManaCostsImpl<>("{1}{U}"))); this.addAbility(FlyingAbility.getInstance());
this.addAbility(ability); this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl<>("{1}{U}"))
));
} }
private VeilApparitionToken(final VeilApparitionToken token) { private VeiledApparitionToken(final VeiledApparitionToken token) {
super(token); super(token);
} }
public VeilApparitionToken copy() { public VeiledApparitionToken copy() {
return new VeilApparitionToken(this); return new VeiledApparitionToken(this);
} }
} }

View file

@ -0,0 +1,51 @@
package mage.cards.v;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.dynamicvalue.common.SourcePermanentPowerValue;
import mage.abilities.effects.common.MillCardsTargetEffect;
import mage.abilities.keyword.CantBeBlockedSourceAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.target.TargetPlayer;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class VeteranIceClimber extends CardImpl {
public VeteranIceClimber(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SCOUT);
this.power = new MageInt(1);
this.toughness = new MageInt(3);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// This creature can't be blocked.
this.addAbility(new CantBeBlockedSourceAbility());
// Whenever this creature attacks, up to one target player mills cards equal to this creature's power.
Ability ability = new AttacksTriggeredAbility(new MillCardsTargetEffect(SourcePermanentPowerValue.NOT_NEGATIVE));
ability.addTarget(new TargetPlayer(0, 1, false));
this.addAbility(ability);
}
private VeteranIceClimber(final VeteranIceClimber card) {
super(card);
}
@Override
public VeteranIceClimber copy() {
return new VeteranIceClimber(this);
}
}

View file

@ -10,7 +10,7 @@ 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.game.permanent.token.WalkerOfTheGroveToken; import mage.game.permanent.token.Elemental44GreenToken;
/** /**
* *
@ -26,7 +26,7 @@ public final class WalkerOfTheGrove extends CardImpl {
this.toughness = new MageInt(7); this.toughness = new MageInt(7);
// When Walker of the Grove leaves the battlefield, create a 4/4 green Elemental creature token. // When Walker of the Grove leaves the battlefield, create a 4/4 green Elemental creature token.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new CreateTokenEffect(new WalkerOfTheGroveToken(), 1), false)); this.addAbility(new LeavesBattlefieldTriggeredAbility(new CreateTokenEffect(new Elemental44GreenToken(), 1), false));
// Evoke {4}{G} // Evoke {4}{G}
this.addAbility(new EvokeAbility("{4}{G}")); this.addAbility(new EvokeAbility("{4}{G}"));
} }

View file

@ -0,0 +1,73 @@
package mage.cards.w;
import mage.abilities.Ability;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.SacrificeTargetEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.token.RedWarriorToken;
import mage.game.permanent.token.Token;
import mage.target.targetpointer.FixedTargets;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WarEffort extends CardImpl {
public WarEffort(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
// Creatures you control get +1/+0.
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(1, 0, Duration.WhileOnBattlefield)));
// Whenever you attack, create a 1/1 red Warrior creature token that's tapped and attacking. Sacrifice it at the beginning of the next end step.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new WarEffortEffect(), 1));
}
private WarEffort(final WarEffort card) {
super(card);
}
@Override
public WarEffort copy() {
return new WarEffort(this);
}
}
class WarEffortEffect extends OneShotEffect {
WarEffortEffect() {
super(Outcome.Benefit);
staticText = "create a 1/1 red Warrior creature token that's tapped and attacking. " +
"Sacrifice it at the beginning of the next end step";
}
private WarEffortEffect(final WarEffortEffect effect) {
super(effect);
}
@Override
public WarEffortEffect copy() {
return new WarEffortEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Token token = new RedWarriorToken();
token.putOntoBattlefield(1, game, source, source.getControllerId(), true, true);
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
new SacrificeTargetEffect("sacrifice it").setTargetPointer(new FixedTargets(token, game))
), source);
return true;
}
}

View file

@ -0,0 +1,62 @@
package mage.cards.w;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.FlurryAbility;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.filter.predicate.mageobject.PermanentPredicate;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WayspeakerBodyguard extends CardImpl {
private static final FilterCard filter = new FilterNonlandCard("nonland permanent card with mana value 2 or less");
static {
filter.add(PermanentPredicate.instance);
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3));
}
public WayspeakerBodyguard(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.ORC);
this.subtype.add(SubType.MONK);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// When this creature enters, return target nonland permanent card with mana value 2 or less from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect());
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(ability);
// Flurry -- Whenever you cast your second spell each turn, tap target creature an opponent controls.
ability = new FlurryAbility(new TapTargetEffect());
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
}
private WayspeakerBodyguard(final WayspeakerBodyguard card) {
super(card);
}
@Override
public WayspeakerBodyguard copy() {
return new WayspeakerBodyguard(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.w;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HarmonizeAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WildRide extends CardImpl {
public WildRide(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}");
// Target creature gets +3/+0 and gains haste until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(
3, 0, Duration.EndOfTurn
).setText("Target creature gets +3/+0"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(
HasteAbility.getInstance(), Duration.EndOfTurn
).setText("and gains haste until end of turn"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Harmonize {4}{R}
this.addAbility(new HarmonizeAbility(this, "{4}{R}"));
}
private WildRide(final WildRide card) {
super(card);
}
@Override
public WildRide copy() {
return new WildRide(this);
}
}

View file

@ -0,0 +1,43 @@
package mage.cards.w;
import mage.MageInt;
import mage.abilities.common.FlurryAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.game.permanent.token.BirdToken;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WingbladeDisciple extends CardImpl {
public WingbladeDisciple(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MONK);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Flurry -- Whenever you cast your second spell each turn, create a 1/1 white Bird creature token with flying.
this.addAbility(new FlurryAbility(new CreateTokenEffect(new BirdToken())));
}
private WingbladeDisciple(final WingbladeDisciple card) {
super(card);
}
@Override
public WingbladeDisciple copy() {
return new WingbladeDisciple(this);
}
}

View file

@ -0,0 +1,60 @@
package mage.cards.y;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.condition.common.CastFromEverywhereSourceCondition;
import mage.abilities.costs.common.MillCardsCost;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class YathanRoadwatcher extends CardImpl {
private static final FilterCard filter
= new FilterCreatureCard("creature card with mana value 3 or less from your graveyard");
static {
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 4));
}
public YathanRoadwatcher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}{B}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SCOUT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When this creature enters, if you cast it, mill four cards. When you do, return target creature card with mana value 3 or less from your graveyard to the battlefield.
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new ReturnFromGraveyardToBattlefieldTargetEffect(), false
);
ability.addTarget(new TargetCardInYourGraveyard(filter));
this.addAbility(new EntersBattlefieldTriggeredAbility(new DoWhenCostPaid(
ability, new MillCardsCost(4), "", false
)).withInterveningIf(CastFromEverywhereSourceCondition.instance));
}
private YathanRoadwatcher(final YathanRoadwatcher card) {
super(card);
}
@Override
public YathanRoadwatcher copy() {
return new YathanRoadwatcher(this);
}
}

View file

@ -0,0 +1,58 @@
package mage.cards.z;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.CantBeSacrificedSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.MobilizeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.TokenPredicate;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ZurgoThundersDecree extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.WARRIOR, "");
static {
filter.add(TokenPredicate.TRUE);
}
private static final Condition condition = new IsStepCondition(PhaseStep.END_TURN, true);
public ZurgoThundersDecree(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{W}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.ORC);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// Mobilize 2
this.addAbility(new MobilizeAbility(2));
// During your end step, Warrior tokens you control have "This token can't be sacrificed."
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(new GainAbilityControlledEffect(
new SimpleStaticAbility(new CantBeSacrificedSourceEffect()), Duration.WhileOnBattlefield
), condition, "during your end step, Warrior tokens you control have \"This token can't be sacrificed.\"")));
}
private ZurgoThundersDecree(final ZurgoThundersDecree card) {
super(card);
}
@Override
public ZurgoThundersDecree copy() {
return new ZurgoThundersDecree(this);
}
}

View file

@ -118,7 +118,7 @@ public final class AetherdriftCommander extends ExpansionSet {
cards.add(new SetCardInfo("Maskwood Nexus", 132, Rarity.RARE, mage.cards.m.MaskwoodNexus.class)); cards.add(new SetCardInfo("Maskwood Nexus", 132, Rarity.RARE, mage.cards.m.MaskwoodNexus.class));
cards.add(new SetCardInfo("Midnight Clock", 79, Rarity.RARE, mage.cards.m.MidnightClock.class)); cards.add(new SetCardInfo("Midnight Clock", 79, Rarity.RARE, mage.cards.m.MidnightClock.class));
cards.add(new SetCardInfo("Midnight Reaper", 44, Rarity.RARE, mage.cards.m.MidnightReaper.class)); cards.add(new SetCardInfo("Midnight Reaper", 44, Rarity.RARE, mage.cards.m.MidnightReaper.class));
cards.add(new SetCardInfo("Murderous Rider // Swift End", 45, Rarity.RARE, mage.cards.m.MurderousRider.class)); cards.add(new SetCardInfo("Murderous Rider", 45, Rarity.RARE, mage.cards.m.MurderousRider.class));
cards.add(new SetCardInfo("Never // Return", 96, Rarity.RARE, mage.cards.n.NeverReturn.class)); cards.add(new SetCardInfo("Never // Return", 96, Rarity.RARE, mage.cards.n.NeverReturn.class));
cards.add(new SetCardInfo("Nissa, Worldsoul Speaker", 13, Rarity.RARE, mage.cards.n.NissaWorldsoulSpeaker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nissa, Worldsoul Speaker", 13, Rarity.RARE, mage.cards.n.NissaWorldsoulSpeaker.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nissa, Worldsoul Speaker", 29, Rarity.RARE, mage.cards.n.NissaWorldsoulSpeaker.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Nissa, Worldsoul Speaker", 29, Rarity.RARE, mage.cards.n.NissaWorldsoulSpeaker.class, NON_FULL_USE_VARIOUS));

View file

@ -1010,13 +1010,13 @@ public final class DoctorWho extends ExpansionSet {
cards.add(new SetCardInfo("The Rani", 754, Rarity.RARE, mage.cards.t.TheRani.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Rani", 754, Rarity.RARE, mage.cards.t.TheRani.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Sea Devils", 108, Rarity.RARE, mage.cards.t.TheSeaDevils.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Sea Devils", 108, Rarity.RARE, mage.cards.t.TheSeaDevils.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Sea Devils", 713, Rarity.RARE, mage.cards.t.TheSeaDevils.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Sea Devils", 713, Rarity.RARE, mage.cards.t.TheSeaDevils.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Second Doctor", "553z", Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Second Doctor", "553z", Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Second Doctor", 1031, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Second Doctor", 1031, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Second Doctor", 1144, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Second Doctor", 1144, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Second Doctor", 156, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Second Doctor", 156, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Second Doctor", 440, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Second Doctor", 440, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Second Doctor", 553, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Second Doctor", 553, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Second Doctor", 761, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("The Second Doctor", 761, Rarity.RARE, mage.cards.t.TheSecondDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Seventh Doctor", "558z", Rarity.RARE, mage.cards.t.TheSeventhDoctor.class, NON_FULL_USE_VARIOUS)); //cards.add(new SetCardInfo("The Seventh Doctor", "558z", Rarity.RARE, mage.cards.t.TheSeventhDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Seventh Doctor", 1033, Rarity.RARE, mage.cards.t.TheSeventhDoctor.class, NON_FULL_USE_VARIOUS)); //cards.add(new SetCardInfo("The Seventh Doctor", 1033, Rarity.RARE, mage.cards.t.TheSeventhDoctor.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("The Seventh Doctor", 1149, Rarity.RARE, mage.cards.t.TheSeventhDoctor.class, NON_FULL_USE_VARIOUS)); //cards.add(new SetCardInfo("The Seventh Doctor", 1149, Rarity.RARE, mage.cards.t.TheSeventhDoctor.class, NON_FULL_USE_VARIOUS));
@ -1093,10 +1093,10 @@ public final class DoctorWho extends ExpansionSet {
cards.add(new SetCardInfo("Thijarian Witness", 716, Rarity.UNCOMMON, mage.cards.t.ThijarianWitness.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thijarian Witness", 716, Rarity.UNCOMMON, mage.cards.t.ThijarianWitness.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Think Twice", 220, Rarity.COMMON, mage.cards.t.ThinkTwice.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Think Twice", 220, Rarity.COMMON, mage.cards.t.ThinkTwice.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Think Twice", 811, Rarity.COMMON, mage.cards.t.ThinkTwice.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Think Twice", 811, Rarity.COMMON, mage.cards.t.ThinkTwice.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("This Is How It Ends", 373, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("This Is How It Ends", 373, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("This Is How It Ends", 675, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("This Is How It Ends", 675, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("This Is How It Ends", 70, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("This Is How It Ends", 70, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("This Is How It Ends", 964, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("This Is How It Ends", 964, Rarity.RARE, mage.cards.t.ThisIsHowItEnds.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Thought Vessel", 255, Rarity.UNCOMMON, mage.cards.t.ThoughtVessel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thought Vessel", 255, Rarity.UNCOMMON, mage.cards.t.ThoughtVessel.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Thought Vessel", 846, Rarity.UNCOMMON, mage.cards.t.ThoughtVessel.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Thought Vessel", 846, Rarity.UNCOMMON, mage.cards.t.ThoughtVessel.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Three Visits", 235, Rarity.UNCOMMON, mage.cards.t.ThreeVisits.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Three Visits", 235, Rarity.UNCOMMON, mage.cards.t.ThreeVisits.class, NON_FULL_USE_VARIOUS));

View file

@ -22,37 +22,69 @@ public class MediaAndCollaborationPromos extends ExpansionSet {
// some cards are non-English (most are Japanese, Jamuraan Lion has a German printing), but it's ok - scryfall can download it // some cards are non-English (most are Japanese, Jamuraan Lion has a German printing), but it's ok - scryfall can download it
cards.add(new SetCardInfo("Archangel", 29, Rarity.RARE, mage.cards.a.Archangel.class)); cards.add(new SetCardInfo("Ajani, Mentor of Heroes", "2024-3", Rarity.MYTHIC, mage.cards.a.AjaniMentorOfHeroes.class));
cards.add(new SetCardInfo("Ascendant Evincar", 28, Rarity.RARE, mage.cards.a.AscendantEvincar.class)); cards.add(new SetCardInfo("Ancestral Mask", "2025-2", Rarity.RARE, mage.cards.a.AncestralMask.class));
cards.add(new SetCardInfo("Blue Elemental Blast", 5, Rarity.COMMON, mage.cards.b.BlueElementalBlast.class)); cards.add(new SetCardInfo("Archangel", "2000-4", Rarity.RARE, mage.cards.a.Archangel.class));
cards.add(new SetCardInfo("Cast Down", 30, Rarity.UNCOMMON, mage.cards.c.CastDown.class)); cards.add(new SetCardInfo("Ascendant Evincar", "2000-7", Rarity.RARE, mage.cards.a.AscendantEvincar.class));
cards.add(new SetCardInfo("Chandra's Outrage", 18, Rarity.COMMON, mage.cards.c.ChandrasOutrage.class)); cards.add(new SetCardInfo("Avalanche Riders", "2023-5", Rarity.RARE, mage.cards.a.AvalancheRiders.class));
cards.add(new SetCardInfo("Chandra's Spitfire", 19, Rarity.UNCOMMON, mage.cards.c.ChandrasSpitfire.class)); cards.add(new SetCardInfo("Blue Elemental Blast", "1995-2", Rarity.COMMON, mage.cards.b.BlueElementalBlast.class));
cards.add(new SetCardInfo("Cunning Sparkmage", 17, Rarity.UNCOMMON, mage.cards.c.CunningSparkmage.class)); cards.add(new SetCardInfo("Bone Shredder", "2021-2", Rarity.RARE, mage.cards.b.BoneShredder.class));
cards.add(new SetCardInfo("Darksteel Juggernaut", 16, Rarity.RARE, mage.cards.d.DarksteelJuggernaut.class)); cards.add(new SetCardInfo("Cast Down", "2019-1", Rarity.UNCOMMON, mage.cards.c.CastDown.class));
cards.add(new SetCardInfo("Daxos, Blessed by the Sun", 36, Rarity.UNCOMMON, mage.cards.d.DaxosBlessedByTheSun.class)); cards.add(new SetCardInfo("Chandra's Outrage", "2010-3", Rarity.COMMON, mage.cards.c.ChandrasOutrage.class));
cards.add(new SetCardInfo("Diabolic Edict", 31, Rarity.RARE, mage.cards.d.DiabolicEdict.class)); cards.add(new SetCardInfo("Chandra's Spitfire", "2010-4", Rarity.UNCOMMON, mage.cards.c.ChandrasSpitfire.class));
cards.add(new SetCardInfo("Duress", 34, Rarity.RARE, mage.cards.d.Duress.class)); cards.add(new SetCardInfo("Counterspell", "2021-1", Rarity.RARE, mage.cards.c.Counterspell.class));
cards.add(new SetCardInfo("Fireball", 4, Rarity.COMMON, mage.cards.f.Fireball.class)); cards.add(new SetCardInfo("Crop Rotation", "2020-7ww", Rarity.RARE, mage.cards.c.CropRotation.class));
cards.add(new SetCardInfo("Jamuraan Lion", "10*", Rarity.COMMON, mage.cards.j.JamuraanLion.class)); cards.add(new SetCardInfo("Culling the Weak", "2023-8", Rarity.RARE, mage.cards.c.CullingTheWeak.class));
cards.add(new SetCardInfo("Kuldotha Phoenix", 20, Rarity.RARE, mage.cards.k.KuldothaPhoenix.class)); cards.add(new SetCardInfo("Cunning Sparkmage", "2010-2", Rarity.UNCOMMON, mage.cards.c.CunningSparkmage.class));
cards.add(new SetCardInfo("Lava Coil", 33, Rarity.UNCOMMON, mage.cards.l.LavaCoil.class)); cards.add(new SetCardInfo("Dark Ritual", "2020-4", Rarity.RARE, mage.cards.d.DarkRitual.class));
cards.add(new SetCardInfo("Lightning Hounds", 10, Rarity.COMMON, mage.cards.l.LightningHounds.class)); cards.add(new SetCardInfo("Darksteel Juggernaut", "2010-1", Rarity.RARE, mage.cards.d.DarksteelJuggernaut.class));
cards.add(new SetCardInfo("Parallax Dementia", 27, Rarity.COMMON, mage.cards.p.ParallaxDementia.class)); cards.add(new SetCardInfo("Daxos, Blessed by the Sun", "2020-2", Rarity.UNCOMMON, mage.cards.d.DaxosBlessedByTheSun.class));
cards.add(new SetCardInfo("Phantasmal Dragon", 21, Rarity.UNCOMMON, mage.cards.p.PhantasmalDragon.class)); cards.add(new SetCardInfo("Diabolic Edict", "2024-5", Rarity.RARE, mage.cards.d.DiabolicEdict.class));
cards.add(new SetCardInfo("Phyrexian Rager", 14, Rarity.COMMON, mage.cards.p.PhyrexianRager.class)); cards.add(new SetCardInfo("Disenchant", "2022-1", Rarity.RARE, mage.cards.d.Disenchant.class));
cards.add(new SetCardInfo("Sandbar Crocodile", 22, Rarity.COMMON, mage.cards.s.SandbarCrocodile.class)); cards.add(new SetCardInfo("Duress", "2025-7", Rarity.RARE, mage.cards.d.Duress.class));
cards.add(new SetCardInfo("Scent of Cinder", 9, Rarity.COMMON, mage.cards.s.ScentOfCinder.class)); cards.add(new SetCardInfo("Fireball", "1995-1", Rarity.COMMON, mage.cards.f.Fireball.class));
cards.add(new SetCardInfo("Shivan Dragon", 15, Rarity.RARE, mage.cards.s.ShivanDragon.class)); cards.add(new SetCardInfo("Frantic Search", "2022-4", Rarity.RARE, mage.cards.f.FranticSearch.class));
cards.add(new SetCardInfo("Shock", 32, Rarity.RARE, mage.cards.s.Shock.class)); cards.add(new SetCardInfo("Gingerbrute", "2023-3", Rarity.RARE, mage.cards.g.Gingerbrute.class));
cards.add(new SetCardInfo("Shrieking Drake", 24, Rarity.COMMON, mage.cards.s.ShriekingDrake.class)); cards.add(new SetCardInfo("Gush", "2024-4", Rarity.RARE, mage.cards.g.Gush.class));
cards.add(new SetCardInfo("Silver Drake", 13, Rarity.COMMON, mage.cards.s.SilverDrake.class)); cards.add(new SetCardInfo("Harald, King of Skemfar", "2021-3", Rarity.RARE, mage.cards.h.HaraldKingOfSkemfar.class));
cards.add(new SetCardInfo("Spined Wurm", 11, Rarity.COMMON, mage.cards.s.SpinedWurm.class)); cards.add(new SetCardInfo("Heliod's Pilgrim", "2020-6", Rarity.RARE, mage.cards.h.HeliodsPilgrim.class));
cards.add(new SetCardInfo("Staggering Insight", 37, Rarity.RARE, mage.cards.s.StaggeringInsight.class)); cards.add(new SetCardInfo("Hypnotic Sprite", "2019-5", Rarity.RARE, mage.cards.h.HypnoticSprite.class));
cards.add(new SetCardInfo("Stream of Life", 25, Rarity.COMMON, mage.cards.s.StreamOfLife.class)); cards.add(new SetCardInfo("Jace Beleren", "2009-1", Rarity.MYTHIC, mage.cards.j.JaceBeleren.class));
cards.add(new SetCardInfo("Thorn Elemental", 26, Rarity.RARE, mage.cards.t.ThornElemental.class)); cards.add(new SetCardInfo("Jace, Memory Adept", "2024-2", Rarity.MYTHIC, mage.cards.j.JaceMemoryAdept.class));
cards.add(new SetCardInfo("Voltaic Key", 35, Rarity.RARE, mage.cards.v.VoltaicKey.class)); cards.add(new SetCardInfo("Jamuraan Lion", "1996-3", Rarity.COMMON, mage.cards.j.JamuraanLion.class));
cards.add(new SetCardInfo("Warmonger", 12, Rarity.UNCOMMON, mage.cards.w.Warmonger.class)); cards.add(new SetCardInfo("Kuldotha Phoenix", "2010-5", Rarity.RARE, mage.cards.k.KuldothaPhoenix.class));
cards.add(new SetCardInfo("Zhalfirin Knight", 23, Rarity.COMMON, mage.cards.z.ZhalfirinKnight.class)); cards.add(new SetCardInfo("Lava Coil", "2019-4", Rarity.UNCOMMON, mage.cards.l.LavaCoil.class));
cards.add(new SetCardInfo("Lightning Hounds", "2000-1", Rarity.COMMON, mage.cards.l.LightningHounds.class));
cards.add(new SetCardInfo("Liliana of the Dark Realms", "2024-8", Rarity.MYTHIC, mage.cards.l.LilianaOfTheDarkRealms.class));
cards.add(new SetCardInfo("Mental Misstep", "2023-1", Rarity.RARE, mage.cards.m.MentalMisstep.class));
cards.add(new SetCardInfo("Nicol Bolas, Planeswalker", "2025-10", Rarity.MYTHIC, mage.cards.n.NicolBolasPlaneswalker.class));
cards.add(new SetCardInfo("Parallax Dementia", "2000-6", Rarity.COMMON, mage.cards.p.ParallaxDementia.class));
cards.add(new SetCardInfo("Patchwork Banner", "2024-7", Rarity.RARE, mage.cards.p.PatchworkBanner.class));
cards.add(new SetCardInfo("Phantasmal Dragon", "2011-1", Rarity.UNCOMMON, mage.cards.p.PhantasmalDragon.class));
cards.add(new SetCardInfo("Phyrexian Rager", "2000-5", Rarity.COMMON, mage.cards.p.PhyrexianRager.class));
cards.add(new SetCardInfo("Pyromancer's Gauntlet", "2023-6", Rarity.RARE, mage.cards.p.PyromancersGauntlet.class));
cards.add(new SetCardInfo("Ruin Crab", "2023-4", Rarity.RARE, mage.cards.r.RuinCrab.class));
cards.add(new SetCardInfo("Sandbar Crocodile", "1996-1", Rarity.COMMON, mage.cards.s.SandbarCrocodile.class));
cards.add(new SetCardInfo("Scent of Cinder", "1999-1", Rarity.COMMON, mage.cards.s.ScentOfCinder.class));
cards.add(new SetCardInfo("Shield Wall", "1997-3", Rarity.COMMON, mage.cards.s.ShieldWall.class));
cards.add(new SetCardInfo("Shivan Dragon", "2001-2", Rarity.RARE, mage.cards.s.ShivanDragon.class));
cards.add(new SetCardInfo("Shock", "2025-1", Rarity.RARE, mage.cards.s.Shock.class));
cards.add(new SetCardInfo("Shrieking Drake", "1997-2", Rarity.COMMON, mage.cards.s.ShriekingDrake.class));
cards.add(new SetCardInfo("Silver Drake", "2000-2", Rarity.COMMON, mage.cards.s.SilverDrake.class));
cards.add(new SetCardInfo("Snuff Out", "2024-1", Rarity.RARE, mage.cards.s.SnuffOut.class));
cards.add(new SetCardInfo("Spined Wurm", "2001-1", Rarity.COMMON, mage.cards.s.SpinedWurm.class));
cards.add(new SetCardInfo("Sprite Dragon", "2020-5", Rarity.RARE, mage.cards.s.SpriteDragon.class));
cards.add(new SetCardInfo("Staggering Insight", "2020-3", Rarity.RARE, mage.cards.s.StaggeringInsight.class));
cards.add(new SetCardInfo("Stream of Life", "1997-4", Rarity.COMMON, mage.cards.s.StreamOfLife.class));
cards.add(new SetCardInfo("Talruum Champion", "1997-1", Rarity.COMMON, mage.cards.t.TalruumChampion.class));
cards.add(new SetCardInfo("Tangled Florahedron", "2020-8", Rarity.UNCOMMON, mage.cards.t.TangledFlorahedron.class));
cards.add(new SetCardInfo("Thorn Elemental", "2000-3", Rarity.RARE, mage.cards.t.ThornElemental.class));
cards.add(new SetCardInfo("Usher of the Fallen", "2022-3", Rarity.RARE, mage.cards.u.UsherOfTheFallen.class));
cards.add(new SetCardInfo("Voltaic Key", "2024-6", Rarity.RARE, mage.cards.v.VoltaicKey.class));
cards.add(new SetCardInfo("Warmonger", "1999-2", Rarity.UNCOMMON, mage.cards.w.Warmonger.class));
cards.add(new SetCardInfo("Wild Growth", "2022-2", Rarity.RARE, mage.cards.w.WildGrowth.class));
cards.add(new SetCardInfo("Winged Boots", "2023-7", Rarity.RARE, mage.cards.w.WingedBoots.class));
cards.add(new SetCardInfo("Worn Powerstone", "2023-2", Rarity.RARE, mage.cards.w.WornPowerstone.class));
cards.add(new SetCardInfo("Zhalfirin Knight", "1996-2", Rarity.COMMON, mage.cards.z.ZhalfirinKnight.class));
} }
} }

View file

@ -12,7 +12,7 @@ import java.util.List;
*/ */
public final class TarkirDragonstorm extends ExpansionSet { public final class TarkirDragonstorm extends ExpansionSet {
private static final List<String> unfinished = Arrays.asList("Channeled Dragonfire", "Glacial Dragonhunt", "Mammoth Bellow", "Nature's Rhythm", "Roamer's Routine", "Songcrafter Mage", "Synchronized Charge", "Unending Whisper", "Ureni's Rebuff", "Winternight Stories"); private static final List<String> unfinished = Arrays.asList("Channeled Dragonfire", "Glacial Dragonhunt", "Mammoth Bellow", "Nature's Rhythm", "Roamer's Routine", "Songcrafter Mage", "Synchronized Charge", "Unending Whisper", "Ureni's Rebuff", "Wild Ride", "Winternight Stories");
private static final TarkirDragonstorm instance = new TarkirDragonstorm(); private static final TarkirDragonstorm instance = new TarkirDragonstorm();
public static TarkirDragonstorm getInstance() { public static TarkirDragonstorm getInstance() {
@ -26,11 +26,15 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Abzan Devotee", 68, Rarity.COMMON, mage.cards.a.AbzanDevotee.class)); cards.add(new SetCardInfo("Abzan Devotee", 68, Rarity.COMMON, mage.cards.a.AbzanDevotee.class));
cards.add(new SetCardInfo("Abzan Monument", 238, Rarity.UNCOMMON, mage.cards.a.AbzanMonument.class)); cards.add(new SetCardInfo("Abzan Monument", 238, Rarity.UNCOMMON, mage.cards.a.AbzanMonument.class));
cards.add(new SetCardInfo("Adorned Crocodile", 69, Rarity.COMMON, mage.cards.a.AdornedCrocodile.class));
cards.add(new SetCardInfo("Aegis Sculptor", 35, Rarity.UNCOMMON, mage.cards.a.AegisSculptor.class)); cards.add(new SetCardInfo("Aegis Sculptor", 35, Rarity.UNCOMMON, mage.cards.a.AegisSculptor.class));
cards.add(new SetCardInfo("Agent of Kotis", 36, Rarity.COMMON, mage.cards.a.AgentOfKotis.class)); cards.add(new SetCardInfo("Agent of Kotis", 36, Rarity.COMMON, mage.cards.a.AgentOfKotis.class));
cards.add(new SetCardInfo("Ainok Wayfarer", 134, Rarity.COMMON, mage.cards.a.AinokWayfarer.class));
cards.add(new SetCardInfo("Alchemist's Assistant", 71, Rarity.UNCOMMON, mage.cards.a.AlchemistsAssistant.class));
cards.add(new SetCardInfo("Alesha's Legacy", 72, Rarity.COMMON, mage.cards.a.AleshasLegacy.class)); cards.add(new SetCardInfo("Alesha's Legacy", 72, Rarity.COMMON, mage.cards.a.AleshasLegacy.class));
cards.add(new SetCardInfo("Ambling Stormshell", 37, Rarity.RARE, mage.cards.a.AmblingStormshell.class)); cards.add(new SetCardInfo("Ambling Stormshell", 37, Rarity.RARE, mage.cards.a.AmblingStormshell.class));
cards.add(new SetCardInfo("Anafenza, Unyielding Lineage", 2, Rarity.RARE, mage.cards.a.AnafenzaUnyieldingLineage.class)); cards.add(new SetCardInfo("Anafenza, Unyielding Lineage", 2, Rarity.RARE, mage.cards.a.AnafenzaUnyieldingLineage.class));
cards.add(new SetCardInfo("Arashin Sunshield", 3, Rarity.COMMON, mage.cards.a.ArashinSunshield.class));
cards.add(new SetCardInfo("Armament Dragon", 168, Rarity.UNCOMMON, mage.cards.a.ArmamentDragon.class)); cards.add(new SetCardInfo("Armament Dragon", 168, Rarity.UNCOMMON, mage.cards.a.ArmamentDragon.class));
cards.add(new SetCardInfo("Attuned Hunter", 135, Rarity.UNCOMMON, mage.cards.a.AttunedHunter.class)); cards.add(new SetCardInfo("Attuned Hunter", 135, Rarity.UNCOMMON, mage.cards.a.AttunedHunter.class));
cards.add(new SetCardInfo("Auroral Procession", 169, Rarity.UNCOMMON, mage.cards.a.AuroralProcession.class)); cards.add(new SetCardInfo("Auroral Procession", 169, Rarity.UNCOMMON, mage.cards.a.AuroralProcession.class));
@ -46,7 +50,9 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Breaching Dragonstorm", 101, Rarity.UNCOMMON, mage.cards.b.BreachingDragonstorm.class)); cards.add(new SetCardInfo("Breaching Dragonstorm", 101, Rarity.UNCOMMON, mage.cards.b.BreachingDragonstorm.class));
cards.add(new SetCardInfo("Call the Spirit Dragons", 174, Rarity.MYTHIC, mage.cards.c.CallTheSpiritDragons.class)); cards.add(new SetCardInfo("Call the Spirit Dragons", 174, Rarity.MYTHIC, mage.cards.c.CallTheSpiritDragons.class));
cards.add(new SetCardInfo("Caustic Exhale", 74, Rarity.COMMON, mage.cards.c.CausticExhale.class)); cards.add(new SetCardInfo("Caustic Exhale", 74, Rarity.COMMON, mage.cards.c.CausticExhale.class));
cards.add(new SetCardInfo("Champion of Dusan", 137, Rarity.COMMON, mage.cards.c.ChampionOfDusan.class));
cards.add(new SetCardInfo("Channeled Dragonfire", 102, Rarity.UNCOMMON, mage.cards.c.ChanneledDragonfire.class)); cards.add(new SetCardInfo("Channeled Dragonfire", 102, Rarity.UNCOMMON, mage.cards.c.ChanneledDragonfire.class));
cards.add(new SetCardInfo("Constrictor Sage", 39, Rarity.UNCOMMON, mage.cards.c.ConstrictorSage.class));
cards.add(new SetCardInfo("Coordinated Maneuver", 6, Rarity.COMMON, mage.cards.c.CoordinatedManeuver.class)); cards.add(new SetCardInfo("Coordinated Maneuver", 6, Rarity.COMMON, mage.cards.c.CoordinatedManeuver.class));
cards.add(new SetCardInfo("Cori Mountain Monastery", 252, Rarity.RARE, mage.cards.c.CoriMountainMonastery.class)); cards.add(new SetCardInfo("Cori Mountain Monastery", 252, Rarity.RARE, mage.cards.c.CoriMountainMonastery.class));
cards.add(new SetCardInfo("Cori Mountain Stalwart", 175, Rarity.UNCOMMON, mage.cards.c.CoriMountainStalwart.class)); cards.add(new SetCardInfo("Cori Mountain Stalwart", 175, Rarity.UNCOMMON, mage.cards.c.CoriMountainStalwart.class));
@ -62,6 +68,7 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Dismal Backwater", 254, Rarity.COMMON, mage.cards.d.DismalBackwater.class)); cards.add(new SetCardInfo("Dismal Backwater", 254, Rarity.COMMON, mage.cards.d.DismalBackwater.class));
cards.add(new SetCardInfo("Dispelling Exhale", 41, Rarity.COMMON, mage.cards.d.DispellingExhale.class)); cards.add(new SetCardInfo("Dispelling Exhale", 41, Rarity.COMMON, mage.cards.d.DispellingExhale.class));
cards.add(new SetCardInfo("Dracogenesis", 105, Rarity.MYTHIC, mage.cards.d.Dracogenesis.class)); cards.add(new SetCardInfo("Dracogenesis", 105, Rarity.MYTHIC, mage.cards.d.Dracogenesis.class));
cards.add(new SetCardInfo("Dragon Sniper", 139, Rarity.UNCOMMON, mage.cards.d.DragonSniper.class));
cards.add(new SetCardInfo("Dragon's Prey", 79, Rarity.COMMON, mage.cards.d.DragonsPrey.class)); cards.add(new SetCardInfo("Dragon's Prey", 79, Rarity.COMMON, mage.cards.d.DragonsPrey.class));
cards.add(new SetCardInfo("Dragonback Assault", 179, Rarity.MYTHIC, mage.cards.d.DragonbackAssault.class)); cards.add(new SetCardInfo("Dragonback Assault", 179, Rarity.MYTHIC, mage.cards.d.DragonbackAssault.class));
cards.add(new SetCardInfo("Dragonback Lancer", 9, Rarity.COMMON, mage.cards.d.DragonbackLancer.class)); cards.add(new SetCardInfo("Dragonback Lancer", 9, Rarity.COMMON, mage.cards.d.DragonbackLancer.class));
@ -71,22 +78,32 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Dragonstorm Globe", 241, Rarity.COMMON, mage.cards.d.DragonstormGlobe.class)); cards.add(new SetCardInfo("Dragonstorm Globe", 241, Rarity.COMMON, mage.cards.d.DragonstormGlobe.class));
cards.add(new SetCardInfo("Dusyut Earthcarver", 141, Rarity.COMMON, mage.cards.d.DusyutEarthcarver.class)); cards.add(new SetCardInfo("Dusyut Earthcarver", 141, Rarity.COMMON, mage.cards.d.DusyutEarthcarver.class));
cards.add(new SetCardInfo("Duty Beyond Death", 10, Rarity.UNCOMMON, mage.cards.d.DutyBeyondDeath.class)); cards.add(new SetCardInfo("Duty Beyond Death", 10, Rarity.UNCOMMON, mage.cards.d.DutyBeyondDeath.class));
cards.add(new SetCardInfo("Elspeth, Storm Slayer", 11, Rarity.MYTHIC, mage.cards.e.ElspethStormSlayer.class));
cards.add(new SetCardInfo("Embermouth Sentinel", 242, Rarity.COMMON, mage.cards.e.EmbermouthSentinel.class)); cards.add(new SetCardInfo("Embermouth Sentinel", 242, Rarity.COMMON, mage.cards.e.EmbermouthSentinel.class));
cards.add(new SetCardInfo("Encroaching Dragonstorm", 142, Rarity.UNCOMMON, mage.cards.e.EncroachingDragonstorm.class)); cards.add(new SetCardInfo("Encroaching Dragonstorm", 142, Rarity.UNCOMMON, mage.cards.e.EncroachingDragonstorm.class));
cards.add(new SetCardInfo("Equilibrium Adept", 106, Rarity.UNCOMMON, mage.cards.e.EquilibriumAdept.class)); cards.add(new SetCardInfo("Equilibrium Adept", 106, Rarity.UNCOMMON, mage.cards.e.EquilibriumAdept.class));
cards.add(new SetCardInfo("Essence Anchor", 44, Rarity.UNCOMMON, mage.cards.e.EssenceAnchor.class));
cards.add(new SetCardInfo("Evolving Wilds", 255, Rarity.COMMON, mage.cards.e.EvolvingWilds.class)); cards.add(new SetCardInfo("Evolving Wilds", 255, Rarity.COMMON, mage.cards.e.EvolvingWilds.class));
cards.add(new SetCardInfo("Fangkeeper's Familiar", 183, Rarity.RARE, mage.cards.f.FangkeepersFamiliar.class)); cards.add(new SetCardInfo("Fangkeeper's Familiar", 183, Rarity.RARE, mage.cards.f.FangkeepersFamiliar.class));
cards.add(new SetCardInfo("Felothar, Dawn of the Abzan", 184, Rarity.RARE, mage.cards.f.FelotharDawnOfTheAbzan.class)); cards.add(new SetCardInfo("Felothar, Dawn of the Abzan", 184, Rarity.RARE, mage.cards.f.FelotharDawnOfTheAbzan.class));
cards.add(new SetCardInfo("Fire-Rim Form", 107, Rarity.COMMON, mage.cards.f.FireRimForm.class));
cards.add(new SetCardInfo("Fleeting Effigy", 108, Rarity.UNCOMMON, mage.cards.f.FleetingEffigy.class));
cards.add(new SetCardInfo("Forest", 285, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Forest", 285, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Fortress Kin-Guard", 12, Rarity.COMMON, mage.cards.f.FortressKinGuard.class)); cards.add(new SetCardInfo("Fortress Kin-Guard", 12, Rarity.COMMON, mage.cards.f.FortressKinGuard.class));
cards.add(new SetCardInfo("Fresh Start", 46, Rarity.UNCOMMON, mage.cards.f.FreshStart.class)); cards.add(new SetCardInfo("Fresh Start", 46, Rarity.UNCOMMON, mage.cards.f.FreshStart.class));
cards.add(new SetCardInfo("Frontier Bivouac", 256, Rarity.UNCOMMON, mage.cards.f.FrontierBivouac.class)); cards.add(new SetCardInfo("Frontier Bivouac", 256, Rarity.UNCOMMON, mage.cards.f.FrontierBivouac.class));
cards.add(new SetCardInfo("Frontline Rush", 186, Rarity.UNCOMMON, mage.cards.f.FrontlineRush.class));
cards.add(new SetCardInfo("Glacial Dragonhunt", 188, Rarity.UNCOMMON, mage.cards.g.GlacialDragonhunt.class)); cards.add(new SetCardInfo("Glacial Dragonhunt", 188, Rarity.UNCOMMON, mage.cards.g.GlacialDragonhunt.class));
cards.add(new SetCardInfo("Great Arashin City", 257, Rarity.RARE, mage.cards.g.GreatArashinCity.class)); cards.add(new SetCardInfo("Great Arashin City", 257, Rarity.RARE, mage.cards.g.GreatArashinCity.class));
cards.add(new SetCardInfo("Gurmag Nightwatch", 190, Rarity.COMMON, mage.cards.g.GurmagNightwatch.class)); cards.add(new SetCardInfo("Gurmag Nightwatch", 190, Rarity.COMMON, mage.cards.g.GurmagNightwatch.class));
cards.add(new SetCardInfo("Gurmag Rakshasa", 81, Rarity.UNCOMMON, mage.cards.g.GurmagRakshasa.class));
cards.add(new SetCardInfo("Hardened Tactician", 191, Rarity.UNCOMMON, mage.cards.h.HardenedTactician.class)); cards.add(new SetCardInfo("Hardened Tactician", 191, Rarity.UNCOMMON, mage.cards.h.HardenedTactician.class));
cards.add(new SetCardInfo("Heritage Reclamation", 145, Rarity.COMMON, mage.cards.h.HeritageReclamation.class)); cards.add(new SetCardInfo("Heritage Reclamation", 145, Rarity.COMMON, mage.cards.h.HeritageReclamation.class));
cards.add(new SetCardInfo("Humbling Elder", 48, Rarity.COMMON, mage.cards.h.HumblingElder.class));
cards.add(new SetCardInfo("Iceridge Serpent", 49, Rarity.COMMON, mage.cards.i.IceridgeSerpent.class));
cards.add(new SetCardInfo("Inevitable Defeat", 194, Rarity.RARE, mage.cards.i.InevitableDefeat.class)); cards.add(new SetCardInfo("Inevitable Defeat", 194, Rarity.RARE, mage.cards.i.InevitableDefeat.class));
cards.add(new SetCardInfo("Inspirited Vanguard", 146, Rarity.UNCOMMON, mage.cards.i.InspiritedVanguard.class));
cards.add(new SetCardInfo("Iridescent Tiger", 109, Rarity.UNCOMMON, mage.cards.i.IridescentTiger.class));
cards.add(new SetCardInfo("Island", 279, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Island", 279, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Jade-Cast Sentinel", 243, Rarity.COMMON, mage.cards.j.JadeCastSentinel.class)); cards.add(new SetCardInfo("Jade-Cast Sentinel", 243, Rarity.COMMON, mage.cards.j.JadeCastSentinel.class));
cards.add(new SetCardInfo("Jeskai Brushmaster", 195, Rarity.UNCOMMON, mage.cards.j.JeskaiBrushmaster.class)); cards.add(new SetCardInfo("Jeskai Brushmaster", 195, Rarity.UNCOMMON, mage.cards.j.JeskaiBrushmaster.class));
@ -95,17 +112,22 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Jeskai Shrinekeeper", 197, Rarity.UNCOMMON, mage.cards.j.JeskaiShrinekeeper.class)); cards.add(new SetCardInfo("Jeskai Shrinekeeper", 197, Rarity.UNCOMMON, mage.cards.j.JeskaiShrinekeeper.class));
cards.add(new SetCardInfo("Jungle Hollow", 258, Rarity.COMMON, mage.cards.j.JungleHollow.class)); cards.add(new SetCardInfo("Jungle Hollow", 258, Rarity.COMMON, mage.cards.j.JungleHollow.class));
cards.add(new SetCardInfo("Kheru Goldkeeper", 199, Rarity.UNCOMMON, mage.cards.k.KheruGoldkeeper.class)); cards.add(new SetCardInfo("Kheru Goldkeeper", 199, Rarity.UNCOMMON, mage.cards.k.KheruGoldkeeper.class));
cards.add(new SetCardInfo("Kin-Tree Nurturer", 83, Rarity.COMMON, mage.cards.k.KinTreeNurturer.class));
cards.add(new SetCardInfo("Kin-Tree Severance", 200, Rarity.UNCOMMON, mage.cards.k.KinTreeSeverance.class)); cards.add(new SetCardInfo("Kin-Tree Severance", 200, Rarity.UNCOMMON, mage.cards.k.KinTreeSeverance.class));
cards.add(new SetCardInfo("Kishla Skimmer", 201, Rarity.UNCOMMON, mage.cards.k.KishlaSkimmer.class)); cards.add(new SetCardInfo("Kishla Skimmer", 201, Rarity.UNCOMMON, mage.cards.k.KishlaSkimmer.class));
cards.add(new SetCardInfo("Kishla Trawlers", 50, Rarity.UNCOMMON, mage.cards.k.KishlaTrawlers.class)); cards.add(new SetCardInfo("Kishla Trawlers", 50, Rarity.UNCOMMON, mage.cards.k.KishlaTrawlers.class));
cards.add(new SetCardInfo("Kishla Village", 259, Rarity.RARE, mage.cards.k.KishlaVillage.class)); cards.add(new SetCardInfo("Kishla Village", 259, Rarity.RARE, mage.cards.k.KishlaVillage.class));
cards.add(new SetCardInfo("Knockout Maneuver", 147, Rarity.UNCOMMON, mage.cards.k.KnockoutManeuver.class));
cards.add(new SetCardInfo("Kotis, the Fangkeeper", 202, Rarity.RARE, mage.cards.k.KotisTheFangkeeper.class));
cards.add(new SetCardInfo("Krotiq Nestguard", 148, Rarity.COMMON, mage.cards.k.KrotiqNestguard.class)); cards.add(new SetCardInfo("Krotiq Nestguard", 148, Rarity.COMMON, mage.cards.k.KrotiqNestguard.class));
cards.add(new SetCardInfo("Lightfoot Technique", 14, Rarity.COMMON, mage.cards.l.LightfootTechnique.class)); cards.add(new SetCardInfo("Lightfoot Technique", 14, Rarity.COMMON, mage.cards.l.LightfootTechnique.class));
cards.add(new SetCardInfo("Loxodon Battle Priest", 15, Rarity.UNCOMMON, mage.cards.l.LoxodonBattlePriest.class)); cards.add(new SetCardInfo("Loxodon Battle Priest", 15, Rarity.UNCOMMON, mage.cards.l.LoxodonBattlePriest.class));
cards.add(new SetCardInfo("Mammoth Bellow", 205, Rarity.UNCOMMON, mage.cards.m.MammothBellow.class)); cards.add(new SetCardInfo("Mammoth Bellow", 205, Rarity.UNCOMMON, mage.cards.m.MammothBellow.class));
cards.add(new SetCardInfo("Mardu Devotee", 16, Rarity.COMMON, mage.cards.m.MarduDevotee.class)); cards.add(new SetCardInfo("Mardu Devotee", 16, Rarity.COMMON, mage.cards.m.MarduDevotee.class));
cards.add(new SetCardInfo("Mardu Monument", 245, Rarity.UNCOMMON, mage.cards.m.MarduMonument.class)); cards.add(new SetCardInfo("Mardu Monument", 245, Rarity.UNCOMMON, mage.cards.m.MarduMonument.class));
cards.add(new SetCardInfo("Marshal of the Lost", 207, Rarity.UNCOMMON, mage.cards.m.MarshalOfTheLost.class));
cards.add(new SetCardInfo("Meticulous Artisan", 112, Rarity.COMMON, mage.cards.m.MeticulousArtisan.class)); cards.add(new SetCardInfo("Meticulous Artisan", 112, Rarity.COMMON, mage.cards.m.MeticulousArtisan.class));
cards.add(new SetCardInfo("Molten Exhale", 113, Rarity.COMMON, mage.cards.m.MoltenExhale.class));
cards.add(new SetCardInfo("Monastery Messenger", 208, Rarity.COMMON, mage.cards.m.MonasteryMessenger.class)); cards.add(new SetCardInfo("Monastery Messenger", 208, Rarity.COMMON, mage.cards.m.MonasteryMessenger.class));
cards.add(new SetCardInfo("Mountain", 283, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 283, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mox Jasper", 246, Rarity.MYTHIC, mage.cards.m.MoxJasper.class)); cards.add(new SetCardInfo("Mox Jasper", 246, Rarity.MYTHIC, mage.cards.m.MoxJasper.class));
@ -114,34 +136,55 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Narset, Jeskai Waymaster", 209, Rarity.RARE, mage.cards.n.NarsetJeskaiWaymaster.class)); cards.add(new SetCardInfo("Narset, Jeskai Waymaster", 209, Rarity.RARE, mage.cards.n.NarsetJeskaiWaymaster.class));
cards.add(new SetCardInfo("Nature's Rhythm", 150, Rarity.RARE, mage.cards.n.NaturesRhythm.class)); cards.add(new SetCardInfo("Nature's Rhythm", 150, Rarity.RARE, mage.cards.n.NaturesRhythm.class));
cards.add(new SetCardInfo("Neriv, Heart of the Storm", 210, Rarity.MYTHIC, mage.cards.n.NerivHeartOfTheStorm.class)); cards.add(new SetCardInfo("Neriv, Heart of the Storm", 210, Rarity.MYTHIC, mage.cards.n.NerivHeartOfTheStorm.class));
cards.add(new SetCardInfo("Nightblade Brigade", 85, Rarity.COMMON, mage.cards.n.NightbladeBrigade.class));
cards.add(new SetCardInfo("Nomad Outpost", 263, Rarity.UNCOMMON, mage.cards.n.NomadOutpost.class)); cards.add(new SetCardInfo("Nomad Outpost", 263, Rarity.UNCOMMON, mage.cards.n.NomadOutpost.class));
cards.add(new SetCardInfo("Opulent Palace", 264, Rarity.UNCOMMON, mage.cards.o.OpulentPalace.class)); cards.add(new SetCardInfo("Opulent Palace", 264, Rarity.UNCOMMON, mage.cards.o.OpulentPalace.class));
cards.add(new SetCardInfo("Osseous Exhale", 17, Rarity.COMMON, mage.cards.o.OsseousExhale.class)); cards.add(new SetCardInfo("Osseous Exhale", 17, Rarity.COMMON, mage.cards.o.OsseousExhale.class));
cards.add(new SetCardInfo("Overwhelming Surge", 115, Rarity.UNCOMMON, mage.cards.o.OverwhelmingSurge.class));
cards.add(new SetCardInfo("Piercing Exhale", 151, Rarity.COMMON, mage.cards.p.PiercingExhale.class)); cards.add(new SetCardInfo("Piercing Exhale", 151, Rarity.COMMON, mage.cards.p.PiercingExhale.class));
cards.add(new SetCardInfo("Plains", 277, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Plains", 277, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Poised Practitioner", 18, Rarity.COMMON, mage.cards.p.PoisedPractitioner.class));
cards.add(new SetCardInfo("Qarsi Revenant", 86, Rarity.RARE, mage.cards.q.QarsiRevenant.class)); cards.add(new SetCardInfo("Qarsi Revenant", 86, Rarity.RARE, mage.cards.q.QarsiRevenant.class));
cards.add(new SetCardInfo("Rainveil Rejuvenator", 152, Rarity.UNCOMMON, mage.cards.r.RainveilRejuvenator.class));
cards.add(new SetCardInfo("Rakshasa's Bargain", 214, Rarity.UNCOMMON, mage.cards.r.RakshasasBargain.class)); cards.add(new SetCardInfo("Rakshasa's Bargain", 214, Rarity.UNCOMMON, mage.cards.r.RakshasasBargain.class));
cards.add(new SetCardInfo("Rally the Monastery", 19, Rarity.UNCOMMON, mage.cards.r.RallyTheMonastery.class)); cards.add(new SetCardInfo("Rally the Monastery", 19, Rarity.UNCOMMON, mage.cards.r.RallyTheMonastery.class));
cards.add(new SetCardInfo("Rebellious Strike", 20, Rarity.COMMON, mage.cards.r.RebelliousStrike.class)); cards.add(new SetCardInfo("Rebellious Strike", 20, Rarity.COMMON, mage.cards.r.RebelliousStrike.class));
cards.add(new SetCardInfo("Rediscover the Way", 215, Rarity.RARE, mage.cards.r.RediscoverTheWay.class));
cards.add(new SetCardInfo("Reigning Victor", 216, Rarity.COMMON, mage.cards.r.ReigningVictor.class)); cards.add(new SetCardInfo("Reigning Victor", 216, Rarity.COMMON, mage.cards.r.ReigningVictor.class));
cards.add(new SetCardInfo("Reputable Merchant", 217, Rarity.COMMON, mage.cards.r.ReputableMerchant.class));
cards.add(new SetCardInfo("Rescue Leopard", 116, Rarity.COMMON, mage.cards.r.RescueLeopard.class));
cards.add(new SetCardInfo("Revival of the Ancestors", 218, Rarity.RARE, mage.cards.r.RevivalOfTheAncestors.class));
cards.add(new SetCardInfo("Ringing Strike Mastery", 53, Rarity.COMMON, mage.cards.r.RingingStrikeMastery.class)); cards.add(new SetCardInfo("Ringing Strike Mastery", 53, Rarity.COMMON, mage.cards.r.RingingStrikeMastery.class));
cards.add(new SetCardInfo("Riverwalk Technique", 54, Rarity.COMMON, mage.cards.r.RiverwalkTechnique.class));
cards.add(new SetCardInfo("Roamer's Routine", 154, Rarity.COMMON, mage.cards.r.RoamersRoutine.class)); cards.add(new SetCardInfo("Roamer's Routine", 154, Rarity.COMMON, mage.cards.r.RoamersRoutine.class));
cards.add(new SetCardInfo("Roar of Endless Song", 220, Rarity.RARE, mage.cards.r.RoarOfEndlessSong.class)); cards.add(new SetCardInfo("Roar of Endless Song", 220, Rarity.RARE, mage.cards.r.RoarOfEndlessSong.class));
cards.add(new SetCardInfo("Roiling Dragonstorm", 55, Rarity.UNCOMMON, mage.cards.r.RoilingDragonstorm.class)); cards.add(new SetCardInfo("Roiling Dragonstorm", 55, Rarity.UNCOMMON, mage.cards.r.RoilingDragonstorm.class));
cards.add(new SetCardInfo("Rugged Highlands", 265, Rarity.COMMON, mage.cards.r.RuggedHighlands.class)); cards.add(new SetCardInfo("Rugged Highlands", 265, Rarity.COMMON, mage.cards.r.RuggedHighlands.class));
cards.add(new SetCardInfo("Sage of the Fang", 155, Rarity.UNCOMMON, mage.cards.s.SageOfTheFang.class));
cards.add(new SetCardInfo("Sagu Pummeler", 156, Rarity.COMMON, mage.cards.s.SaguPummeler.class));
cards.add(new SetCardInfo("Salt Road Packbeast", 23, Rarity.COMMON, mage.cards.s.SaltRoadPackbeast.class)); cards.add(new SetCardInfo("Salt Road Packbeast", 23, Rarity.COMMON, mage.cards.s.SaltRoadPackbeast.class));
cards.add(new SetCardInfo("Salt Road Skirmish", 88, Rarity.UNCOMMON, mage.cards.s.SaltRoadSkirmish.class));
cards.add(new SetCardInfo("Sandskitter Outrider", 89, Rarity.COMMON, mage.cards.s.SandskitterOutrider.class));
cards.add(new SetCardInfo("Sandsteppe Citadel", 266, Rarity.UNCOMMON, mage.cards.s.SandsteppeCitadel.class)); cards.add(new SetCardInfo("Sandsteppe Citadel", 266, Rarity.UNCOMMON, mage.cards.s.SandsteppeCitadel.class));
cards.add(new SetCardInfo("Sarkhan's Resolve", 158, Rarity.COMMON, mage.cards.s.SarkhansResolve.class)); cards.add(new SetCardInfo("Sarkhan's Resolve", 158, Rarity.COMMON, mage.cards.s.SarkhansResolve.class));
cards.add(new SetCardInfo("Sarkhan, Dragon Ascendant", 118, Rarity.RARE, mage.cards.s.SarkhanDragonAscendant.class));
cards.add(new SetCardInfo("Scoured Barrens", 267, Rarity.COMMON, mage.cards.s.ScouredBarrens.class)); cards.add(new SetCardInfo("Scoured Barrens", 267, Rarity.COMMON, mage.cards.s.ScouredBarrens.class));
cards.add(new SetCardInfo("Seize Opportunity", 119, Rarity.COMMON, mage.cards.s.SeizeOpportunity.class)); cards.add(new SetCardInfo("Seize Opportunity", 119, Rarity.COMMON, mage.cards.s.SeizeOpportunity.class));
cards.add(new SetCardInfo("Shiko, Paragon of the Way", 223, Rarity.MYTHIC, mage.cards.s.ShikoParagonOfTheWay.class)); cards.add(new SetCardInfo("Shiko, Paragon of the Way", 223, Rarity.MYTHIC, mage.cards.s.ShikoParagonOfTheWay.class));
cards.add(new SetCardInfo("Shock Brigade", 120, Rarity.COMMON, mage.cards.s.ShockBrigade.class)); cards.add(new SetCardInfo("Shock Brigade", 120, Rarity.COMMON, mage.cards.s.ShockBrigade.class));
cards.add(new SetCardInfo("Shocking Sharpshooter", 121, Rarity.UNCOMMON, mage.cards.s.ShockingSharpshooter.class)); cards.add(new SetCardInfo("Shocking Sharpshooter", 121, Rarity.UNCOMMON, mage.cards.s.ShockingSharpshooter.class));
cards.add(new SetCardInfo("Sibsig Appraiser", 56, Rarity.COMMON, mage.cards.s.SibsigAppraiser.class));
cards.add(new SetCardInfo("Sinkhole Surveyor", 93, Rarity.RARE, mage.cards.s.SinkholeSurveyor.class)); cards.add(new SetCardInfo("Sinkhole Surveyor", 93, Rarity.RARE, mage.cards.s.SinkholeSurveyor.class));
cards.add(new SetCardInfo("Skirmish Rhino", 224, Rarity.UNCOMMON, mage.cards.s.SkirmishRhino.class)); cards.add(new SetCardInfo("Skirmish Rhino", 224, Rarity.UNCOMMON, mage.cards.s.SkirmishRhino.class));
cards.add(new SetCardInfo("Smile at Death", 24, Rarity.MYTHIC, mage.cards.s.SmileAtDeath.class)); cards.add(new SetCardInfo("Smile at Death", 24, Rarity.MYTHIC, mage.cards.s.SmileAtDeath.class));
cards.add(new SetCardInfo("Snakeskin Veil", 159, Rarity.COMMON, mage.cards.s.SnakeskinVeil.class)); cards.add(new SetCardInfo("Snakeskin Veil", 159, Rarity.COMMON, mage.cards.s.SnakeskinVeil.class));
cards.add(new SetCardInfo("Snowmelt Stag", 57, Rarity.COMMON, mage.cards.s.SnowmeltStag.class));
cards.add(new SetCardInfo("Songcrafter Mage", 225, Rarity.RARE, mage.cards.s.SongcrafterMage.class));
cards.add(new SetCardInfo("Sonic Shrieker", 226, Rarity.UNCOMMON, mage.cards.s.SonicShrieker.class));
cards.add(new SetCardInfo("Spectral Denial", 58, Rarity.UNCOMMON, mage.cards.s.SpectralDenial.class)); cards.add(new SetCardInfo("Spectral Denial", 58, Rarity.UNCOMMON, mage.cards.s.SpectralDenial.class));
cards.add(new SetCardInfo("Stadium Headliner", 122, Rarity.RARE, mage.cards.s.StadiumHeadliner.class));
cards.add(new SetCardInfo("Static Snare", 26, Rarity.UNCOMMON, mage.cards.s.StaticSnare.class));
cards.add(new SetCardInfo("Stormbeacon Blade", 27, Rarity.UNCOMMON, mage.cards.s.StormbeaconBlade.class));
cards.add(new SetCardInfo("Stormplain Detainment", 28, Rarity.COMMON, mage.cards.s.StormplainDetainment.class)); cards.add(new SetCardInfo("Stormplain Detainment", 28, Rarity.COMMON, mage.cards.s.StormplainDetainment.class));
cards.add(new SetCardInfo("Stormscale Scion", 123, Rarity.MYTHIC, mage.cards.s.StormscaleScion.class)); cards.add(new SetCardInfo("Stormscale Scion", 123, Rarity.MYTHIC, mage.cards.s.StormscaleScion.class));
cards.add(new SetCardInfo("Sultai Devotee", 160, Rarity.COMMON, mage.cards.s.SultaiDevotee.class)); cards.add(new SetCardInfo("Sultai Devotee", 160, Rarity.COMMON, mage.cards.s.SultaiDevotee.class));
@ -150,13 +193,20 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Sunset Strikemaster", 126, Rarity.UNCOMMON, mage.cards.s.SunsetStrikemaster.class)); cards.add(new SetCardInfo("Sunset Strikemaster", 126, Rarity.UNCOMMON, mage.cards.s.SunsetStrikemaster.class));
cards.add(new SetCardInfo("Swamp", 281, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swamp", 281, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swiftwater Cliffs", 268, Rarity.COMMON, mage.cards.s.SwiftwaterCliffs.class)); cards.add(new SetCardInfo("Swiftwater Cliffs", 268, Rarity.COMMON, mage.cards.s.SwiftwaterCliffs.class));
cards.add(new SetCardInfo("Teeming Dragonstorm", 30, Rarity.UNCOMMON, mage.cards.t.TeemingDragonstorm.class));
cards.add(new SetCardInfo("Tempest Hawk", 31, Rarity.COMMON, mage.cards.t.TempestHawk.class)); cards.add(new SetCardInfo("Tempest Hawk", 31, Rarity.COMMON, mage.cards.t.TempestHawk.class));
cards.add(new SetCardInfo("Temur Devotee", 61, Rarity.COMMON, mage.cards.t.TemurDevotee.class)); cards.add(new SetCardInfo("Temur Devotee", 61, Rarity.COMMON, mage.cards.t.TemurDevotee.class));
cards.add(new SetCardInfo("Temur Monument", 248, Rarity.UNCOMMON, mage.cards.t.TemurMonument.class)); cards.add(new SetCardInfo("Temur Monument", 248, Rarity.UNCOMMON, mage.cards.t.TemurMonument.class));
cards.add(new SetCardInfo("Temur Tawnyback", 229, Rarity.COMMON, mage.cards.t.TemurTawnyback.class)); cards.add(new SetCardInfo("Temur Tawnyback", 229, Rarity.COMMON, mage.cards.t.TemurTawnyback.class));
cards.add(new SetCardInfo("The Sibsig Ceremony", 91, Rarity.RARE, mage.cards.t.TheSibsigCeremony.class));
cards.add(new SetCardInfo("Thornwood Falls", 269, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class)); cards.add(new SetCardInfo("Thornwood Falls", 269, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class));
cards.add(new SetCardInfo("Thunder of Unity", 231, Rarity.RARE, mage.cards.t.ThunderOfUnity.class));
cards.add(new SetCardInfo("Trade Route Envoy", 163, Rarity.COMMON, mage.cards.t.TradeRouteEnvoy.class));
cards.add(new SetCardInfo("Tranquil Cove", 270, Rarity.COMMON, mage.cards.t.TranquilCove.class)); cards.add(new SetCardInfo("Tranquil Cove", 270, Rarity.COMMON, mage.cards.t.TranquilCove.class));
cards.add(new SetCardInfo("Traveling Botanist", 164, Rarity.UNCOMMON, mage.cards.t.TravelingBotanist.class));
cards.add(new SetCardInfo("Twin Bolt", 128, Rarity.COMMON, mage.cards.t.TwinBolt.class));
cards.add(new SetCardInfo("Ugin, Eye of the Storms", 1, Rarity.MYTHIC, mage.cards.u.UginEyeOfTheStorms.class)); cards.add(new SetCardInfo("Ugin, Eye of the Storms", 1, Rarity.MYTHIC, mage.cards.u.UginEyeOfTheStorms.class));
cards.add(new SetCardInfo("Unburied Earthcarver", 95, Rarity.COMMON, mage.cards.u.UnburiedEarthcarver.class));
cards.add(new SetCardInfo("Underfoot Underdogs", 129, Rarity.COMMON, mage.cards.u.UnderfootUnderdogs.class)); cards.add(new SetCardInfo("Underfoot Underdogs", 129, Rarity.COMMON, mage.cards.u.UnderfootUnderdogs.class));
cards.add(new SetCardInfo("Undergrowth Leopard", 165, Rarity.COMMON, mage.cards.u.UndergrowthLeopard.class)); cards.add(new SetCardInfo("Undergrowth Leopard", 165, Rarity.COMMON, mage.cards.u.UndergrowthLeopard.class));
cards.add(new SetCardInfo("Unending Whisper", 62, Rarity.COMMON, mage.cards.u.UnendingWhisper.class)); cards.add(new SetCardInfo("Unending Whisper", 62, Rarity.COMMON, mage.cards.u.UnendingWhisper.class));
@ -165,14 +215,21 @@ public final class TarkirDragonstorm extends ExpansionSet {
cards.add(new SetCardInfo("Unsparing Boltcaster", 130, Rarity.UNCOMMON, mage.cards.u.UnsparingBoltcaster.class)); cards.add(new SetCardInfo("Unsparing Boltcaster", 130, Rarity.UNCOMMON, mage.cards.u.UnsparingBoltcaster.class));
cards.add(new SetCardInfo("Ureni's Rebuff", 63, Rarity.UNCOMMON, mage.cards.u.UrenisRebuff.class)); cards.add(new SetCardInfo("Ureni's Rebuff", 63, Rarity.UNCOMMON, mage.cards.u.UrenisRebuff.class));
cards.add(new SetCardInfo("Venerated Stormsinger", 97, Rarity.UNCOMMON, mage.cards.v.VeneratedStormsinger.class)); cards.add(new SetCardInfo("Venerated Stormsinger", 97, Rarity.UNCOMMON, mage.cards.v.VeneratedStormsinger.class));
cards.add(new SetCardInfo("Veteran Ice Climber", 64, Rarity.UNCOMMON, mage.cards.v.VeteranIceClimber.class));
cards.add(new SetCardInfo("Voice of Victory", 33, Rarity.RARE, mage.cards.v.VoiceOfVictory.class)); cards.add(new SetCardInfo("Voice of Victory", 33, Rarity.RARE, mage.cards.v.VoiceOfVictory.class));
cards.add(new SetCardInfo("War Effort", 131, Rarity.UNCOMMON, mage.cards.w.WarEffort.class));
cards.add(new SetCardInfo("Watcher of the Wayside", 249, Rarity.COMMON, mage.cards.w.WatcherOfTheWayside.class)); cards.add(new SetCardInfo("Watcher of the Wayside", 249, Rarity.COMMON, mage.cards.w.WatcherOfTheWayside.class));
cards.add(new SetCardInfo("Wayspeaker Bodyguard", 34, Rarity.UNCOMMON, mage.cards.w.WayspeakerBodyguard.class));
cards.add(new SetCardInfo("Wild Ride", 132, Rarity.COMMON, mage.cards.w.WildRide.class));
cards.add(new SetCardInfo("Wind-Scarred Crag", 271, Rarity.COMMON, mage.cards.w.WindScarredCrag.class)); cards.add(new SetCardInfo("Wind-Scarred Crag", 271, Rarity.COMMON, mage.cards.w.WindScarredCrag.class));
cards.add(new SetCardInfo("Wingblade Disciple", 65, Rarity.UNCOMMON, mage.cards.w.WingbladeDisciple.class));
cards.add(new SetCardInfo("Wingspan Stride", 66, Rarity.COMMON, mage.cards.w.WingspanStride.class)); cards.add(new SetCardInfo("Wingspan Stride", 66, Rarity.COMMON, mage.cards.w.WingspanStride.class));
cards.add(new SetCardInfo("Winternight Stories", 67, Rarity.RARE, mage.cards.w.WinternightStories.class)); cards.add(new SetCardInfo("Winternight Stories", 67, Rarity.RARE, mage.cards.w.WinternightStories.class));
cards.add(new SetCardInfo("Worthy Cost", 99, Rarity.COMMON, mage.cards.w.WorthyCost.class)); cards.add(new SetCardInfo("Worthy Cost", 99, Rarity.COMMON, mage.cards.w.WorthyCost.class));
cards.add(new SetCardInfo("Yathan Roadwatcher", 236, Rarity.RARE, mage.cards.y.YathanRoadwatcher.class));
cards.add(new SetCardInfo("Yathan Tombguard", 100, Rarity.UNCOMMON, mage.cards.y.YathanTombguard.class)); cards.add(new SetCardInfo("Yathan Tombguard", 100, Rarity.UNCOMMON, mage.cards.y.YathanTombguard.class));
cards.add(new SetCardInfo("Zurgo's Vanguard", 133, Rarity.UNCOMMON, mage.cards.z.ZurgosVanguard.class)); cards.add(new SetCardInfo("Zurgo's Vanguard", 133, Rarity.UNCOMMON, mage.cards.z.ZurgosVanguard.class));
cards.add(new SetCardInfo("Zurgo, Thunder's Decree", 237, Rarity.RARE, mage.cards.z.ZurgoThundersDecree.class));
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName()));
} }

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