diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml
index 776034c3ba5..5be94dfac9c 100644
--- a/Mage.Client/pom.xml
+++ b/Mage.Client/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
org.mage
diff --git a/Mage.Client/release/sample-decks/2013/Standard/DailyMTG Reconstructed - Sliving the good Life/Douglas Scheinberg's Séance Combo.dck b/Mage.Client/release/sample-decks/2013/Standard/DailyMTG Reconstructed - Sliving the good Life/Douglas Scheinberg's Seance Combo.dck
similarity index 96%
rename from Mage.Client/release/sample-decks/2013/Standard/DailyMTG Reconstructed - Sliving the good Life/Douglas Scheinberg's Séance Combo.dck
rename to Mage.Client/release/sample-decks/2013/Standard/DailyMTG Reconstructed - Sliving the good Life/Douglas Scheinberg's Seance Combo.dck
index 6cb6e9d096e..a11ea95c633 100644
--- a/Mage.Client/release/sample-decks/2013/Standard/DailyMTG Reconstructed - Sliving the good Life/Douglas Scheinberg's Séance Combo.dck
+++ b/Mage.Client/release/sample-decks/2013/Standard/DailyMTG Reconstructed - Sliving the good Life/Douglas Scheinberg's Seance Combo.dck
@@ -1,22 +1,22 @@
-NAME:Douglas Scheinberg's Séance Combo
-1 [AVR:42] Alchemist's Apprentice
-4 [RTR:1] Angel of Serenity
-1 [ISD:68] Mirror-Mad Phantasm
-2 [ISD:248] Sulfur Falls
-4 [RTR:249] Transguild Promenade
-3 [RTR:247] Steam Vents
-1 [AVR:1] Angel of Glory's Rise
-4 [ISD:122] Unburial Rites
-4 [RTR:201] Supreme Verdict
-1 [ISD:55] Forbidden Alchemy
-1 [ISD:61] Laboratory Maniac
-3 [ISD:238] Clifftop Retreat
-3 [ISD:43] Armored Skaab
-2 [GTC:245] Sacred Foundry
-4 [M13:69] Sphinx of Uthuun
-3 [M13:225] Glacial Fortress
-4 [RTR:172] Izzet Charm
-2 [AVR:229] Slayers' Stronghold
-2 [AVR:226] Cavern of Souls
-4 [DKA:87] Faithless Looting
-4 [RTR:241] Hallowed Fountain
+NAME:Douglas Scheinberg's Séance Combo
+1 [AVR:42] Alchemist's Apprentice
+4 [RTR:1] Angel of Serenity
+1 [ISD:68] Mirror-Mad Phantasm
+2 [ISD:248] Sulfur Falls
+4 [RTR:249] Transguild Promenade
+3 [RTR:247] Steam Vents
+1 [AVR:1] Angel of Glory's Rise
+4 [ISD:122] Unburial Rites
+4 [RTR:201] Supreme Verdict
+1 [ISD:55] Forbidden Alchemy
+1 [ISD:61] Laboratory Maniac
+3 [ISD:238] Clifftop Retreat
+3 [ISD:43] Armored Skaab
+2 [GTC:245] Sacred Foundry
+4 [M13:69] Sphinx of Uthuun
+3 [M13:225] Glacial Fortress
+4 [RTR:172] Izzet Charm
+2 [AVR:229] Slayers' Stronghold
+2 [AVR:226] Cavern of Souls
+4 [DKA:87] Faithless Looting
+4 [RTR:241] Hallowed Fountain
diff --git a/Mage.Client/release/sample-decks/2013/Standard/GP Guadalajara (May 26)/Emmanuel RamÃrez's Reanimator.dck b/Mage.Client/release/sample-decks/2013/Standard/GP Guadalajara (May 26)/Emmanuel Ramirez's Reanimator.dck
similarity index 96%
rename from Mage.Client/release/sample-decks/2013/Standard/GP Guadalajara (May 26)/Emmanuel RamÃrez's Reanimator.dck
rename to Mage.Client/release/sample-decks/2013/Standard/GP Guadalajara (May 26)/Emmanuel Ramirez's Reanimator.dck
index db9096fb72d..c8bf400e7de 100644
--- a/Mage.Client/release/sample-decks/2013/Standard/GP Guadalajara (May 26)/Emmanuel RamÃrez's Reanimator.dck
+++ b/Mage.Client/release/sample-decks/2013/Standard/GP Guadalajara (May 26)/Emmanuel Ramirez's Reanimator.dck
@@ -1,31 +1,31 @@
-NAME:Emmanuel Ramírez's Reanimator
-4 [ISD:170] Avacyn's Pilgrim
-2 [ISD:249] Woodland Cemetery
-3 [M13:159] Acidic Slime
-3 [ISD:196] Mulch
-1 [ISD:239] Gavony Township
-3 [ISD:15] Fiend Hunter
-3 [RTR:1] Angel of Serenity
-2 [AVR:226] Cavern of Souls
-4 [AVR:32] Restoration Angel
-2 [ISD:242] Isolated Chapel
-4 [RTR:248] Temple Garden
-4 [RTR:243] Overgrown Tomb
-3 [M13:160] Arbor Elf
-4 [M13:193] Thragtusk
-2 [DGM:103] Sin Collector
-4 [RTR:165] Grisly Salvage
-3 [M13:229] Sunpetal Grove
-3 [RTR:270] Forest
-2 [GTC:242] Godless Shrine
-4 [ISD:122] Unburial Rites
-SB: 1 [RTR:148] Centaur Healer
-SB: 2 [DKA:17] Ray of Revelation
-SB: 1 [M13:159] Acidic Slime
-SB: 2 [ISD:181] Garruk Relentless
-SB: 2 [RTR:141] Abrupt Decay
-SB: 1 [ISD:15] Fiend Hunter
-SB: 2 [RTR:213] Deathrite Shaman
-SB: 1 [DGM:103] Sin Collector
-SB: 2 [RTR:178] Loxodon Smiter
-SB: 1 [ISD:115] Sever the Bloodline
+NAME:Emmanuel Ramírez's Reanimator
+4 [ISD:170] Avacyn's Pilgrim
+2 [ISD:249] Woodland Cemetery
+3 [M13:159] Acidic Slime
+3 [ISD:196] Mulch
+1 [ISD:239] Gavony Township
+3 [ISD:15] Fiend Hunter
+3 [RTR:1] Angel of Serenity
+2 [AVR:226] Cavern of Souls
+4 [AVR:32] Restoration Angel
+2 [ISD:242] Isolated Chapel
+4 [RTR:248] Temple Garden
+4 [RTR:243] Overgrown Tomb
+3 [M13:160] Arbor Elf
+4 [M13:193] Thragtusk
+2 [DGM:103] Sin Collector
+4 [RTR:165] Grisly Salvage
+3 [M13:229] Sunpetal Grove
+3 [RTR:270] Forest
+2 [GTC:242] Godless Shrine
+4 [ISD:122] Unburial Rites
+SB: 1 [RTR:148] Centaur Healer
+SB: 2 [DKA:17] Ray of Revelation
+SB: 1 [M13:159] Acidic Slime
+SB: 2 [ISD:181] Garruk Relentless
+SB: 2 [RTR:141] Abrupt Decay
+SB: 1 [ISD:15] Fiend Hunter
+SB: 2 [RTR:213] Deathrite Shaman
+SB: 1 [DGM:103] Sin Collector
+SB: 2 [RTR:178] Loxodon Smiter
+SB: 1 [ISD:115] Sever the Bloodline
diff --git a/Mage.Client/release/sample-decks/2013/Standard/GP Quebec City/Frédéric Mercier's Esper Control.dck b/Mage.Client/release/sample-decks/2013/Standard/GP Quebec City/Frederic Mercier's Esper Control.dck
similarity index 96%
rename from Mage.Client/release/sample-decks/2013/Standard/GP Quebec City/Frédéric Mercier's Esper Control.dck
rename to Mage.Client/release/sample-decks/2013/Standard/GP Quebec City/Frederic Mercier's Esper Control.dck
index 40acc0590eb..70622a3155f 100644
--- a/Mage.Client/release/sample-decks/2013/Standard/GP Quebec City/Frédéric Mercier's Esper Control.dck
+++ b/Mage.Client/release/sample-decks/2013/Standard/GP Quebec City/Frederic Mercier's Esper Control.dck
@@ -1,33 +1,33 @@
-NAME:Frédéric Mercier's Esper Control
-2 [M13:26] Planar Cleansing
-1 [RTR:250] Plains
-4 [M13:225] Glacial Fortress
-2 [GTC:63] Devour Flesh
-4 [ISD:83] Think Twice
-4 [RTR:145] Azorius Charm
-2 [ISD:78] Snapcaster Mage
-2 [GTC:249] Watery Grave
-1 [RTR:82] Ultimate Price
-1 [RTR:156] Dramatic Rescue
-2 [GPT:157] Godless Shrine
-3 [AVR:32] Restoration Angel
-4 [M13:43] Augur of Bolas
-4 [ISD:242] Isolated Chapel
-4 [RTR:201] Supreme Verdict
-2 [MIR:61] Dissipate
-1 [RTR:256] Island
-1 [RTR:255] Island
-4 [ISD:245] Nephalia Drownyard
-4 [RTR:241] Hallowed Fountain
-4 [M13:223] Drowned Catacomb
-4 [RTR:200] Sphinx's Revelation
-SB: 1 [WWK:26] Dispel
-SB: 3 [AVR:104] Gloom Surgeon
-SB: 2 [M11:96] Duress
-SB: 2 [ISD:236] Witchbane Orb
-SB: 1 [RTR:18] Rest in Peace
-SB: 1 [RTR:36] Dispel
-SB: 1 [SOK:158] Pithing Needle
-SB: 1 [RTR:47] Psychic Spiral
-SB: 2 [M13:56] Jace, Memory Adept
-SB: 1 [M12:69] Negate
+NAME:Frédéric Mercier's Esper Control
+2 [M13:26] Planar Cleansing
+1 [RTR:250] Plains
+4 [M13:225] Glacial Fortress
+2 [GTC:63] Devour Flesh
+4 [ISD:83] Think Twice
+4 [RTR:145] Azorius Charm
+2 [ISD:78] Snapcaster Mage
+2 [GTC:249] Watery Grave
+1 [RTR:82] Ultimate Price
+1 [RTR:156] Dramatic Rescue
+2 [GPT:157] Godless Shrine
+3 [AVR:32] Restoration Angel
+4 [M13:43] Augur of Bolas
+4 [ISD:242] Isolated Chapel
+4 [RTR:201] Supreme Verdict
+2 [MIR:61] Dissipate
+1 [RTR:256] Island
+1 [RTR:255] Island
+4 [ISD:245] Nephalia Drownyard
+4 [RTR:241] Hallowed Fountain
+4 [M13:223] Drowned Catacomb
+4 [RTR:200] Sphinx's Revelation
+SB: 1 [WWK:26] Dispel
+SB: 3 [AVR:104] Gloom Surgeon
+SB: 2 [M11:96] Duress
+SB: 2 [ISD:236] Witchbane Orb
+SB: 1 [RTR:18] Rest in Peace
+SB: 1 [RTR:36] Dispel
+SB: 1 [SOK:158] Pithing Needle
+SB: 1 [RTR:47] Psychic Spiral
+SB: 2 [M13:56] Jace, Memory Adept
+SB: 1 [M12:69] Negate
diff --git a/Mage.Client/release/sample-decks/2013/Standard/GP Verona/Jérémy Dezani's Jund Midrange.dck b/Mage.Client/release/sample-decks/2013/Standard/GP Verona/Jeremy Dezani's Jund Midrange.dck
similarity index 96%
rename from Mage.Client/release/sample-decks/2013/Standard/GP Verona/Jérémy Dezani's Jund Midrange.dck
rename to Mage.Client/release/sample-decks/2013/Standard/GP Verona/Jeremy Dezani's Jund Midrange.dck
index 3a4b62e0147..e5e32ee185a 100644
--- a/Mage.Client/release/sample-decks/2013/Standard/GP Verona/Jérémy Dezani's Jund Midrange.dck
+++ b/Mage.Client/release/sample-decks/2013/Standard/GP Verona/Jeremy Dezani's Jund Midrange.dck
@@ -1,36 +1,36 @@
-NAME:Jérémy Dezani's Jund Midrange
-4 [M13:170] Farseek
-3 [AVR:129] Bonfire of the Damned
-1 [DKA:76] Tragic Slip
-4 [ISD:249] Woodland Cemetery
-2 [RTR:141] Abrupt Decay
-3 [ISD:105] Liliana of the Veil
-3 [M13:222] Dragonskull Summit
-1 [RTR:82] Ultimate Price
-2 [ISD:243] Kessig Wolf Run
-1 [M13:217] Staff of Nin
-1 [M13:101] Murder
-4 [GTC:247] Stomping Ground
-3 [ISD:215] Olivia Voldaren
-2 [M13:174] Garruk, Primal Hunter
-2 [RTR:188] Rakdos's Return
-4 [DKA:140] Huntmaster of the Fells
-4 [RTR:243] Overgrown Tomb
-2 [M13:160] Arbor Elf
-4 [M13:193] Thragtusk
-4 [RTR:238] Blood Crypt
-2 [M13:228] Rootbound Crag
-1 [RTR:101] Mizzium Mortars
-1 [RTR:157] Dreadbore
-2 [RTR:270] Forest
-SB: 1 [RTR:188] Rakdos's Return
-SB: 1 [AVR:129] Bonfire of the Damned
-SB: 1 [DKA:76] Tragic Slip
-SB: 2 [M13:159] Acidic Slime
-SB: 1 [RTR:141] Abrupt Decay
-SB: 1 [DKA:149] Grafdigger's Cage
-SB: 2 [M13:90] Duress
-SB: 1 [M13:219] Tormod's Crypt
-SB: 3 [RTR:197] Slaughter Games
-SB: 1 [RTR:101] Mizzium Mortars
-SB: 1 [AVR:149] Pillar of Flame
+NAME:Jérémy Dezani's Jund Midrange
+4 [M13:170] Farseek
+3 [AVR:129] Bonfire of the Damned
+1 [DKA:76] Tragic Slip
+4 [ISD:249] Woodland Cemetery
+2 [RTR:141] Abrupt Decay
+3 [ISD:105] Liliana of the Veil
+3 [M13:222] Dragonskull Summit
+1 [RTR:82] Ultimate Price
+2 [ISD:243] Kessig Wolf Run
+1 [M13:217] Staff of Nin
+1 [M13:101] Murder
+4 [GTC:247] Stomping Ground
+3 [ISD:215] Olivia Voldaren
+2 [M13:174] Garruk, Primal Hunter
+2 [RTR:188] Rakdos's Return
+4 [DKA:140] Huntmaster of the Fells
+4 [RTR:243] Overgrown Tomb
+2 [M13:160] Arbor Elf
+4 [M13:193] Thragtusk
+4 [RTR:238] Blood Crypt
+2 [M13:228] Rootbound Crag
+1 [RTR:101] Mizzium Mortars
+1 [RTR:157] Dreadbore
+2 [RTR:270] Forest
+SB: 1 [RTR:188] Rakdos's Return
+SB: 1 [AVR:129] Bonfire of the Damned
+SB: 1 [DKA:76] Tragic Slip
+SB: 2 [M13:159] Acidic Slime
+SB: 1 [RTR:141] Abrupt Decay
+SB: 1 [DKA:149] Grafdigger's Cage
+SB: 2 [M13:90] Duress
+SB: 1 [M13:219] Tormod's Crypt
+SB: 3 [RTR:197] Slaughter Games
+SB: 1 [RTR:101] Mizzium Mortars
+SB: 1 [AVR:149] Pillar of Flame
diff --git a/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Philipp Schönegger's Miracles.dck b/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Philipp Schonegger's Miracles.dck
similarity index 96%
rename from Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Philipp Schönegger's Miracles.dck
rename to Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Philipp Schonegger's Miracles.dck
index 1959f8d1e65..791dfa7183a 100644
--- a/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Philipp Schönegger's Miracles.dck
+++ b/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Philipp Schonegger's Miracles.dck
@@ -1,32 +1,32 @@
-NAME:Philipp Schönegger's Miracles
-4 [C13:341] Island
-4 [CHK:268] Sensei's Divining Top
-4 [ONS:316] Flooded Strand
-2 [AVR:20] Entreat the Angels
-3 [WWK:31] Jace, the Mind Sculptor
-3 [ISD:78] Snapcaster Mage
-4 [ALL:42] Force of Will
-2 [ZEN:211] Arid Mesa
-2 [M12:73] Ponder
-1 [MMA:70] Vendilion Clique
-4 [CMD:40] Brainstorm
-1 [LEG:248] Karakas
-2 [7ED:67] Counterspell
-3 [CSP:31] Counterbalance
-4 [AVR:38] Terminus
-4 [ZEN:223] Scalding Tarn
-2 [ZEN:67] Spell Pierce
-2 [C13:337] Plains
-2 [3ED:306] Volcanic Island
-3 [3ED:304] Tundra
-4 [DDF:22] Swords to Plowshares
-SB: 1 [5ED:262] Pyroblast
-SB: 1 [AVR:20] Entreat the Angels
-SB: 3 [CMD:46] Flusterstorm
-SB: 2 [4ED:236] Red Elemental Blast
-SB: 1 [TSB:6] Disenchant
-SB: 2 [MMA:204] Engineered Explosives
-SB: 1 [7ED:67] Counterspell
-SB: 1 [RTR:201] Supreme Verdict
-SB: 1 [MMA:70] Vendilion Clique
-SB: 2 [RTR:18] Rest in Peace
+NAME:Philipp Schönegger's Miracles
+4 [C13:341] Island
+4 [CHK:268] Sensei's Divining Top
+4 [ONS:316] Flooded Strand
+2 [AVR:20] Entreat the Angels
+3 [WWK:31] Jace, the Mind Sculptor
+3 [ISD:78] Snapcaster Mage
+4 [ALL:42] Force of Will
+2 [ZEN:211] Arid Mesa
+2 [M12:73] Ponder
+1 [MMA:70] Vendilion Clique
+4 [CMD:40] Brainstorm
+1 [LEG:248] Karakas
+2 [7ED:67] Counterspell
+3 [CSP:31] Counterbalance
+4 [AVR:38] Terminus
+4 [ZEN:223] Scalding Tarn
+2 [ZEN:67] Spell Pierce
+2 [C13:337] Plains
+2 [3ED:306] Volcanic Island
+3 [3ED:304] Tundra
+4 [DDF:22] Swords to Plowshares
+SB: 1 [5ED:262] Pyroblast
+SB: 1 [AVR:20] Entreat the Angels
+SB: 3 [CMD:46] Flusterstorm
+SB: 2 [4ED:236] Red Elemental Blast
+SB: 1 [TSB:6] Disenchant
+SB: 2 [MMA:204] Engineered Explosives
+SB: 1 [7ED:67] Counterspell
+SB: 1 [RTR:201] Supreme Verdict
+SB: 1 [MMA:70] Vendilion Clique
+SB: 2 [RTR:18] Rest in Peace
diff --git a/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Stefan Böttcher's Deathblade.dck b/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Stefan Bottcher's Deathblade.dck
similarity index 96%
rename from Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Stefan Böttcher's Deathblade.dck
rename to Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Stefan Bottcher's Deathblade.dck
index eeb9e9c7815..668d8ad15d7 100644
--- a/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Stefan Böttcher's Deathblade.dck
+++ b/Mage.Client/release/sample-decks/2014/Legacy/GP Paris/Stefan Bottcher's Deathblade.dck
@@ -1,42 +1,42 @@
-NAME:Stefan Böttcher's Deathblade
-1 [WWK:134] Creeping Tar Pit
-4 [RTR:213] Deathrite Shaman
-1 [AVR:20] Entreat the Angels
-2 [C13:63] True-Name Nemesis
-2 [WWK:31] Jace, the Mind Sculptor
-3 [ISD:78] Snapcaster Mage
-3 [MMA:75] Dark Confidant
-1 [MMA:70] Vendilion Clique
-1 [NPH:130] Batterskull
-1 [ARB:85] Zealous Persecution
-4 [CMD:40] Brainstorm
-2 [THS:107] Thoughtseize
-1 [MMA:204] Engineered Explosives
-1 [BOK:163] Umezawa's Jitte
-1 [3ED:298] Scrubland
-1 [C13:337] Plains
-3 [3ED:305] Underground Sea
-3 [3ED:304] Tundra
-4 [DDF:22] Swords to Plowshares
-1 [3ED:303] Tropical Island
-1 [C13:341] Island
-3 [ONS:316] Flooded Strand
-1 [C13:345] Swamp
-1 [ZEN:219] Marsh Flats
-2 [TMP:340] Wasteland
-1 [LEG:248] Karakas
-1 [MMA:219] Academy Ruins
-1 [7ED:67] Counterspell
-3 [ONS:321] Polluted Delta
-3 [ZEN:67] Spell Pierce
-3 [WWK:20] Stoneforge Mystic
-SB: 1 [ISD:105] Liliana of the Veil
-SB: 1 [RTR:155] Detention Sphere
-SB: 3 [ALL:42] Force of Will
-SB: 1 [RTR:201] Supreme Verdict
-SB: 3 [M11:21] Leyline of Sanctity
-SB: 1 [MBS:138] Sword of Feast and Famine
-SB: 2 [NPH:74] Surgical Extraction
-SB: 1 [THS:65] Swan Song
-SB: 1 [MMA:213] Relic of Progenitus
-SB: 1 [NMS:111] Reverent Silence
+NAME:Stefan Böttcher's Deathblade
+1 [WWK:134] Creeping Tar Pit
+4 [RTR:213] Deathrite Shaman
+1 [AVR:20] Entreat the Angels
+2 [C13:63] True-Name Nemesis
+2 [WWK:31] Jace, the Mind Sculptor
+3 [ISD:78] Snapcaster Mage
+3 [MMA:75] Dark Confidant
+1 [MMA:70] Vendilion Clique
+1 [NPH:130] Batterskull
+1 [ARB:85] Zealous Persecution
+4 [CMD:40] Brainstorm
+2 [THS:107] Thoughtseize
+1 [MMA:204] Engineered Explosives
+1 [BOK:163] Umezawa's Jitte
+1 [3ED:298] Scrubland
+1 [C13:337] Plains
+3 [3ED:305] Underground Sea
+3 [3ED:304] Tundra
+4 [DDF:22] Swords to Plowshares
+1 [3ED:303] Tropical Island
+1 [C13:341] Island
+3 [ONS:316] Flooded Strand
+1 [C13:345] Swamp
+1 [ZEN:219] Marsh Flats
+2 [TMP:340] Wasteland
+1 [LEG:248] Karakas
+1 [MMA:219] Academy Ruins
+1 [7ED:67] Counterspell
+3 [ONS:321] Polluted Delta
+3 [ZEN:67] Spell Pierce
+3 [WWK:20] Stoneforge Mystic
+SB: 1 [ISD:105] Liliana of the Veil
+SB: 1 [RTR:155] Detention Sphere
+SB: 3 [ALL:42] Force of Will
+SB: 1 [RTR:201] Supreme Verdict
+SB: 3 [M11:21] Leyline of Sanctity
+SB: 1 [MBS:138] Sword of Feast and Famine
+SB: 2 [NPH:74] Surgical Extraction
+SB: 1 [THS:65] Swan Song
+SB: 1 [MMA:213] Relic of Progenitus
+SB: 1 [NMS:111] Reverent Silence
diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java
index e9edbd8017d..fef0dfef0b6 100644
--- a/Mage.Client/src/main/java/mage/client/MageFrame.java
+++ b/Mage.Client/src/main/java/mage/client/MageFrame.java
@@ -3,6 +3,7 @@ package mage.client;
import mage.cards.action.ActionCallback;
import mage.cards.decks.Deck;
import mage.cards.repository.CardRepository;
+import mage.cards.repository.ExpansionRepository;
import mage.cards.repository.RepositoryUtil;
import mage.client.cards.BigCard;
import mage.client.chat.ChatPanelBasic;
@@ -719,6 +720,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
boolean autoConnectParamValue = startUser != null || Boolean.parseBoolean(PREFS.get("autoConnect", "false"));
boolean status = false;
if (autoConnectParamValue) {
+ LOGGER.info("Auto-connecting to " + MagePreferences.getServerAddress());
status = performConnect(false);
}
return status;
@@ -741,6 +743,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
currentConnection.setPassword(password);
currentConnection.setHost(server);
currentConnection.setPort(port);
+ // force to redownload db on updates
+ boolean redownloadDatabase = (ExpansionRepository.instance.getSetByCode("GRN") == null || CardRepository.instance.findCard("Island") == null);
+ currentConnection.setForceDBComparison(redownloadDatabase);
String allMAC = "";
try {
allMAC = Connection.getMAC();
@@ -762,7 +767,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
prepareAndShowTablesPane();
return true;
} else {
- showMessage("Unable connect to server");
+ showMessage("Unable connect to server: " + SessionHandler.getLastConnectError());
}
} finally {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
diff --git a/Mage.Client/src/main/java/mage/client/SessionHandler.java b/Mage.Client/src/main/java/mage/client/SessionHandler.java
index 8524b125dae..02962d9489b 100644
--- a/Mage.Client/src/main/java/mage/client/SessionHandler.java
+++ b/Mage.Client/src/main/java/mage/client/SessionHandler.java
@@ -1,6 +1,5 @@
package mage.client;
-import java.util.*;
import mage.cards.decks.DeckCardLists;
import mage.client.chat.LocalCommands;
import mage.client.dialog.PreferencesDialog;
@@ -16,19 +15,22 @@ import mage.remote.Session;
import mage.remote.SessionImpl;
import mage.view.*;
+import java.util.*;
+
/**
* Created by IGOUDT on 15-9-2016.
*/
public final class SessionHandler {
private static Session session;
+ private static String lastConnectError = "";
public static void startSession(MageFrame mageFrame) {
session = new SessionImpl(mageFrame);
session.setJsonLogActive("true".equals(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_LOG_AUTO_SAVE, "true")));
}
-
+
public static void ping() {
session.ping();
}
@@ -46,7 +48,17 @@ public final class SessionHandler {
}
public static boolean connect(Connection connection) {
- return session.connect(connection);
+ lastConnectError = "";
+ if (session.connect(connection)) {
+ return true;
+ } else {
+ lastConnectError = session.getLastError();
+ return false;
+ }
+ }
+
+ public static String getLastConnectError() {
+ return lastConnectError;
}
public static boolean stopConnecting() {
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form
index c1ef452cc22..99de56d11bb 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form
+++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form
@@ -3,9 +3,6 @@
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
index 471ad2d3c6a..a0ee45ce2bf 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
@@ -5,44 +5,12 @@
*/
package mage.client.dialog;
-import java.awt.Cursor;
-import java.awt.event.ActionListener;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.InputStreamReader;
-import java.io.Writer;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JLayeredPane;
-import javax.swing.JOptionPane;
-import javax.swing.SwingWorker;
-
import mage.cards.repository.CardRepository;
import mage.cards.repository.ExpansionRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.client.MageFrame;
-import static mage.client.dialog.PreferencesDialog.KEY_CONNECTION_URL_SERVER_LIST;
-import static mage.client.dialog.PreferencesDialog.KEY_CONNECT_AUTO_CONNECT;
-import static mage.client.dialog.PreferencesDialog.KEY_CONNECT_FLAG;
+import mage.client.SessionHandler;
import mage.client.preference.MagePreferences;
import mage.client.util.Config;
import mage.client.util.gui.countryBox.CountryItemEditor;
@@ -51,6 +19,20 @@ import mage.remote.Connection;
import mage.utils.StreamUtils;
import org.apache.log4j.Logger;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.io.*;
+import java.net.*;
+import java.util.List;
+import java.util.*;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static mage.client.dialog.PreferencesDialog.*;
+
/**
* @author BetaSteward_at_googlemail.com
*/
@@ -124,10 +106,6 @@ public class ConnectDialog extends MageDialog {
private void initComponents() {
lblServer = new javax.swing.JLabel();
- txtServer = new javax.swing.JTextField();
- btnFind = new javax.swing.JButton();
- lblPort = new javax.swing.JLabel();
- txtPort = new javax.swing.JTextField();
lblUserName = new javax.swing.JLabel();
txtUserName = new javax.swing.JTextField();
lblPassword = new javax.swing.JLabel();
@@ -141,47 +119,41 @@ public class ConnectDialog extends MageDialog {
lblStatus = new javax.swing.JLabel();
btnRegister = new javax.swing.JButton();
btnForgotPassword = new javax.swing.JButton();
- btnFind1 = new javax.swing.JButton();
- btnFind2 = new javax.swing.JButton();
- btnFind3 = new javax.swing.JButton();
lblFastConnect = new javax.swing.JLabel();
panelFlag = new javax.swing.JPanel();
cbFlag = new mage.client.util.gui.countryBox.CountryComboBox();
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(5, 0), new java.awt.Dimension(4, 0), new java.awt.Dimension(5, 32767));
btnFlagSearch = new javax.swing.JButton();
+ panelFast = new javax.swing.JPanel();
+ btnFindMain = new javax.swing.JButton();
+ btnFindLocal = new javax.swing.JButton();
+ btnFindBeta = new javax.swing.JButton();
+ btnFindUs = new javax.swing.JButton();
+ btnFindOther = new javax.swing.JButton();
+ panelServer = new javax.swing.JPanel();
+ txtServer = new javax.swing.JTextField();
+ txtPort = new javax.swing.JTextField();
+ lblPort = new javax.swing.JLabel();
+ btnCheckStatus = new javax.swing.JButton();
+ filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 50), new java.awt.Dimension(0, 50), new java.awt.Dimension(32767, 50));
setTitle("Connect to server");
- setNormalBounds(new java.awt.Rectangle(100, 100, 410, 307));
+ lblServer.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblServer.setLabelFor(txtServer);
- lblServer.setText("Server:");
-
- btnFind.setText("Find...");
- btnFind.setToolTipText("Shows the list of public servers");
- btnFind.setName("findServerBtn"); // NOI18N
- btnFind.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- findPublicServerActionPerformed(evt);
- }
- });
-
- lblPort.setLabelFor(txtPort);
- lblPort.setText("Port:");
-
- txtPort.addKeyListener(new java.awt.event.KeyAdapter() {
- public void keyTyped(java.awt.event.KeyEvent evt) {
- ConnectDialog.this.keyTyped(evt);
- }
- });
+ lblServer.setText("Server name:");
+ lblUserName.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblUserName.setLabelFor(txtUserName);
- lblUserName.setText("User name:");
+ lblUserName.setText("Username:");
+ lblPassword.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblPassword.setLabelFor(txtPassword);
lblPassword.setText("Password:");
+ lblFlag.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblFlag.setLabelFor(txtUserName);
- lblFlag.setText("User flag:");
+ lblFlag.setText("User's flag:");
chkAutoConnect.setText("Automatically connect to this server next time");
chkAutoConnect.setToolTipText("If active this connect dialog will not be shown if you choose to connect.
\nInstead XMage tries to connect to the last server you were connected to.");
@@ -242,55 +214,12 @@ public class ConnectDialog extends MageDialog {
}
});
- btnFind1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/de.png"))); // NOI18N
- btnFind1.setText("X");
- btnFind1.setToolTipText("Connect to xmage.de (Europe, most popular)");
- btnFind1.setActionCommand("connectXmageDe");
- btnFind1.setAlignmentY(0.0F);
- btnFind1.setMargin(new java.awt.Insets(2, 2, 2, 2));
- btnFind1.setMaximumSize(new java.awt.Dimension(42, 23));
- btnFind1.setMinimumSize(new java.awt.Dimension(42, 23));
- btnFind1.setName("connectXmageDeBtn"); // NOI18N
- btnFind1.setPreferredSize(new java.awt.Dimension(23, 23));
- btnFind1.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- connectXmageDe(evt);
- }
- });
-
- btnFind2.setText("L");
- btnFind2.setToolTipText("Connect to localhost (local server)");
- btnFind2.setActionCommand("connectLocalhost");
- btnFind2.setAlignmentY(0.0F);
- btnFind2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
- btnFind2.setMargin(new java.awt.Insets(2, 2, 2, 2));
- btnFind2.setName("connectLocalhostBtn"); // NOI18N
- btnFind2.setPreferredSize(new java.awt.Dimension(23, 23));
- btnFind2.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- connectLocalhost(evt);
- }
- });
-
- btnFind3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
- btnFind3.setText("P");
- btnFind3.setToolTipText("Connect to mtg.powersofwar.com (USA)");
- btnFind3.setActionCommand("connectXmageus");
- btnFind3.setAlignmentY(0.0F);
- btnFind3.setMargin(new java.awt.Insets(2, 2, 2, 2));
- btnFind3.setName("connectXmageusBtn"); // NOI18N
- btnFind3.setPreferredSize(new java.awt.Dimension(23, 23));
- btnFind3.addActionListener(new java.awt.event.ActionListener() {
- public void actionPerformed(java.awt.event.ActionEvent evt) {
- connectXmageus(evt);
- }
- });
-
- lblFastConnect.setLabelFor(btnFind1);
- lblFastConnect.setText("Fast connect to:");
+ lblFastConnect.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ lblFastConnect.setLabelFor(btnFindMain);
+ lblFastConnect.setText("Connect to:");
lblFastConnect.setName(""); // NOI18N
- panelFlag.setPreferredSize(new java.awt.Dimension(189, 30));
+ panelFlag.setMinimumSize(new java.awt.Dimension(50, 33));
panelFlag.setLayout(new javax.swing.BoxLayout(panelFlag, javax.swing.BoxLayout.LINE_AXIS));
cbFlag.setEditable(true);
@@ -312,109 +241,232 @@ public class ConnectDialog extends MageDialog {
});
panelFlag.add(btnFlagSearch);
+ btnFindMain.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/de.png"))); // NOI18N
+ btnFindMain.setText("X");
+ btnFindMain.setToolTipText("Connect to xmage.de (Europe, most popular, registration needs)");
+ btnFindMain.setActionCommand("connectXmageDe");
+ btnFindMain.setAlignmentY(0.0F);
+ btnFindMain.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ btnFindMain.setMaximumSize(new java.awt.Dimension(42, 23));
+ btnFindMain.setMinimumSize(new java.awt.Dimension(42, 23));
+ btnFindMain.setName("connectXmageDeBtn"); // NOI18N
+ btnFindMain.setPreferredSize(new java.awt.Dimension(23, 23));
+ btnFindMain.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ connectXmageDe(evt);
+ }
+ });
+
+ btnFindLocal.setText("LOCAL");
+ btnFindLocal.setToolTipText("Connect to localhost (local server)");
+ btnFindLocal.setActionCommand("connectLocalhost");
+ btnFindLocal.setAlignmentY(0.0F);
+ btnFindLocal.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnFindLocal.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ btnFindLocal.setName("connectLocalhostBtn"); // NOI18N
+ btnFindLocal.setPreferredSize(new java.awt.Dimension(23, 23));
+ btnFindLocal.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ connectLocalhost(evt);
+ }
+ });
+
+ btnFindBeta.setText("BETA");
+ btnFindBeta.setToolTipText("Connect to BETA server (use any username without registration)");
+ btnFindBeta.setAlignmentY(0.0F);
+ btnFindBeta.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnFindBeta.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ btnFindBeta.setPreferredSize(new java.awt.Dimension(23, 23));
+ btnFindBeta.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnFindBetaconnectLocalhost(evt);
+ }
+ });
+
+ btnFindUs.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/us.png"))); // NOI18N
+ btnFindUs.setText("P");
+ btnFindUs.setToolTipText("Connect to mtg.powersofwar.com (USA, use any username without registration)");
+ btnFindUs.setActionCommand("connectXmageus");
+ btnFindUs.setAlignmentY(0.0F);
+ btnFindUs.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ btnFindUs.setName("connectXmageusBtn"); // NOI18N
+ btnFindUs.setPreferredSize(new java.awt.Dimension(23, 23));
+ btnFindUs.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ connectXmageus(evt);
+ }
+ });
+
+ btnFindOther.setText("Other servers...");
+ btnFindOther.setToolTipText("Choose server from full servers list");
+ btnFindOther.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnFindOther.setName("findServerBtn"); // NOI18N
+ btnFindOther.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ findPublicServerActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelFastLayout = new javax.swing.GroupLayout(panelFast);
+ panelFast.setLayout(panelFastLayout);
+ panelFastLayout.setHorizontalGroup(
+ panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelFastLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnFindLocal, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnFindOther, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGap(0, 0, 0))
+ );
+ panelFastLayout.setVerticalGroup(
+ panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelFastLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(panelFastLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(btnFindMain, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnFindLocal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnFindUs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnFindBeta, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnFindOther))
+ .addGap(0, 0, 0))
+ );
+
+ txtPort.addKeyListener(new java.awt.event.KeyAdapter() {
+ public void keyTyped(java.awt.event.KeyEvent evt) {
+ ConnectDialog.this.keyTyped(evt);
+ }
+ });
+
+ lblPort.setLabelFor(txtPort);
+ lblPort.setText("Port:");
+
+ btnCheckStatus.setIcon(new javax.swing.ImageIcon(getClass().getResource("/flags/world.png"))); // NOI18N
+ btnCheckStatus.setText("Check online status");
+ btnCheckStatus.setToolTipText("Go to servers online statuses page");
+ btnCheckStatus.setAlignmentY(0.0F);
+ btnCheckStatus.setMargin(new java.awt.Insets(2, 2, 2, 2));
+ btnCheckStatus.setPreferredSize(new java.awt.Dimension(23, 23));
+ btnCheckStatus.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnCheckStatusActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout panelServerLayout = new javax.swing.GroupLayout(panelServer);
+ panelServer.setLayout(panelServerLayout);
+ panelServerLayout.setHorizontalGroup(
+ panelServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelServerLayout.createSequentialGroup()
+ .addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, 212, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblPort)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, 141, Short.MAX_VALUE)
+ .addGap(0, 0, 0))
+ );
+ panelServerLayout.setVerticalGroup(
+ panelServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(panelServerLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(panelServerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblPort)
+ .addComponent(btnCheckStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ );
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
- .addGap(29, 29, 29)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(lblPort)
- .addComponent(lblServer)))
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addContainerGap()
- .addComponent(lblFlag)))
- .addGroup(layout.createSequentialGroup()
- .addContainerGap()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(lblUserName)
- .addComponent(lblPassword, javax.swing.GroupLayout.Alignment.TRAILING))))
- .addGap(0, 0, 0)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addComponent(lblStatus, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(chkForceUpdateDB, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(layout.createSequentialGroup()
- .addComponent(jProxySettingsButton)
- .addGap(0, 0, Short.MAX_VALUE))
- .addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(panelFlag, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(txtServer, javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(txtUserName, javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(txtPassword, javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(layout.createSequentialGroup()
- .addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 11, Short.MAX_VALUE)
- .addComponent(lblFastConnect)
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(lblUserName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblServer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblFastConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGap(18, 18, 18)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jProxySettingsButton)
+ .addGap(0, 0, Short.MAX_VALUE))
+ .addComponent(lblStatus, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(chkForceUpdateDB, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(txtUserName)
+ .addComponent(txtPassword)
+ .addComponent(panelFlag, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnCancel, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(panelFast, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(panelServer, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnFind1, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnFind3, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnFind2, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addGap(0, 0, 0)
- .addComponent(btnFind)))
- .addContainerGap())
+ .addComponent(filler2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
);
layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
- .addContainerGap()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(lblServer)
- .addComponent(txtServer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(btnFind))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(txtPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lblPort)
- .addComponent(btnFind1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(btnFind2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(btnFind3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lblFastConnect))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(txtUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lblUserName))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lblPassword))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(panelFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lblFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(chkAutoConnect)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(chkForceUpdateDB)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(jProxySettingsButton)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
- .addGroup(layout.createSequentialGroup()
- .addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(btnCancel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addGap(23, 23, 23))
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(panelFast, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblFastConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(panelServer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblServer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(txtUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblUserName, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(txtPassword)
+ .addComponent(lblPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ .addComponent(filler2, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(panelFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblFlag, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(chkAutoConnect)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(chkForceUpdateDB)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jProxySettingsButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(btnRegister, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnForgotPassword, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addComponent(btnConnect, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(btnCancel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGap(23, 23, 23))
);
+ lblFastConnect.getAccessibleContext().setAccessibleName("Fast connect to:");
+
pack();
}// //GEN-END:initComponents
@@ -457,13 +509,12 @@ public class ConnectDialog extends MageDialog {
connection.setPort(Integer.valueOf(this.txtPort.getText().trim()));
connection.setUsername(this.txtUserName.getText().trim());
connection.setPassword(this.txtPassword.getText().trim());
-
// force to redownload db
boolean redownloadDatabase = (ExpansionRepository.instance.getSetByCode("GRN") == null || CardRepository.instance.findCard("Island") == null);
connection.setForceDBComparison(this.chkForceUpdateDB.isSelected() || redownloadDatabase);
String allMAC = "";
try {
- allMAC = connection.getMAC();
+ allMAC = Connection.getMAC();
} catch (SocketException ex) {
}
connection.setUserIdStr(System.getProperty("user.name") + ":" + System.getProperty("os.name") + ":" + MagePreferences.getUserNames() + ":" + allMAC);
@@ -485,6 +536,7 @@ public class ConnectDialog extends MageDialog {
private class ConnectTask extends SwingWorker {
private boolean result = false;
+ private String lastConnectError = "";
private static final int CONNECTION_TIMEOUT_MS = 2100;
@@ -493,6 +545,7 @@ public class ConnectDialog extends MageDialog {
lblStatus.setText("Connecting...");
btnConnect.setEnabled(false);
result = MageFrame.connect(connection);
+ lastConnectError = SessionHandler.getLastConnectError();
return result;
}
@@ -506,7 +559,7 @@ public class ConnectDialog extends MageDialog {
connected();
MageFrame.getInstance().prepareAndShowTablesPane();
} else {
- lblStatus.setText("Could not connect");
+ lblStatus.setText("Could not connect: " + lastConnectError);
}
} catch (InterruptedException ex) {
logger.fatal("Update Players Task error", ex);
@@ -679,8 +732,7 @@ public class ConnectDialog extends MageDialog {
this.txtPort.setText("17171");
// Update userName and password according to the chosen server.
this.txtUserName.setText(MagePreferences.getUserName(serverAddress));
- this.txtPassword.setText(MagePreferences.getPassword(serverAddress));
-
+ this.txtPassword.setText(MagePreferences.getPassword(serverAddress)); // TODO add your handling code here:
}//GEN-LAST:event_btnFind1findPublicServerActionPerformed
private void connectLocalhost(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFind2findPublicServerActionPerformed
@@ -702,10 +754,33 @@ public class ConnectDialog extends MageDialog {
this.txtPassword.setText(MagePreferences.getPassword(serverAddress));
}
+ private void connectBeta(java.awt.event.ActionEvent evt) {
+ String serverAddress = "xmage.today";
+ this.txtServer.setText(serverAddress);
+ this.txtPort.setText("17171");
+ // Update userName and password according to the chosen server.
+ this.txtUserName.setText(MagePreferences.getUserName(serverAddress));
+ this.txtPassword.setText(MagePreferences.getPassword(serverAddress));
+ }
+
private void btnFlagSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFlagSearchActionPerformed
doFastFlagSearch();
}//GEN-LAST:event_btnFlagSearchActionPerformed
+ private void btnFindBetaconnectLocalhost(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFindBetaconnectLocalhost
+ connectBeta(evt);
+ }//GEN-LAST:event_btnFindBetaconnectLocalhost
+
+ private void btnCheckStatusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckStatusActionPerformed
+ if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
+ try {
+ Desktop.getDesktop().browse(new URI("http://xmageservers.online/"));
+ } catch (Exception e) {
+ //
+ }
+ }
+ }//GEN-LAST:event_btnCheckStatusActionPerformed
+
private void doFastFlagSearch() {
Choice choice = new ChoiceImpl(false);
@@ -751,11 +826,13 @@ public class ConnectDialog extends MageDialog {
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel;
+ private javax.swing.JButton btnCheckStatus;
private javax.swing.JButton btnConnect;
- private javax.swing.JButton btnFind;
- private javax.swing.JButton btnFind1;
- private javax.swing.JButton btnFind2;
- private javax.swing.JButton btnFind3;
+ private javax.swing.JButton btnFindBeta;
+ private javax.swing.JButton btnFindLocal;
+ private javax.swing.JButton btnFindMain;
+ private javax.swing.JButton btnFindOther;
+ private javax.swing.JButton btnFindUs;
private javax.swing.JButton btnFlagSearch;
private javax.swing.JButton btnForgotPassword;
private javax.swing.JButton btnRegister;
@@ -763,6 +840,7 @@ public class ConnectDialog extends MageDialog {
private javax.swing.JCheckBox chkAutoConnect;
private javax.swing.JCheckBox chkForceUpdateDB;
private javax.swing.Box.Filler filler1;
+ private javax.swing.Box.Filler filler2;
private javax.swing.JButton jProxySettingsButton;
private javax.swing.JLabel lblFastConnect;
private javax.swing.JLabel lblFlag;
@@ -771,7 +849,9 @@ public class ConnectDialog extends MageDialog {
private javax.swing.JLabel lblServer;
private javax.swing.JLabel lblStatus;
private javax.swing.JLabel lblUserName;
+ private javax.swing.JPanel panelFast;
private javax.swing.JPanel panelFlag;
+ private javax.swing.JPanel panelServer;
private javax.swing.JPasswordField txtPassword;
private javax.swing.JTextField txtPort;
private javax.swing.JTextField txtServer;
diff --git a/Mage.Client/src/main/java/mage/client/table/TablesUtil.java b/Mage.Client/src/main/java/mage/client/table/TablesUtil.java
index 475be3d2f96..bdb6bc363bc 100644
--- a/Mage.Client/src/main/java/mage/client/table/TablesUtil.java
+++ b/Mage.Client/src/main/java/mage/client/table/TablesUtil.java
@@ -18,6 +18,8 @@ public class TablesUtil {
searchId = ((TablesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
} else if (table.getModel() instanceof MatchesTableModel) {
searchId = ((MatchesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
+ } else if (table.getModel() instanceof TournamentMatchesTableModel) {
+ searchId = ((TournamentMatchesTableModel) table.getModel()).findTableAndGameInfoByRow(row);
} else {
logger.error("Not supported tables model " + table.getModel().getClass().toString());
}
@@ -31,6 +33,8 @@ public class TablesUtil {
row = ((TablesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
} else if (tableModel instanceof MatchesTableModel) {
row = ((MatchesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
+ } else if (tableModel instanceof TournamentMatchesTableModel) {
+ row = ((TournamentMatchesTableModel) tableModel).findRowByTableAndGameInfo(searchId);
} else {
logger.error("Not supported tables model " + tableModel.getClass().toString());
}
diff --git a/Mage.Client/src/main/java/mage/client/table/TournamentMatchesTableModel.java b/Mage.Client/src/main/java/mage/client/table/TournamentMatchesTableModel.java
new file mode 100644
index 00000000000..288a5c70f7e
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/table/TournamentMatchesTableModel.java
@@ -0,0 +1,116 @@
+package mage.client.table;
+
+import mage.view.RoundView;
+import mage.view.TournamentGameView;
+import mage.view.TournamentView;
+
+import javax.swing.table.AbstractTableModel;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author JayDi85
+ */
+public class TournamentMatchesTableModel extends AbstractTableModel {
+ public static final int ACTION_COLUMN = 4; // column the action is located
+
+ private final String[] columnNames = new String[]{"Round Number", "Players", "State", "Result", "Action"};
+ private TournamentGameView[] games = new TournamentGameView[0];
+ private boolean watchingAllowed;
+
+ public void loadData(TournamentView tournament) {
+ List views = new ArrayList<>();
+ watchingAllowed = tournament.isWatchingAllowed();
+ for (RoundView round : tournament.getRounds()) {
+ for (TournamentGameView game : round.getGames()) {
+ views.add(game);
+ }
+ }
+ games = views.toArray(new TournamentGameView[0]);
+ this.fireTableDataChanged();
+ }
+
+ public String getTableAndGameInfo(int row) {
+ return this.games[row].getTableId().toString() + ";" + games[row].toString();
+ }
+
+ public String findTableAndGameInfoByRow(int row) {
+ if (row >= 0 && row < this.games.length) {
+ return getTableAndGameInfo(row);
+ } else {
+ return null;
+ }
+ }
+
+ public int findRowByTableAndGameInfo(String tableAndGame) {
+ for (int i = 0; i < this.games.length; i++) {
+ String rowID = this.games[i].getTableId().toString() + ";" + this.games[i].toString();
+ if (tableAndGame.equals(rowID)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public int getRowCount() {
+ return games.length;
+ }
+
+ @Override
+ public int getColumnCount() {
+ return columnNames.length;
+ }
+
+ @Override
+ public Object getValueAt(int arg0, int arg1) {
+ switch (arg1) {
+ case 0:
+ return Integer.toString(games[arg0].getRoundNum());
+ case 1:
+ return games[arg0].getPlayers();
+ case 2:
+ return games[arg0].getState();
+ case 3:
+ return games[arg0].getResult();
+ case 4:
+// if (games[arg0].getState().equals("Finished")) {
+// return "Replay";
+// }
+ if (watchingAllowed && games[arg0].getState().startsWith("Dueling")) {
+ return "Watch";
+ }
+ return "";
+ case 5:
+ return games[arg0].getTableId().toString();
+ case 6:
+ return games[arg0].getMatchId().toString();
+ case 7:
+ return games[arg0].getGameId().toString();
+
+ }
+ return "";
+ }
+
+ @Override
+ public String getColumnName(int columnIndex) {
+ String colName = "";
+
+ if (columnIndex <= getColumnCount()) {
+ colName = columnNames[columnIndex];
+ }
+
+ return colName;
+ }
+
+ @Override
+ public Class getColumnClass(int columnIndex) {
+ return String.class;
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return columnIndex == ACTION_COLUMN;
+ }
+
+}
\ No newline at end of file
diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java
index bdafa112a59..19eeb84fdbc 100644
--- a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java
+++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java
@@ -5,12 +5,16 @@ import mage.client.SessionHandler;
import mage.client.chat.ChatPanelBasic;
import mage.client.dialog.PreferencesDialog;
import mage.client.table.TablesButtonColumn;
+import mage.client.table.TablesUtil;
+import mage.client.table.TournamentMatchesTableModel;
import mage.client.util.Format;
import mage.client.util.GUISizeHelper;
import mage.client.util.gui.TableUtil;
import mage.client.util.gui.countryBox.CountryCellRenderer;
import mage.constants.PlayerAction;
-import mage.view.*;
+import mage.view.TournamentPlayerView;
+import mage.view.TournamentView;
+import mage.view.UserRequestMessage;
import org.apache.log4j.Logger;
import javax.swing.*;
@@ -18,7 +22,6 @@ import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.text.DateFormat;
-import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@@ -74,7 +77,11 @@ public class TournamentPanel extends javax.swing.JPanel {
Action action = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
- int modelRow = Integer.valueOf(e.getActionCommand());
+ String searchID = e.getActionCommand();
+ int modelRow = TablesUtil.findTableRowFromSearchId(matchesModel, searchID);
+ if (modelRow == -1) {
+ return;
+ }
String state = (String) tableMatches.getValueAt(modelRow, tableMatches.convertColumnIndexToView(2));
String actionText = (String) tableMatches.getValueAt(modelRow, tableMatches.convertColumnIndexToView(TournamentMatchesTableModel.ACTION_COLUMN));
@@ -132,7 +139,7 @@ public class TournamentPanel extends javax.swing.JPanel {
private void saveDividerLocations() {
// save panel sizes and divider locations.
Rectangle rec = MageFrame.getDesktop().getBounds();
- String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight());
+ String sb = Double.toString(rec.getWidth()) + 'x' + rec.getHeight();
PreferencesDialog.saveValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, sb);
PreferencesDialog.saveValue(PreferencesDialog.KEY_TOURNAMENT_DIVIDER_LOCATION_1, Integer.toString(this.jSplitPane1.getDividerLocation()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_TOURNAMENT_DIVIDER_LOCATION_2, Integer.toString(this.jSplitPane2.getDividerLocation()));
@@ -142,7 +149,7 @@ public class TournamentPanel extends javax.swing.JPanel {
Rectangle rec = MageFrame.getDesktop().getBounds();
if (rec != null) {
String size = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_MAGE_PANEL_LAST_SIZE, null);
- String sb = Double.toString(rec.getWidth()) + 'x' + Double.toString(rec.getHeight());
+ String sb = Double.toString(rec.getWidth()) + 'x' + rec.getHeight();
// use divider positions only if screen size is the same as it was the time the settings were saved
if (size != null && size.equals(sb)) {
String location = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_TOURNAMENT_DIVIDER_LOCATION_1, null);
@@ -585,88 +592,6 @@ class TournamentPlayersTableModel extends AbstractTableModel {
}
-class TournamentMatchesTableModel extends AbstractTableModel {
-
- public static final int ACTION_COLUMN = 4; // column the action is located
-
- private final String[] columnNames = new String[]{"Round Number", "Players", "State", "Result", "Action"};
- private TournamentGameView[] games = new TournamentGameView[0];
- private boolean watchingAllowed;
-
- public void loadData(TournamentView tournament) {
- List views = new ArrayList<>();
- watchingAllowed = tournament.isWatchingAllowed();
- for (RoundView round : tournament.getRounds()) {
- for (TournamentGameView game : round.getGames()) {
- views.add(game);
- }
- }
- games = views.toArray(new TournamentGameView[0]);
- this.fireTableDataChanged();
- }
-
- @Override
- public int getRowCount() {
- return games.length;
- }
-
- @Override
- public int getColumnCount() {
- return columnNames.length;
- }
-
- @Override
- public Object getValueAt(int arg0, int arg1) {
- switch (arg1) {
- case 0:
- return Integer.toString(games[arg0].getRoundNum());
- case 1:
- return games[arg0].getPlayers();
- case 2:
- return games[arg0].getState();
- case 3:
- return games[arg0].getResult();
- case 4:
-// if (games[arg0].getState().equals("Finished")) {
-// return "Replay";
-// }
- if (watchingAllowed && games[arg0].getState().startsWith("Dueling")) {
- return "Watch";
- }
- return "";
- case 5:
- return games[arg0].getTableId().toString();
- case 6:
- return games[arg0].getMatchId().toString();
- case 7:
- return games[arg0].getGameId().toString();
-
- }
- return "";
- }
-
- @Override
- public String getColumnName(int columnIndex) {
- String colName = "";
-
- if (columnIndex <= getColumnCount()) {
- colName = columnNames[columnIndex];
- }
-
- return colName;
- }
-
- @Override
- public Class getColumnClass(int columnIndex) {
- return String.class;
- }
-
- @Override
- public boolean isCellEditable(int rowIndex, int columnIndex) {
- return columnIndex == ACTION_COLUMN;
- }
-
-}
class UpdateTournamentTask extends SwingWorker {
@@ -709,4 +634,4 @@ class UpdateTournamentTask extends SwingWorker {
}
}
-}
+}
\ No newline at end of file
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java
index 08424c69acc..f365a441436 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSupportCards.java
@@ -354,6 +354,13 @@ public class ScryfallImageSupportCards {
// TODO: remove Grand Prix fix after scryfall fix image's link (that's link must be work: https://img.scryfall.com/cards/large/en/pgpx/2016b.jpg )
put("GPX/Sword of Feast and Famine", "https://img.scryfall.com/cards/large/en/pgpx/1%E2%98%85.jpg");
+
+ // TODO: remove after scryfall add lands to RNA (that's link must works: https://api.scryfall.com/cards/rna/262/en?format=image)
+ put("RNA/Plains", "https://api.scryfall.com/cards/grn/260/en?format=image");
+ put("RNA/Island", "https://api.scryfall.com/cards/grn/261/en?format=image");
+ put("RNA/Swamp", "https://api.scryfall.com/cards/grn/262/en?format=image");
+ put("RNA/Mountain", "https://api.scryfall.com/cards/grn/263/en?format=image");
+ put("RNA/Forest", "https://api.scryfall.com/cards/grn/264/en?format=image");
}
};
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java
index 483bb27e866..11388b07b9d 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallSymbolsSource.java
@@ -70,10 +70,7 @@ public class ScryfallSymbolsSource implements Iterable {
}
// gen symbols list
- ArrayList allMageSymbols = new ArrayList<>();
- for (int i = 0; i < SYMBOLS_LIST.length; i++) {
- allMageSymbols.add(SYMBOLS_LIST[i]);
- }
+ List allMageSymbols = Arrays.asList(SYMBOLS_LIST);
for (Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++) {
allMageSymbols.add(String.valueOf(SYMBOLS_NUMBER_START + i));
}
@@ -111,21 +108,17 @@ public class ScryfallSymbolsSource implements Iterable {
if (destFile.exists() && (destFile.length() > 0)) {
continue;
}
- FileOutputStream stream = null;
- try {
+ try(FileOutputStream stream = new FileOutputStream(destFile)) {
// base64 transform
String data64 = foundedData.get(searchCode);
Base64.Decoder dec = Base64.getDecoder();
byte[] fileData = dec.decode(data64);
- stream = new FileOutputStream(destFile);
stream.write(fileData);
LOGGER.info("New svg symbol downloaded: " + needCode);
} catch (Exception e) {
LOGGER.error("Can't decode svg icon and save to file: " + destFile.getPath() + ", reason: " + e.getMessage());
- } finally {
- StreamUtils.closeQuietly(stream);
}
}
}
@@ -166,7 +159,7 @@ public class ScryfallSymbolsSource implements Iterable {
org.jsoup.nodes.Document doc = CardImageUtils.downloadHtmlDocument(CSS_SOURCE_URL);
org.jsoup.select.Elements cssList = doc.select(CSS_SOURCE_SELECTOR);
if (cssList.size() == 1) {
- this.cssUrl = cssList.first().attr("href").toString();
+ this.cssUrl = cssList.first().attr("href");
}
if (this.cssUrl.isEmpty()) {
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java
index ddec9bd3b4d..44b62569026 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPicturesService.java
@@ -26,8 +26,8 @@ import java.awt.event.ItemEvent;
import java.io.*;
import java.net.*;
import java.nio.file.AccessDeniedException;
-import java.util.List;
import java.util.*;
+import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -817,13 +817,9 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
// can save result
if (isDownloadOK & httpConn != null) {
// save data to temp
- OutputStream out = null;
- OutputStream tfileout = null;
- InputStream in = null;
- try {
- in = new BufferedInputStream(httpConn.getInputStream());
- tfileout = new TFileOutputStream(fileTempImage);
- out = new BufferedOutputStream(tfileout);
+ try (InputStream in = new BufferedInputStream(httpConn.getInputStream());
+ OutputStream tfileout = new TFileOutputStream(fileTempImage);
+ OutputStream out = new BufferedOutputStream(tfileout)) {
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) {
@@ -849,13 +845,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
}
out.write(buf, 0, len);
}
- } finally {
- StreamUtils.closeQuietly(in);
- StreamUtils.closeQuietly(out);
- StreamUtils.closeQuietly(tfileout);
}
-
-
// TODO: add two faces card correction? (WTF)
// SAVE final data
if (fileTempImage.exists()) {
@@ -912,7 +902,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
this.cardsDownloadQueue.removeAll(downloadedCards);
this.cardsMissing.removeAll(downloadedCards);
- if (this.cardsDownloadQueue.size() == 0) {
+ if (this.cardsDownloadQueue.isEmpty()) {
// stop download
uiDialog.getProgressBar().setString("0 images remaining. Please close.");
} else {
diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java
index 9d0d5730cc0..c7dae393558 100644
--- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java
+++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java
@@ -126,6 +126,15 @@ public final class CardImageUtils {
return path;
}
+ public static String fixSetNameForWindows(String set) {
+ // windows can't create con folders
+ if (set.equals("CON") || set.equals("con")) {
+ return "COX";
+ } else {
+ return set;
+ }
+ }
+
public static String buildImagePathToTokens() {
String imagesPath = getImagesDir() + File.separator;
@@ -159,14 +168,14 @@ public final class CardImageUtils {
String imagesPath = getImagesDir() + File.separator;
if (PreferencesDialog.isSaveImagesToZip()) {
- return imagesPath + set + ".zip" + File.separator + set + File.separator;
+ return imagesPath + fixSetNameForWindows(set) + ".zip" + File.separator + fixSetNameForWindows(set) + File.separator;
} else {
- return imagesPath + set + File.separator;
+ return imagesPath + fixSetNameForWindows(set) + File.separator;
}
}
private static String buildImagePathToSetAsToken(String set) {
- return buildImagePathToTokens() + set + File.separator;
+ return buildImagePathToTokens() + fixSetNameForWindows(set) + File.separator;
}
public static String buildImagePathToCard(CardDownloadData card) {
@@ -217,7 +226,7 @@ public final class CardImageUtils {
}
public static String generateFaceImagePath(String cardname, String set) {
- return getImagesDir() + File.separator + "FACE" + File.separator + set + File.separator + prepareCardNameForFile(cardname) + ".jpg";
+ return getImagesDir() + File.separator + "FACE" + File.separator + fixSetNameForWindows(set) + File.separator + prepareCardNameForFile(cardname) + ".jpg";
}
public static String generateTokenDescriptorImagePath(CardDownloadData card) {
diff --git a/Mage.Common/pom.xml b/Mage.Common/pom.xml
index 5eb7a110dab..f1535ccfae1 100644
--- a/Mage.Common/pom.xml
+++ b/Mage.Common/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage-common
diff --git a/Mage.Common/src/main/java/mage/remote/SessionImpl.java b/Mage.Common/src/main/java/mage/remote/SessionImpl.java
index 45f0b0c5be5..38439c01a5b 100644
--- a/Mage.Common/src/main/java/mage/remote/SessionImpl.java
+++ b/Mage.Common/src/main/java/mage/remote/SessionImpl.java
@@ -61,6 +61,7 @@ public class SessionImpl implements Session {
private boolean canceled = false;
private boolean jsonLogActive = false;
+ private String lastError = "";
static {
debugMode = System.getProperty("debug.mage") != null;
@@ -195,20 +196,29 @@ public class SessionImpl implements Session {
&& handleRemotingTaskExceptions(new RemotingTask() {
@Override
public boolean run() throws Throwable {
+ setLastError("");
logger.info("Trying to log-in as " + getUserName() + " to XMAGE server at " + connection.getHost() + ':' + connection.getPort());
boolean registerResult;
if (connection.getAdminPassword() == null) {
// for backward compatibility. don't remove twice call - first one does nothing but for version checking
registerResult = server.connectUser(connection.getUsername(), connection.getPassword(), sessionId, client.getVersion(), connection.getUserIdStr());
- if (registerResult) {
- server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr());
- }
} else {
registerResult = server.connectAdmin(connection.getAdminPassword(), sessionId, client.getVersion());
}
if (registerResult) {
serverState = server.getServerState();
+
+ // client side check for incompatible versions
+ if (client.getVersion().compareTo(serverState.getVersion()) != 0) {
+ String err = "Client and server versions are incompatible.";
+ setLastError(err);
+ logger.info(err);
+ disconnect(false);
+ return false;
+ }
+
if (!connection.getUsername().equals("Admin")) {
+ server.setUserData(connection.getUsername(), sessionId, connection.getUserData(), client.getVersion().toString(), connection.getUserIdStr());
updateDatabase(connection.isForceDBComparison(), serverState);
}
logger.info("Logged-in as " + getUserName() + " to MAGE server at " + connection.getHost() + ':' + connection.getPort());
@@ -1621,6 +1631,15 @@ public class SessionImpl implements Session {
this.jsonLogActive = jsonLogActive;
}
+ private void setLastError(String error) {
+ lastError = error;
+ }
+
+ @Override
+ public String getLastError() {
+ return lastError;
+ }
+
}
class MageAuthenticator extends Authenticator {
diff --git a/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java b/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java
index 747f5e63c57..4795578ffcd 100644
--- a/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java
+++ b/Mage.Common/src/main/java/mage/remote/interfaces/Connect.java
@@ -1,4 +1,3 @@
-
package mage.remote.interfaces;
import mage.remote.Connection;
@@ -37,10 +36,12 @@ public interface Connect {
boolean muteUserChat(String userName, long durationMinute);
boolean setActivation(String userName, boolean active);
-
+
boolean toggleActivation(String userName);
boolean lockUser(String userName, long durationMinute);
String getSessionId();
+
+ String getLastError();
}
diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java
index e4550bddf11..2ad341ebc79 100644
--- a/Mage.Common/src/main/java/mage/utils/MageVersion.java
+++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java
@@ -14,9 +14,11 @@ public class MageVersion implements Serializable, Comparable {
*/
public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4;
- public final static int MAGE_VERSION_PATCH = 32;
+ public final static int MAGE_VERSION_PATCH = 33;
public final static String MAGE_EDITION_INFO = ""; // set "-beta" for 1.4.32-betaV0
- public final static String MAGE_VERSION_MINOR_PATCH = "V0";
+ public final static String MAGE_VERSION_MINOR_PATCH = "V1"; // default V0
+ // strict mode
+ private final static boolean MAGE_VERSION_MINOR_PATCH_MUST_BE_SAME = true; // set true on uncompatible github changes, set false after new major release (after MAGE_VERSION_PATCH changes)
private final int major;
private final int minor;
@@ -74,7 +76,9 @@ public class MageVersion implements Serializable, Comparable {
if (patch != o.patch) {
return patch - o.patch;
}
+ if (MAGE_VERSION_MINOR_PATCH_MUST_BE_SAME && !minorPatch.equals(o.minorPatch)) {
+ return minorPatch.compareTo(o.minorPatch);
+ }
return editionInfo.compareTo(o.editionInfo);
}
-
}
diff --git a/Mage.Plugins/Mage.Counter.Plugin/pom.xml b/Mage.Plugins/Mage.Counter.Plugin/pom.xml
index 27f3f04daa8..37dccf66a3c 100644
--- a/Mage.Plugins/Mage.Counter.Plugin/pom.xml
+++ b/Mage.Plugins/Mage.Counter.Plugin/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-plugins
- 1.4.32
+ 1.4.33
mage-counter-plugin
diff --git a/Mage.Plugins/pom.xml b/Mage.Plugins/pom.xml
index 8ae91a6e66c..844a031c2dc 100644
--- a/Mage.Plugins/pom.xml
+++ b/Mage.Plugins/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage-plugins
diff --git a/Mage.Server.Console/pom.xml b/Mage.Server.Console/pom.xml
index c754825bb39..50c953f3acd 100644
--- a/Mage.Server.Console/pom.xml
+++ b/Mage.Server.Console/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
org.mage
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml
index ae308a042c8..c458b09fd11 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-deck-constructed
diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java
index bbd28dcfa7a..45dcba803b2 100644
--- a/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java
+++ b/Mage.Server.Plugins/Mage.Deck.Constructed/src/mage/deck/Commander.java
@@ -631,7 +631,7 @@ public class Commander extends Constructed {
|| cn.equals("krark-clan ironworks") || cn.equals("krenko, mob boss")
|| cn.equals("krosan restorer") || cn.equals("laboratory maniac")
|| cn.equals("leonin relic-warder") || cn.equals("leyline of the void")
- || cn.equals("memnarch") || cn.equals("memnarch")
+ || cn.equals("memnarch")
|| cn.equals("meren of clan nel toth") || cn.equals("mikaeus, the unhallowed")
|| cn.equals("mindcrank") || cn.equals("mindslaver")
|| cn.equals("minion reflector") || cn.equals("mycosynth lattice")
@@ -649,7 +649,7 @@ public class Commander extends Constructed {
|| cn.equals("sunder")
|| cn.equals("storm cauldron") || cn.equals("teferi's puzzle box")
|| cn.equals("tangle wire")
- || cn.equals("teferi, mage of zhalfir") || cn.equals("teferi, mage of zhalfir")
+ || cn.equals("teferi, mage of zhalfir")
|| cn.equals("tezzeret the seeker") || cn.equals("time stretch")
|| cn.equals("time warp") || cn.equals("training grounds")
|| cn.equals("triskelavus") || cn.equals("triskelion")
diff --git a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml
index 98e6f8d47fb..3970fd8aec4 100644
--- a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml
+++ b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-deck-limited
diff --git a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml
index c8e41100ec6..c4468a780eb 100644
--- a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-brawlduel
diff --git a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml
index 6acd4acfc23..68b7153f7c9 100644
--- a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-brawlfreeforall
diff --git a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml
index 6a96d18e1ea..9957ade0c13 100644
--- a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-canadianhighlanderduel
diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml
index 6bdd993258d..1be9b9c39b7 100644
--- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-commanderduel
diff --git a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml
index 159cbc07010..c15e9c37865 100644
--- a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-commanderfreeforall
diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml
index 9c8f09b34e8..12379002c19 100644
--- a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-freeforall
diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml
index 3c49cfae83e..f09b70e6775 100644
--- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-freeformcommanderfreeforall
diff --git a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml
index 2c78b0d5ad6..cfdab7bfbd9 100644
--- a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-momirduel
diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml
index 79f3c5abdf1..dc080d0c864 100644
--- a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-momirfreeforall
diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml
index f110bd92500..8c46ad880c2 100644
--- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-pennydreadfulcommanderfreeforall
diff --git a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml
index c0744d767fe..c89f501bf29 100644
--- a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-tinyleadersduel
diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml
index 9f0fcd6fc9d..817912749f7 100644
--- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml
+++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-game-twoplayerduel
diff --git a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml
index 6bf13c4d634..38289a5a1e4 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-player-ai-draftbot
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml
index f5503335224..c228f0dcef9 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-player-ai-ma
diff --git a/Mage.Server.Plugins/Mage.Player.AI/pom.xml b/Mage.Server.Plugins/Mage.Player.AI/pom.xml
index 3d07accfddf..ea0fe82fa9f 100644
--- a/Mage.Server.Plugins/Mage.Player.AI/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AI/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-player-ai
diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
index 3625c367692..0d3cf9c08dd 100644
--- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
@@ -500,6 +500,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
if (target.getOriginalTarget() instanceof TargetPermanent) {
List targets;
+ TargetPermanent t = (TargetPermanent) target.getOriginalTarget();
boolean outcomeTargets = true;
if (outcome.isGood()) {
targets = threats(abilityControllerId, source == null ? null : source.getSourceId(), ((TargetPermanent) target).getFilter(), game, target.getTargets());
@@ -512,6 +513,9 @@ public class ComputerPlayer extends PlayerImpl implements Player {
outcomeTargets = false;
//targets = game.getBattlefield().getActivePermanents(((TargetPermanent)target).getFilter(), playerId, game);
}
+ if (targets.isEmpty() && target.isRequired()) {
+ targets = game.getBattlefield().getActivePermanents(t.getFilter(), playerId, game);
+ }
for (Permanent permanent : targets) {
if (((TargetPermanent) target).canTarget(abilityControllerId, permanent.getId(), source, game)) {
target.addTarget(permanent.getId(), source, game);
diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/rna.csv b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/rna.csv
new file mode 100644
index 00000000000..620b2081c33
--- /dev/null
+++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/resources/ratings/rna.csv
@@ -0,0 +1,254 @@
+Biogenic Ooze:1000
+Angel of Grace:986
+Rakdos, the Showstopper:974
+Skarrgan Hellkite:964
+Spawn of Mayhem:954
+Seraph of the Scales:945
+Hydroid Krasis:937
+Domri, Chaos Bringer:929
+Ethereal Absolution:922
+Lawmage's Binding:915
+Electrodominance:908
+Sphinx of Foresight:902
+Ravager Wurm:896
+Bedevil:891
+Mesmerizing Benthid:885
+Zegana, Utopian Speaker:880
+Thrash // Threat:875
+Deputy of Detention:870
+Mortify:865
+Judith, the Scourge Diva:861
+Gruul Spellbreaker:856
+Pestilent Spirit:852
+Dovin, Grand Arbiter:848
+Warrant // Warden:843
+Skewer the Critics:839
+Sunder Shaman:836
+Sharktocrab:832
+Biomancer's Familiar:828
+Prime Speaker Vannifar:824
+Kaya's Wrath:821
+Incubation Druid:817
+Theater of Horrors:814
+Frilled Mystic:810
+Get the Point:807
+Nikya of the Old Ways:804
+Combine Guildmage:801
+Rix Maadi Reveler:797
+Growth-Chamber Guardian:794
+Ministrant of Obligation:791
+Frenzied Arynx:788
+Teysa Karlov:785
+Bedeck // Bedazzle:782
+Precognitive Perception:779
+Final Payment:776
+Rhythm of the Wild:774
+Captive Audience:771
+End-Raze Forerunners:768
+Lumbering Battlement:765
+Rakdos Firewheeler:763
+Senate Guildmage:760
+Trollbred Guardian:757
+Galloping Lizrog:755
+Grotesque Demise:752
+Skatewing Spy:749
+Azorius Skyguard:747
+Sphinx of New Prahv:744
+Cry of the Carnarium:742
+Dagger Caster:739
+Immolation Shaman:737
+Orzhov Enforcer:735
+Consecrate // Consume:732
+Aeromunculus:730
+Windstorm Drake:727
+Clear the Stage:725
+Depose // Deploy:723
+Revival // Revenge:720
+Mass Manipulation:718
+Senate Griffin:716
+Biogenic Upgrade:713
+Savage Smash:711
+Unbreakable Formation:709
+Applied Biomancy:707
+Pitiless Pontiff:705
+Hero of Precinct One:702
+Summary Judgment:700
+Gyre Engineer:698
+Benthic Biomancer:696
+Cult Guildmage:694
+Zhur-Taa Goblin:691
+Spirit of the Spires:689
+Collision // Colossus:687
+Pteramander:685
+Flames of the Raze-Boar:683
+Carnival // Carnage:681
+Grasping Thrull:679
+Hackrobat:677
+Clan Guildmage:675
+Imperious Oligarch:673
+Scorchmark:670
+Syndicate Guildmage:668
+Gatebreaker Ram:666
+Rampaging Rendhorn:664
+Forbidding Spirit:662
+Tithe Taker:660
+Fireblade Artist:658
+Azorius Knight-Arbiter:656
+Simic Ascendancy:654
+Guardian Project:652
+Enraged Ceratok:650
+Bolrac-Clan Crusher:648
+Consign to the Pit:646
+Repudiate // Replicate:644
+Gruul Beastmaster:642
+Gutterbones:640
+Spire Mangler:638
+Titanic Brawl:636
+Dovin's Acuity:634
+Incubation // Incongruity:633
+Sky Tether:631
+Basilica Bell-Haunt:629
+Amplifire:627
+Essence Capture:625
+Arrester's Admonition:623
+Chillbringer:621
+Clamor Shaman:619
+Syndicate Messenger:617
+Rubblebelt Runner:615
+Faerie Duelist:613
+Burning-Tree Vandal:611
+Sauroform Hybrid:609
+Undercity's Embrace:607
+Sphinx of the Guildpact:605
+Growth Spiral:603
+Orzhov Racketeers:602
+Dead Revels:600
+Vindictive Vampire:598
+Priest of Forgotten Gods:596
+Silhana Wayfinder:594
+Rumbling Ruin:592
+Skitter Eel:590
+Wrecking Beast:588
+Gateway Sneak:586
+Sage's Row Savant:584
+Gate Colossus:582
+Swirling Torrent:580
+Light Up the Stage:578
+Senate Courier:576
+Sentinel's Mark:574
+Ghor-Clan Wrecker:572
+Angelic Exaltation:571
+Blade Juggler:569
+Bring to Trial:567
+Code of Constraint:565
+Eyes Everywhere:563
+Gravel-Hide Goblin:561
+Absorb:559
+Sphinx's Insight:557
+Bladebrand:555
+Hallowed Fountain:553
+Verity Circle:551
+Archway Angel:549
+Breeding Pool:547
+Twilight Panther:545
+Resolute Watchdog:543
+Gates Ablaze:541
+Rakdos Roustabout:539
+Rubblebelt Recluse:537
+Mammoth Spider:535
+Knight of the Last Breath:533
+Territorial Boar:531
+Glass of the Guildpact:529
+Undercity Scavenger:527
+Blood Crypt:525
+Macabre Mockery:522
+Steeple Creeper:520
+Impassioned Orator:518
+Arrester's Zeal:516
+Kaya, Orzhov Usurper:514
+Rubble Slinger:512
+Emergency Powers:510
+Plague Wight:508
+Noxious Groodion:506
+Civic Stalwart:503
+Vizkopa Vampire:501
+Rally to Battle:499
+Gift of Strength:497
+Stomping Ground:495
+High Alert:492
+Cindervines:490
+Goblin Gathering:488
+Storm Strike:486
+Shimmer of Possibility:483
+Bloodmist Infiltrator:481
+Smelt-Ward Ignus:479
+Footlight Fiend:477
+Godless Shrine:474
+Rakdos Trumpeter:472
+Slimebind:469
+Debtors' Transport:467
+Spear Spewer:465
+Stony Strength:462
+Mirror March:460
+Carrion Imp:457
+Tome of the Guildpact:455
+Open the Gates:452
+Concordia Pegasus:450
+Ill-Gotten Inheritance:447
+Quench:445
+Sylvan Brushstrider:442
+Tenth District Veteran:439
+Lavinia, Azorius Renegade:437
+Drill Bit:434
+Watchful Giant:431
+Scuttlegator:428
+Regenesis:426
+Humongulus:423
+Spikewheel Acrobat:420
+Axebane Beast:417
+Haazda Officer:414
+Prying Eyes:411
+Knight of Sorrows:408
+Plaza of Harmony:405
+Rafter Demon:402
+Saruli Caretaker:399
+Awaken the Erstwhile:396
+Thought Collapse:392
+Wilderness Reclamation:389
+Act of Treason:386
+Smothering Tithe:382
+Tin Street Dodger:379
+Catacomb Crocodile:375
+Sagittars' Volley:371
+Cavalcade of Calamity:368
+Azorius Guildgate:364
+Orzhov Guildgate:360
+Bankrupt in Blood:356
+Persistent Petitioners:352
+Gateway Plaza:348
+Simic Guildgate:343
+Thirsting Shade:339
+Justiciar's Portal:334
+Font of Agonies:329
+Tower Defense:325
+Wall of Lost Thoughts:320
+Rakdos Guildgate:314
+Feral Maaka:309
+Burn Bright:303
+Gruul Guildgate:297
+Expose to Daylight:291
+Gruul Locket:285
+Azorius Locket:278
+Prowling Caracal:271
+Simic Locket:263
+Coral Commando:255
+Screaming Shield:246
+Junktroller:236
+Scrabbling Claws:226
+Orzhov Locket:214
+Rampage of the Clans:201
+Deface:186
+Clear the Mind:168
+Rakdos Locket:145
+Rubble Reading:115
+Root Snare:66
\ No newline at end of file
diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml
index c3c78bb4e93..99b1af89d28 100644
--- a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-player-ai-mcts
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml
index 1a6103ef54d..b9fa2e06d15 100644
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-player-aiminimax
diff --git a/Mage.Server.Plugins/Mage.Player.Human/pom.xml b/Mage.Server.Plugins/Mage.Player.Human/pom.xml
index 59ecd9969b5..70766f01b85 100644
--- a/Mage.Server.Plugins/Mage.Player.Human/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.Human/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-player-human
diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml
index 8e791631f4f..ae783f103b4 100644
--- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml
+++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-tournament-boosterdraft
diff --git a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml
index 91a6ef148f1..f6035abaa47 100644
--- a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml
+++ b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-tournament-constructed
diff --git a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml
index d51fc65a620..c30f7193e58 100644
--- a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml
+++ b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-server-plugins
- 1.4.32
+ 1.4.33
mage-tournament-sealed
diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml
index 6e660046e92..8ee5605668b 100644
--- a/Mage.Server.Plugins/pom.xml
+++ b/Mage.Server.Plugins/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage-server-plugins
diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml
index 1ca377aaf5f..4b762aa1d1a 100644
--- a/Mage.Server/pom.xml
+++ b/Mage.Server/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage-server
diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java
index 03fe704d7e1..06dc38db0f9 100644
--- a/Mage.Server/src/main/java/mage/server/Main.java
+++ b/Mage.Server/src/main/java/mage/server/Main.java
@@ -56,9 +56,9 @@ public final class Main {
private static final File extensionFolder = new File("extensions");
public static final PluginClassLoader classLoader = new PluginClassLoader();
- public static TransporterServer server;
- protected static boolean testMode;
- protected static boolean fastDbMode;
+ private static TransporterServer server;
+ private static boolean testMode;
+ private static boolean fastDbMode;
/**
* @param args the command line arguments
@@ -418,8 +418,10 @@ public final class Main {
File[] files = directory.listFiles(
(dir, name) -> name.endsWith(".game")
);
- for (File file : files) {
- file.delete();
+ if(files != null) {
+ for (File file : files) {
+ file.delete();
+ }
}
}
diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManager.java
index 66d9c7d8e14..a0a30d2edd0 100644
--- a/Mage.Server/src/main/java/mage/server/SessionManager.java
+++ b/Mage.Server/src/main/java/mage/server/SessionManager.java
@@ -1,14 +1,15 @@
package mage.server;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.annotation.Nonnull;
import mage.MageException;
import mage.players.net.UserData;
import org.apache.log4j.Logger;
import org.jboss.remoting.callback.InvokerCallbackHandler;
+import javax.annotation.Nonnull;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* @author BetaSteward_at_googlemail.com
*/
@@ -88,18 +89,15 @@ public enum SessionManager {
}
public boolean setUserData(String userName, String sessionId, UserData userData, String clientVersion, String userIdStr) throws MageException {
- Session session = sessions.get(sessionId);
- if (session != null) {
- session.setUserData(userName, userData, clientVersion, userIdStr);
- return true;
- }
- return false;
+ return getSession(sessionId)
+ .map(session -> session.setUserData(userName,userData, clientVersion, userIdStr))
+ .orElse(false);
+
}
public void disconnect(String sessionId, DisconnectReason reason) {
- Session session = sessions.get(sessionId);
- if (session != null) {
- if (!sessions.containsKey(sessionId)) {
+ getSession(sessionId).ifPresent(session -> {
+ if (!isValidSession(sessionId)) {
// session was removed meanwhile by another thread so we can return
return;
}
@@ -122,11 +120,11 @@ public enum SessionManager {
default:
logger.trace("endSession: unexpected reason " + reason.toString() + " - sessionId: " + sessionId);
}
-
- }
+ });
}
+
/**
* Admin requested the disconnect of a user
*
@@ -150,11 +148,9 @@ public enum SessionManager {
}
private Optional getUserFromSession(String sessionId) {
- Optional session = getSession(sessionId);
- if (!session.isPresent()) {
- return Optional.empty();
- }
- return UserManager.instance.getUser(session.get().getUserId());
+ return getSession(sessionId)
+ .flatMap(s -> UserManager.instance.getUser(s.getUserId()));
+
}
public void endUserSession(String sessionId, String userSessionId) {
@@ -164,11 +160,8 @@ public enum SessionManager {
}
public boolean isAdmin(String sessionId) {
- Session admin = sessions.get(sessionId);
- if (admin != null) {
- return admin.isAdmin();
- }
- return false;
+ return getSession(sessionId).map(Session::isAdmin).orElse(false);
+
}
public boolean isValidSession(@Nonnull String sessionId) {
@@ -185,11 +178,9 @@ public enum SessionManager {
}
public boolean extendUserSession(String sessionId, String pingInfo) {
- Session session = sessions.get(sessionId);
- if (session != null) {
- return UserManager.instance.extendUserSession(session.getUserId(), pingInfo);
- }
- return false;
+ return getSession(sessionId)
+ .map(session -> UserManager.instance.extendUserSession(session.getUserId(), pingInfo))
+ .orElse(false);
}
public void sendErrorMessageToClient(String sessionId, String message) {
diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java
index 90e7638c6e3..914bdf3a53c 100644
--- a/Mage.Server/src/main/java/mage/server/TableController.java
+++ b/Mage.Server/src/main/java/mage/server/TableController.java
@@ -927,12 +927,10 @@ public class TableController {
public boolean isTournamentStillValid() {
if (table.getTournament() != null) {
if (table.getState() != TableState.WAITING && table.getState() != TableState.READY_TO_START && table.getState() != TableState.STARTING) {
- TournamentController tournamentController = TournamentManager.instance.getTournamentController(table.getTournament().getId());
- if (tournamentController != null) {
- return tournamentController.isTournamentStillValid(table.getState());
- } else {
- return false;
- }
+ return TournamentManager.instance.getTournamentController(table.getTournament().getId())
+ .map(tc -> tc.isTournamentStillValid(table.getState()))
+ .orElse(false);
+
} else {
// check if table creator is still a valid user, if not removeUserFromAllTablesAndChat table
return UserManager.instance.getUser(userId).isPresent();
diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java
index 0649e7ac20a..930133aa73f 100644
--- a/Mage.Server/src/main/java/mage/server/User.java
+++ b/Mage.Server/src/main/java/mage/server/User.java
@@ -334,10 +334,10 @@ public class User {
}
for (Iterator> iterator = userTournaments.entrySet().iterator(); iterator.hasNext();) {
Entry next = iterator.next();
- TournamentController tournamentController = TournamentManager.instance.getTournamentController(next.getValue());
- if (tournamentController != null) {
+ Optional tournamentController = TournamentManager.instance.getTournamentController(next.getValue());
+ if (tournamentController.isPresent()) {
ccTournamentStarted(next.getValue(), next.getKey());
- tournamentController.rejoin(next.getKey());
+ tournamentController.get().rejoin(next.getKey());
} else {
iterator.remove(); // tournament has ended meanwhile
}
diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java
index 4473afb3e08..a3c1c43842e 100644
--- a/Mage.Server/src/main/java/mage/server/UserManager.java
+++ b/Mage.Server/src/main/java/mage/server/UserManager.java
@@ -70,13 +70,8 @@ public enum UserManager {
final Lock r = lock.readLock();
r.lock();
try {
- Optional u = users.values().stream().filter(user -> user.getName().equals(userName))
+ return users.values().stream().filter(user -> user.getName().equals(userName))
.findFirst();
- if (u.isPresent()) {
- return u;
- } else {
- return Optional.empty();
- }
} finally {
r.unlock();
}
@@ -84,7 +79,7 @@ public enum UserManager {
}
public Collection getUsers() {
- ArrayList userList = new ArrayList<>();
+ List userList = new ArrayList<>();
final Lock r = lock.readLock();
r.lock();
try {
diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java
index b3a1f6d7d15..450f0fbe050 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameController.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameController.java
@@ -627,7 +627,7 @@ public class GameController implements GameCallback {
for (MatchPlayer p : TableManager.instance.getTable(tableId).getMatch().getPlayers()) {
if (p.getPlayer().getId().equals(userIdRequester)) {
Optional u = UserManager.instance.getUser(origId);
- if (u != null && u.isPresent() && p.getDeck() != null) {
+ if (u.isPresent() && p.getDeck() != null) {
u.get().ccViewLimitedDeck(p.getDeck(), tableId, requestsOpen, true);
}
}
diff --git a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java
index d9a611d26cd..da4844fed9a 100644
--- a/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java
+++ b/Mage.Server/src/main/java/mage/server/tournament/TournamentManager.java
@@ -16,8 +16,8 @@ public enum TournamentManager {
instance;
private final ConcurrentHashMap controllers = new ConcurrentHashMap<>();
- public TournamentController getTournamentController(UUID tournamentId) {
- return controllers.get(tournamentId);
+ public Optional getTournamentController(UUID tournamentId) {
+ return Optional.ofNullable(controllers.get(tournamentId));
}
public void createTournamentSession(Tournament tournament, ConcurrentHashMap userPlayerMap, UUID tableId) {
diff --git a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java
index 4d6f2cb51d5..41e8b9e6918 100644
--- a/Mage.Server/src/main/java/mage/server/util/SystemUtil.java
+++ b/Mage.Server/src/main/java/mage/server/util/SystemUtil.java
@@ -7,9 +7,12 @@ import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
+import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
+import mage.counters.CounterType;
import mage.game.Game;
+import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.util.RandomUtil;
@@ -433,6 +436,13 @@ public final class SystemUtil {
game.addPlane((mage.game.command.Plane) plane, null, player.getId());
continue;
}
+ } else if ("loyalty".equalsIgnoreCase(command.zone)) {
+ for (Permanent perm : game.getBattlefield().getAllActivePermanents(player.getId())) {
+ if (perm.getName().equals(command.cardName) && perm.getCardType().contains(CardType.PLANESWALKER)) {
+ perm.addCounters(CounterType.LOYALTY.createInstance(command.Amount), null, game);
+ }
+ }
+ continue;
}
Zone gameZone;
diff --git a/Mage.Sets/pom.xml b/Mage.Sets/pom.xml
index 6f88ade019a..6992395f0d4 100644
--- a/Mage.Sets/pom.xml
+++ b/Mage.Sets/pom.xml
@@ -7,7 +7,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
org.mage
diff --git a/Mage.Sets/src/mage/cards/a/AbandonHope.java b/Mage.Sets/src/mage/cards/a/AbandonHope.java
index a1adea968ab..635917a8982 100644
--- a/Mage.Sets/src/mage/cards/a/AbandonHope.java
+++ b/Mage.Sets/src/mage/cards/a/AbandonHope.java
@@ -34,7 +34,7 @@ public final class AbandonHope extends CardImpl {
this.addAbility(ability);
// Look at target opponent's hand and choose X cards from it. That player discards those cards.
- ManacostVariableValue manaX = new ManacostVariableValue();
+ ManacostVariableValue manaX = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new DiscardCardYouChooseTargetEffect(manaX, TargetController.ANY));
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().setCostAdjuster(AbandonHopeAdjuster.instance);
diff --git a/Mage.Sets/src/mage/cards/a/AdamaroFirstToDesire.java b/Mage.Sets/src/mage/cards/a/AdamaroFirstToDesire.java
index a4b80c6083e..134eaaabf50 100644
--- a/Mage.Sets/src/mage/cards/a/AdamaroFirstToDesire.java
+++ b/Mage.Sets/src/mage/cards/a/AdamaroFirstToDesire.java
@@ -1,7 +1,6 @@
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@@ -14,14 +13,15 @@ import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class AdamaroFirstToDesire extends CardImpl {
public AdamaroFirstToDesire(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SPIRIT);
@@ -46,7 +46,7 @@ class MostCardsInOpponentsHandCount implements DynamicValue {
@Override
public int calculate(Game game, Ability source, Effect effect) {
int maxCards = 0;
- for (UUID opponentId: game.getOpponents(source.getControllerId())) {
+ for (UUID opponentId : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
int cards = opponent.getHand().size();
@@ -60,7 +60,7 @@ class MostCardsInOpponentsHandCount implements DynamicValue {
@Override
public DynamicValue copy() {
- return new mage.abilities.dynamicvalue.common.CardsInControllerHandCount();
+ return new MostCardsInOpponentsHandCount();
}
@Override
diff --git a/Mage.Sets/src/mage/cards/a/AeonChronicler.java b/Mage.Sets/src/mage/cards/a/AeonChronicler.java
index 4a6d8d4b4a3..8b3f42378d0 100644
--- a/Mage.Sets/src/mage/cards/a/AeonChronicler.java
+++ b/Mage.Sets/src/mage/cards/a/AeonChronicler.java
@@ -36,7 +36,7 @@ public final class AeonChronicler extends CardImpl {
this.toughness = new MageInt(0);
// Aeon Chronicler's power and toughness are each equal to the number of cards in your hand.
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInControllerHandCount(), Duration.EndOfGame)));
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(CardsInControllerHandCount.instance, Duration.EndOfGame)));
// Suspend X-{X}{3}{U}. X can't be 0.
this.addAbility(new SuspendAbility(Integer.MAX_VALUE, new ManaCostsImpl("{3}{U}"), this, true));
diff --git a/Mage.Sets/src/mage/cards/a/AetherMutation.java b/Mage.Sets/src/mage/cards/a/AetherMutation.java
index 4f0fad54ba3..c5b9b39587f 100644
--- a/Mage.Sets/src/mage/cards/a/AetherMutation.java
+++ b/Mage.Sets/src/mage/cards/a/AetherMutation.java
@@ -25,7 +25,7 @@ public final class AetherMutation extends CardImpl {
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// create X 1/1 green Saproling creature tokens, where X is that creature's converted mana cost.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), new TargetConvertedManaCost()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), TargetConvertedManaCost.instance));
}
public AetherMutation(final AetherMutation card) {
diff --git a/Mage.Sets/src/mage/cards/a/AetherTide.java b/Mage.Sets/src/mage/cards/a/AetherTide.java
index fc3c6c4915b..f368a6ff020 100644
--- a/Mage.Sets/src/mage/cards/a/AetherTide.java
+++ b/Mage.Sets/src/mage/cards/a/AetherTide.java
@@ -2,23 +2,22 @@ package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.VariableCostImpl;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.costs.CostAdjuster;
import mage.abilities.costs.common.DiscardTargetCost;
-import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.common.InfoEffect;
+import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.cards.CardsImpl;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
-import mage.game.stack.StackObject;
-import mage.players.Player;
-import mage.target.TargetPermanent;
import mage.target.common.TargetCardInHand;
+import mage.target.common.TargetCreaturePermanent;
+import mage.target.targetadjustment.TargetAdjuster;
/**
*
@@ -30,10 +29,16 @@ public final class AetherTide extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}");
// As an additional cost to cast Aether Tide, discard X creature cards.
- this.getSpellAbility().addCost(new AetherTideCost());
+ Ability ability = new SimpleStaticAbility(Zone.ALL, new InfoEffect("As an additional cost to cast {this}, discard X creature cards"));
+ ability.setRuleAtTheTop(true);
+ this.addAbility(ability);
// Return X target creatures to their owners' hands.
- this.getSpellAbility().addEffect(new ReturnToHandTargetPermanentEffect());
+ Effect effect = new ReturnToHandTargetEffect(true);
+ effect.setText("Return X target creatures to their owners' hands");
+ this.getSpellAbility().addEffect(effect);
+ this.getSpellAbility().setTargetAdjuster(AetherTideTargetAdjuster.instance);
+ this.getSpellAbility().setCostAdjuster(AetherTideCostAdjuster.instance);
}
@@ -47,98 +52,25 @@ public final class AetherTide extends CardImpl {
}
}
-class AetherTideCost extends VariableCostImpl {
-
- public AetherTideCost() {
- super("discard X creature cards");
- text = "As an additional cost to cast {this}, discard X creature cards";
- }
-
- public AetherTideCost(AetherTideCost cost) {
- super(cost);
- }
+enum AetherTideTargetAdjuster implements TargetAdjuster {
+ instance;
@Override
- public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
- return (game.getPlayer(controllerId).getHand().count(new FilterCreatureCard(), game) > 0);
+ public void adjustTargets(Ability ability, Game game) {
+ ability.getTargets().clear();
+ int xValue = ability.getManaCostsToPay().getX();
+ ability.addTarget(new TargetCreaturePermanent(xValue, xValue, new FilterCreaturePermanent(), false));
}
-
- @Override
- public int getMaxValue(Ability source, Game game) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- return controller.getHand().count(new FilterCreatureCard(), game);
- }
- return 0;
- }
-
- @Override
- public int getMinValue(Ability source, Game game) {
- return 0;
- }
-
- @Override
- public Cost getFixedCostsFromAnnouncedValue(int xValue) {
- TargetCardInHand target = new TargetCardInHand(xValue, new FilterCreatureCard());
- return new DiscardTargetCost(target);
- }
-
- @Override
- public int announceXValue(Ability source, Game game) {
- int xValue = 0;
- Player controller = game.getPlayer(source.getControllerId());
- StackObject stackObject = game.getStack().getStackObject(source.getId());
- if (controller != null
- && stackObject != null) {
- xValue = controller.announceXCost(getMinValue(source, game), getMaxValue(source, game),
- "Announce the number of creature cards to discard", game, source, this);
- }
- return xValue;
- }
-
- @Override
- public AetherTideCost copy() {
- return new AetherTideCost(this);
- }
-
}
-class ReturnToHandTargetPermanentEffect extends OneShotEffect {
-
- public ReturnToHandTargetPermanentEffect() {
- super(Outcome.ReturnToHand);
- setText("Return X target creatures to their owners' hands");
- }
-
- public ReturnToHandTargetPermanentEffect(final ReturnToHandTargetPermanentEffect effect) {
- super(effect);
- }
+enum AetherTideCostAdjuster implements CostAdjuster {
+ instance;
@Override
- public ReturnToHandTargetPermanentEffect copy() {
- return new ReturnToHandTargetPermanentEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- int xPaid = source.getCosts().getVariableCosts().get(0).getAmount();
- if (controller != null
- && xPaid > 0) {
- int available = game.getBattlefield().count(new FilterCreaturePermanent(),
- source.getSourceId(),
- source.getControllerId(), game);
- if (available > 0) {
- TargetPermanent target = new TargetPermanent(Math.min(xPaid, available),
- xPaid,
- new FilterCreaturePermanent("creatures to return to their owner's hands"),
- true);
- if (controller.chooseTarget(outcome.Detriment, target, source, game)) {
- controller.moveCards(new CardsImpl(target.getTargets()), Zone.HAND, source, game);
- }
- return true;
- }
+ public void adjustCosts(Ability ability, Game game) {
+ int xValue = ability.getManaCostsToPay().getX();
+ if (xValue > 0) {
+ ability.addCost(new DiscardTargetCost(new TargetCardInHand(xValue, xValue, new FilterCreatureCard("creature cards"))));
}
- return false;
}
}
diff --git a/Mage.Sets/src/mage/cards/a/Aggression.java b/Mage.Sets/src/mage/cards/a/Aggression.java
new file mode 100644
index 00000000000..78b9408748f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/a/Aggression.java
@@ -0,0 +1,104 @@
+package mage.cards.a;
+
+import java.util.UUID;
+import mage.MageObjectReference;
+import mage.constants.SubType;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalTriggeredAbility;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.DestroyAttachedToEffect;
+import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
+import mage.constants.Outcome;
+import mage.target.TargetPermanent;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.TrampleAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AttachmentType;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.watchers.common.AttackedThisTurnWatcher;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public final class Aggression extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
+
+ static {
+ filter.add(Predicates.not(new SubtypePredicate(SubType.WALL)));
+ }
+
+ public Aggression(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant non-Wall creature
+ TargetPermanent auraTarget = new TargetPermanent(filter);
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // Enchanted creature has first strike and trample.
+ Ability ability2 = new SimpleStaticAbility(
+ Zone.BATTLEFIELD,
+ new GainAbilityAttachedEffect(
+ FirstStrikeAbility.getInstance(),
+ AttachmentType.AURA));
+ ability2.addEffect(new GainAbilityAttachedEffect(
+ TrampleAbility.getInstance(),
+ AttachmentType.AURA));
+ this.addAbility(ability2);
+
+ // At the beginning of the end step of enchanted creature's controller, destroy that creature if it didn't attack this turn.
+ this.addAbility(new ConditionalTriggeredAbility(
+ new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new DestroyAttachedToEffect("enchanted"),
+ TargetController.CONTROLLER_ATTACHED_TO),
+ DidNotAttackedThisTurnEnchantedCondition.instance,
+ "At the beginning of the end step of enchanted creature's controller, destroy that creature if it didn't attack this turn."),
+ new AttackedThisTurnWatcher());
+
+ }
+
+ private Aggression(final Aggression card) {
+ super(card);
+ }
+
+ @Override
+ public Aggression copy() {
+ return new Aggression(this);
+ }
+}
+
+enum DidNotAttackedThisTurnEnchantedCondition implements Condition {
+ instance;
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent auraPermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (auraPermanent != null) {
+ Permanent enchantedPermanent = game.getPermanent(auraPermanent.getAttachedTo());
+ AttackedThisTurnWatcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class);
+ return enchantedPermanent != null
+ && watcher != null
+ && !watcher.getAttackedThisTurnCreatures().contains(
+ new MageObjectReference(enchantedPermanent, game));
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/a/AgonizingDemise.java b/Mage.Sets/src/mage/cards/a/AgonizingDemise.java
index a183e73f73e..dcaab970431 100644
--- a/Mage.Sets/src/mage/cards/a/AgonizingDemise.java
+++ b/Mage.Sets/src/mage/cards/a/AgonizingDemise.java
@@ -40,7 +40,7 @@ public final class AgonizingDemise extends CardImpl {
//If Agonizing Demise was kicked, it deals damage equal to that creature's power to the creature's controller.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetControllerEffect(new TargetPermanentPowerCount()),
+ new DamageTargetControllerEffect(TargetPermanentPowerCount.instance),
KickedCondition.instance,
"if this spell was kicked, it deals damage equal to that creature's power to the creature's controller."));
diff --git a/Mage.Sets/src/mage/cards/a/AirdropCondor.java b/Mage.Sets/src/mage/cards/a/AirdropCondor.java
index 447fbfae6c7..824ef1f5721 100644
--- a/Mage.Sets/src/mage/cards/a/AirdropCondor.java
+++ b/Mage.Sets/src/mage/cards/a/AirdropCondor.java
@@ -42,7 +42,7 @@ public final class AirdropCondor extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// {1}{R}, Sacrifice a Goblin creature: Airdrop Condor deals damage equal to the sacrificed creature's power to any target.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new SacrificeCostCreaturesPower()), new ManaCostsImpl("{1}{R}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(SacrificeCostCreaturesPower.instance), new ManaCostsImpl("{1}{R}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter)));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java b/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java
index 0dfdd6a8bf5..a3b0b04fc46 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniCallerOfThePride.java
@@ -49,7 +49,7 @@ public final class AjaniCallerOfThePride extends CardImpl {
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// -8: create X 2/2 white Cat creature tokens, where X is your life total.
- this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new CatToken(), new ControllerLifeCount()), -8));
+ this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new CatToken(), ControllerLifeCount.instance), -8));
}
public AjaniCallerOfThePride(final AjaniCallerOfThePride card) {
diff --git a/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
index 00f6ca6c98f..7bec5ea3f33 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniValiantProtector.java
@@ -44,7 +44,7 @@ public final class AjaniValiantProtector extends CardImpl {
this.addAbility(new LoyaltyAbility(new RevealCardsFromLibraryUntilEffect(new FilterCreatureCard(), Zone.HAND, Zone.LIBRARY), 1));
// -11: Put X +1/+1 counters on target creature, where X is your life total. That creature gains trample until end of turn.
- Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), new ControllerLifeCount());
+ Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), ControllerLifeCount.instance);
effect.setText("Put X +1/+1 counters on target creature, where X is your life total.");
ability = new LoyaltyAbility(effect, -11);
effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
diff --git a/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java b/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java
index 8a28d2545e2..02198d974d4 100644
--- a/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java
+++ b/Mage.Sets/src/mage/cards/a/AjaniWiseCounselor.java
@@ -44,7 +44,7 @@ public final class AjaniWiseCounselor extends CardImpl {
// −9: Put X +1/+1 counters on target creature, where X is your life total.
Ability ability = new LoyaltyAbility(new AddCountersTargetEffect(
CounterType.P1P1.createInstance(),
- new ControllerLifeCount()
+ ControllerLifeCount.instance
).setText("put X +1/+1 counters on target creature, where X is your life total"), -9);
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/a/AjanisPridemate.java b/Mage.Sets/src/mage/cards/a/AjanisPridemate.java
index 124891d3c79..ad07f8d4e93 100644
--- a/Mage.Sets/src/mage/cards/a/AjanisPridemate.java
+++ b/Mage.Sets/src/mage/cards/a/AjanisPridemate.java
@@ -2,38 +2,37 @@
package mage.cards.a;
-import java.util.UUID;
import mage.MageInt;
-import mage.abilities.TriggeredAbilityImpl;
+import mage.abilities.common.GainLifeControllerTriggeredAbility;
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.constants.Zone;
import mage.counters.CounterType;
-import mage.game.Game;
-import mage.game.events.GameEvent;
-import mage.game.events.GameEvent.EventType;
+
+import java.util.UUID;
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public final class AjanisPridemate extends CardImpl {
public AjanisPridemate(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add(SubType.CAT);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- this.addAbility(new AjanisPridemateAbility());
+ // Whenever you gain life, put a +1/+1 counter on Ajani's Pridemate.
+ this.addAbility(new GainLifeControllerTriggeredAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false
+ ));
}
- public AjanisPridemate(final AjanisPridemate card) {
+ private AjanisPridemate(final AjanisPridemate card) {
super(card);
}
@@ -43,35 +42,3 @@ public final class AjanisPridemate extends CardImpl {
}
}
-
-class AjanisPridemateAbility extends TriggeredAbilityImpl {
-
- public AjanisPridemateAbility() {
- super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true);
- }
-
- public AjanisPridemateAbility(final AjanisPridemateAbility ability) {
- super(ability);
- }
-
- @Override
- public AjanisPridemateAbility copy() {
- return new AjanisPridemateAbility(this);
- }
-
- @Override
- public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == EventType.GAINED_LIFE;
- }
-
- @Override
- public boolean checkTrigger(GameEvent event, Game game) {
- return event.getPlayerId().equals(controllerId);
- }
-
- @Override
- public String getRule() {
- return "Whenever you gain life, you may put a +1/+1 counter on {this}.";
- }
-
-}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/AlabasterPotion.java b/Mage.Sets/src/mage/cards/a/AlabasterPotion.java
index 2e918e1fe18..9a69608a6f5 100644
--- a/Mage.Sets/src/mage/cards/a/AlabasterPotion.java
+++ b/Mage.Sets/src/mage/cards/a/AlabasterPotion.java
@@ -23,10 +23,10 @@ public final class AlabasterPotion extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{W}{W}");
// Choose one - Target player gains X life; or prevent the next X damage that would be dealt to any target this turn.
- this.getSpellAbility().addEffect(new GainLifeTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new GainLifeTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayer());
Mode mode = new Mode();
- mode.addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, new ManacostVariableValue()));
+ mode.addEffect(new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, ManacostVariableValue.instance));
mode.addTarget(new TargetAnyTarget());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/a/Aleatory.java b/Mage.Sets/src/mage/cards/a/Aleatory.java
index 71080e6298b..eb33925b2bc 100644
--- a/Mage.Sets/src/mage/cards/a/Aleatory.java
+++ b/Mage.Sets/src/mage/cards/a/Aleatory.java
@@ -67,7 +67,7 @@ class AleatoryEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
game.addEffect(new BoostTargetEffect(1, 1, Duration.EndOfTurn), source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/a/Amplifire.java b/Mage.Sets/src/mage/cards/a/Amplifire.java
index 273435ab00c..a93e1f986f9 100644
--- a/Mage.Sets/src/mage/cards/a/Amplifire.java
+++ b/Mage.Sets/src/mage/cards/a/Amplifire.java
@@ -81,7 +81,7 @@ class AmplifireEffect extends OneShotEffect {
game.addEffect(new SetPowerToughnessSourceEffect(
2 * lastCard.getPower().getValue(),
2 * lastCard.getToughness().getValue(),
- Duration.UntilYourNextTurn
+ Duration.UntilYourNextTurn, SubLayer.SetPT_7b
), source);
}
player.putCardsOnBottomOfLibrary(cards, game, source, false);
diff --git a/Mage.Sets/src/mage/cards/a/AncientExcavation.java b/Mage.Sets/src/mage/cards/a/AncientExcavation.java
index 4965f68132a..c339ac270d0 100644
--- a/Mage.Sets/src/mage/cards/a/AncientExcavation.java
+++ b/Mage.Sets/src/mage/cards/a/AncientExcavation.java
@@ -61,7 +61,7 @@ class AncientExcavationEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- DynamicValue numCards = new CardsInControllerHandCount();
+ DynamicValue numCards = CardsInControllerHandCount.instance;
int amount = numCards.calculate(game, source, this);
player.drawCards(amount, game);
player.discard(amount, false, source, game);
diff --git a/Mage.Sets/src/mage/cards/a/ApexHawks.java b/Mage.Sets/src/mage/cards/a/ApexHawks.java
index 796decca43d..12d41455eb8 100644
--- a/Mage.Sets/src/mage/cards/a/ApexHawks.java
+++ b/Mage.Sets/src/mage/cards/a/ApexHawks.java
@@ -35,7 +35,7 @@ public final class ApexHawks extends CardImpl {
// Apex Hawks enters the battlefield with a +1/+1 counter on it for each time it was kicked.
this.addAbility(new EntersBattlefieldAbility(
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new MultikickerCount(), true)
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), MultikickerCount.instance, true)
,"with a +1/+1 counter on it for each time it was kicked"));
}
diff --git a/Mage.Sets/src/mage/cards/a/ArashiTheSkyAsunder.java b/Mage.Sets/src/mage/cards/a/ArashiTheSkyAsunder.java
index 7a91c68a674..e474a02af84 100644
--- a/Mage.Sets/src/mage/cards/a/ArashiTheSkyAsunder.java
+++ b/Mage.Sets/src/mage/cards/a/ArashiTheSkyAsunder.java
@@ -43,13 +43,13 @@ public final class ArashiTheSkyAsunder extends CardImpl {
this.toughness = new MageInt(5);
// {X}{G}, {tap}: Arashi, the Sky Asunder deals X damage to target creature with flying.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}{G}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{G}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
// Channel - {X}{G}{G}, Discard Arashi: Arashi deals X damage to each creature with flying.
- this.addAbility(new ChannelAbility("{X}{G}{G}", new DamageAllEffect(new ManacostVariableValue(), filter)));
+ this.addAbility(new ChannelAbility("{X}{G}{G}", new DamageAllEffect(ManacostVariableValue.instance, filter)));
}
public ArashiTheSkyAsunder(final ArashiTheSkyAsunder card) {
diff --git a/Mage.Sets/src/mage/cards/a/ArtifactMutation.java b/Mage.Sets/src/mage/cards/a/ArtifactMutation.java
index 2aaa2ef0272..43c0240f8e0 100644
--- a/Mage.Sets/src/mage/cards/a/ArtifactMutation.java
+++ b/Mage.Sets/src/mage/cards/a/ArtifactMutation.java
@@ -25,7 +25,7 @@ public final class ArtifactMutation extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));
this.getSpellAbility().addTarget(new TargetArtifactPermanent());
// create X 1/1 green Saproling creature tokens, where X is that artifact's converted mana cost.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), new TargetConvertedManaCost()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), TargetConvertedManaCost.instance));
}
public ArtifactMutation(final ArtifactMutation card) {
diff --git a/Mage.Sets/src/mage/cards/a/AsForetold.java b/Mage.Sets/src/mage/cards/a/AsForetold.java
index 01dc7cb5670..e5cf038407d 100644
--- a/Mage.Sets/src/mage/cards/a/AsForetold.java
+++ b/Mage.Sets/src/mage/cards/a/AsForetold.java
@@ -16,19 +16,13 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
-import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
-import mage.watchers.Watcher;
/**
*
* @author stravant
*
- * Note, this card is pretty hacky in its implementation due to the fact that
- * the alternative cost system doesn't really support "once each turn"
- * alternative costs in an obvious way, but it should work in all scenarios as
- * far as I can see.
*/
public final class AsForetold extends CardImpl {
@@ -43,13 +37,12 @@ public final class AsForetold extends CardImpl {
new StaticValue(1),
true),
TargetController.YOU,
- /* optional = */ false));
+ false));
// Once each turn, you may pay {0} rather than pay the mana cost for a spell you cast with converted mana cost X or less, where X is the number of time counters on As Foretold.
addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
- new AsForetoldAddAltCostEffect()),
- new AsForetoldAltCostUsedWatcher());
+ new AsForetoldAddAltCostEffect()));
}
@@ -98,7 +91,7 @@ class AsForetoldAlternativeCost extends AlternativeCostSourceAbility {
this.sourceAsForetold = sourceAsForetold;
}
- private AsForetoldAlternativeCost(final AsForetoldAlternativeCost ability) {
+ private AsForetoldAlternativeCost(final AsForetoldAlternativeCost ability) {
super(ability);
this.sourceAsForetold = ability.sourceAsForetold;
this.wasActivated = ability.wasActivated;
@@ -115,15 +108,13 @@ class AsForetoldAlternativeCost extends AlternativeCostSourceAbility {
Permanent asForetold = game.getPermanent(sourceAsForetold);
if (controller != null
&& asForetold != null) {
- if (controller.chooseUse(Outcome.Neutral, "Do you wish to use " + asForetold.getLogName() + " to pay the alternative cost ?", ability, game)) {
+ if (controller.chooseUse(Outcome.Neutral, "Do you wish to use "
+ + asForetold.getLogName() + " to pay the alternative cost ?", ability, game)) {
wasActivated = super.askToActivateAlternativeCosts(ability, game);
if (wasActivated) {
- // Get the watcher
- AsForetoldAltCostUsedWatcher asForetoldAltCostUsedWatcher
- = game.getState().getWatcher(AsForetoldAltCostUsedWatcher.class, sourceAsForetold);
-
- // Mark as used
- asForetoldAltCostUsedWatcher.markUsedThisTurn();
+ game.getState().setValue(asForetold.getId().toString()
+ + asForetold.getZoneChangeCounter(game)
+ + asForetold.getTurnsOnBattlefield(), true);
}
}
}
@@ -158,17 +149,16 @@ class AsForetoldAddAltCostEffect extends ContinuousEffectImpl {
if (controller != null) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null) {
- // Get the watcher
- AsForetoldAltCostUsedWatcher asForetoldAltCostUsedWatcher
- = game.getState().getWatcher(
- AsForetoldAltCostUsedWatcher.class, sourcePermanent.getId());
-
+ Boolean wasItUsed = (Boolean) game.getState().getValue(
+ sourcePermanent.getId().toString()
+ + sourcePermanent.getZoneChangeCounter(game)
+ + sourcePermanent.getTurnsOnBattlefield());
// If we haven't used it yet this turn, give the option of using the zero alternative cost
- if (!asForetoldAltCostUsedWatcher.hasBeenUsedThisTurn()) {
+ if (wasItUsed == null) {
int timeCounters = sourcePermanent.getCounters(game).getCount("time");
- controller.getAlternativeSourceCosts().add(new AsForetoldAlternativeCost(sourcePermanent.getId(), timeCounters));
+ controller.getAlternativeSourceCosts().add(
+ new AsForetoldAlternativeCost(sourcePermanent.getId(), timeCounters));
}
-
// Return true even if we didn't add the alt cost. We still applied the effect
return true;
}
@@ -186,40 +176,3 @@ class AsForetoldAddAltCostEffect extends ContinuousEffectImpl {
return layer == Layer.RulesEffects;
}
}
-
-/**
- * Watcher used as extra storage to record whether a given As Foretold has been
- * used this turn. Technically speaking this watcher doesn't *watch* any
- * GameEvents, but it does "watch" the alternative cost being used. That just
- * isn't possible to watch through a game event. It's still helpful to co-op the
- * Watcher system for this since it automatically handles ZoneChangeCounter
- * stuff and resetting the condition at the end of the turn.
- */
-class AsForetoldAltCostUsedWatcher extends Watcher {
-
- public AsForetoldAltCostUsedWatcher() {
- super("asForetoldAltCostUsedWatcher", WatcherScope.CARD);
- }
-
- public AsForetoldAltCostUsedWatcher(final AsForetoldAltCostUsedWatcher watcher) {
- super(watcher);
- }
-
- @Override
- public void watch(GameEvent event, Game game) {
- // Nothing to do, we explicitly mark used in the alternative cost
- }
-
- public boolean hasBeenUsedThisTurn() {
- return conditionMet();
- }
-
- public void markUsedThisTurn() {
- condition = true;
- }
-
- @Override
- public AsForetoldAltCostUsedWatcher copy() {
- return new AsForetoldAltCostUsedWatcher(this);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/a/AshenSkinZubera.java b/Mage.Sets/src/mage/cards/a/AshenSkinZubera.java
index 55f6c44791d..050b2493a30 100644
--- a/Mage.Sets/src/mage/cards/a/AshenSkinZubera.java
+++ b/Mage.Sets/src/mage/cards/a/AshenSkinZubera.java
@@ -27,7 +27,7 @@ public final class AshenSkinZubera extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(2);
- Ability ability = new DiesTriggeredAbility(new DiscardTargetEffect(new ZuberasDiedDynamicValue()));
+ Ability ability = new DiesTriggeredAbility(new DiscardTargetEffect(ZuberasDiedDynamicValue.instance));
ability.addTarget(new TargetOpponent());
this.addAbility(ability, new ZuberasDiedWatcher());
}
diff --git a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java
index 386cb7f67d7..38c00a82ce0 100644
--- a/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java
+++ b/Mage.Sets/src/mage/cards/a/AtalyaSamiteMaster.java
@@ -41,7 +41,7 @@ public final class AtalyaSamiteMaster extends CardImpl {
this.toughness = new MageInt(3);
// {X}, {tap}: Choose one - Prevent the next X damage that would be dealt to target creature this turn; or you gain X life. Spend only white mana on X.
- PreventDamageToTargetEffect effect = new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, new ManacostVariableValue());
+ PreventDamageToTargetEffect effect = new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, ManacostVariableValue.instance);
effect.setText("Prevent the next X damage that would be dealt to target creature this turn. Spend only white mana on X.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
@@ -55,7 +55,7 @@ public final class AtalyaSamiteMaster extends CardImpl {
// or you gain X life
Mode mode = new Mode();
- mode.addEffect(new GainLifeEffect(new ManacostVariableValue()).setText("You gain X life. Spend only white mana on X."));
+ mode.addEffect(new GainLifeEffect(ManacostVariableValue.instance).setText("You gain X life. Spend only white mana on X."));
ability.addMode(mode);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/a/Atogatog.java b/Mage.Sets/src/mage/cards/a/Atogatog.java
index 107f7ccbbe1..0f17b1a8a08 100644
--- a/Mage.Sets/src/mage/cards/a/Atogatog.java
+++ b/Mage.Sets/src/mage/cards/a/Atogatog.java
@@ -37,7 +37,7 @@ public final class Atogatog extends CardImpl {
this.power = new MageInt(5);
this.toughness = new MageInt(5);
- DynamicValue xValue = new SacrificeCostCreaturesPower();
+ DynamicValue xValue = SacrificeCostCreaturesPower.instance;
// Sacrifice an Atog creature: Atogatog gets +X/+X until end of turn, where X is the sacrificed creature's power.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
new BoostSourceEffect(xValue, xValue,Duration.EndOfTurn),
diff --git a/Mage.Sets/src/mage/cards/a/AuraMutation.java b/Mage.Sets/src/mage/cards/a/AuraMutation.java
index 6586f22e633..7eaad0d970c 100644
--- a/Mage.Sets/src/mage/cards/a/AuraMutation.java
+++ b/Mage.Sets/src/mage/cards/a/AuraMutation.java
@@ -25,7 +25,7 @@ public final class AuraMutation extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetEnchantmentPermanent());
// create X 1/1 green Saproling creature tokens, where X is that enchantment's converted mana cost.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), new TargetConvertedManaCost()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), TargetConvertedManaCost.instance));
}
public AuraMutation(final AuraMutation card) {
diff --git a/Mage.Sets/src/mage/cards/a/AureliasFury.java b/Mage.Sets/src/mage/cards/a/AureliasFury.java
index 0f42f5d652e..01d4800511d 100644
--- a/Mage.Sets/src/mage/cards/a/AureliasFury.java
+++ b/Mage.Sets/src/mage/cards/a/AureliasFury.java
@@ -62,7 +62,7 @@ public final class AureliasFury extends CardImpl {
// Aurelia's Fury deals X damage divided as you choose among any number of target creatures and/or players.
// Tap each creature dealt damage this way. Players dealt damage this way can't cast noncreature spells this turn.
- DynamicValue xValue = new ManacostVariableValue();
+ DynamicValue xValue = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new DamageMultiEffect(xValue));
this.getSpellAbility().addEffect(new AureliasFuryEffect());
this.getSpellAbility().addTarget(new TargetAnyTargetAmount(xValue));
diff --git a/Mage.Sets/src/mage/cards/a/AvatarOfFury.java b/Mage.Sets/src/mage/cards/a/AvatarOfFury.java
index dbcc9e1e046..eed329a4e25 100644
--- a/Mage.Sets/src/mage/cards/a/AvatarOfFury.java
+++ b/Mage.Sets/src/mage/cards/a/AvatarOfFury.java
@@ -85,55 +85,4 @@ class AvatarOfFuryAdjustingCostsAbility extends SimpleStaticAbility implements A
}
}
}
-}
-
-//class AvatarOfFuryAdjustingCostsEffect extends CostModificationEffectImpl {
-//
-// public AvatarOfFuryAdjustingCostsEffect() {
-// super(Duration.Custom, Outcome.Benefit, CostModificationType.REDUCE_COST);
-// }
-//
-// public AvatarOfFuryAdjustingCostsEffect(final AvatarOfFuryAdjustingCostsEffect effect) {
-// super(effect);
-// }
-//
-// @Override
-// public boolean apply(Game game, Ability source, Ability abilityToModify) {
-// SpellAbility spellAbility = (SpellAbility)abilityToModify;
-// Mana mana = spellAbility.getManaCostsToPay().getMana();
-//
-// boolean condition = false;
-// FilterPermanent filter = new FilterLandPermanent();
-// for (UUID playerId: game.getOpponents(source.getControllerId())) {
-// if (game.getBattlefield().countAll(filter, playerId, game) > 6) {
-// condition = true;
-// break;
-// }
-// }
-//
-// if (mana.getColorless() > 0 && condition) {
-// int newCount = mana.getColorless() - 6;
-// if (newCount < 0) {
-// newCount = 0;
-// }
-// mana.setColorless(newCount);
-// spellAbility.getManaCostsToPay().load(mana.toString());
-// return true;
-// }
-// return false;
-// }
-//
-// @Override
-// public boolean applies(Ability abilityToModify, Ability source, Game game) {
-// if ((abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility || abilityToModify instanceof RetraceAbility)
-// && abilityToModify.getSourceId().equals(source.getSourceId())) {
-// return true;
-// }
-// return false;
-// }
-//
-// @Override
-// public AvatarOfFuryAdjustingCostsEffect copy() {
-// return new AvatarOfFuryAdjustingCostsEffect(this);
-// }
-//}
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java b/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java
index d552596e349..4e6c3c32821 100644
--- a/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java
+++ b/Mage.Sets/src/mage/cards/a/AyliEternalPilgrim.java
@@ -45,7 +45,7 @@ public final class AyliEternalPilgrim extends CardImpl {
this.addAbility(DeathtouchAbility.getInstance());
// {1}, Sacrifice another creature: You gain life equal to the sacrificed creature's toughness.
- Effect effect = new GainLifeEffect(new SacrificeCostCreaturesToughness());
+ Effect effect = new GainLifeEffect(SacrificeCostCreaturesToughness.instance);
effect.setText("You gain life equal to the sacrificed creature's toughness");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1));
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)));
diff --git a/Mage.Sets/src/mage/cards/a/AzoriusPloy.java b/Mage.Sets/src/mage/cards/a/AzoriusPloy.java
index c7e1c996d58..0a2586584a1 100644
--- a/Mage.Sets/src/mage/cards/a/AzoriusPloy.java
+++ b/Mage.Sets/src/mage/cards/a/AzoriusPloy.java
@@ -2,14 +2,9 @@ package mage.cards.a;
import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.AbilityImpl;
-import mage.abilities.SpellAbility;
import mage.abilities.effects.Effect;
-import mage.abilities.effects.common.PreventCombatDamageBySourceEffect;
import mage.abilities.effects.common.PreventDamageByTargetEffect;
import mage.abilities.effects.common.PreventDamageToTargetEffect;
-import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -46,7 +41,7 @@ public final class AzoriusPloy extends CardImpl {
}
- public AzoriusPloy(final AzoriusPloy card) {
+ private AzoriusPloy(final AzoriusPloy card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/BalduvianConjurer.java b/Mage.Sets/src/mage/cards/b/BalduvianConjurer.java
index c9797864b59..e2a00d71490 100644
--- a/Mage.Sets/src/mage/cards/b/BalduvianConjurer.java
+++ b/Mage.Sets/src/mage/cards/b/BalduvianConjurer.java
@@ -11,8 +11,6 @@ import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.mageobject.SupertypePredicate;
-import mage.game.permanent.token.TokenImpl;
-import mage.game.permanent.token.Token;
import mage.game.permanent.token.custom.CreatureToken;
import mage.target.TargetPermanent;
@@ -43,7 +41,7 @@ public final class BalduvianConjurer extends CardImpl {
this.addAbility(ability);
}
- public BalduvianConjurer(final BalduvianConjurer card) {
+ private BalduvianConjurer(final BalduvianConjurer card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/BalduvianFallen.java b/Mage.Sets/src/mage/cards/b/BalduvianFallen.java
index 6191b9cf44a..7d8565f9974 100644
--- a/Mage.Sets/src/mage/cards/b/BalduvianFallen.java
+++ b/Mage.Sets/src/mage/cards/b/BalduvianFallen.java
@@ -3,8 +3,6 @@ package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
-import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.constants.Duration;
import mage.constants.SubType;
@@ -38,7 +36,7 @@ public final class BalduvianFallen extends CardImpl {
this.addAbility(new BalduvianFallenAbility());
}
- public BalduvianFallen(final BalduvianFallen card) {
+ private BalduvianFallen(final BalduvianFallen card) {
super(card);
}
@@ -54,7 +52,7 @@ class BalduvianFallenAbility extends TriggeredAbilityImpl {
super(Zone.BATTLEFIELD, null, false);
}
- public BalduvianFallenAbility(final BalduvianFallenAbility ability) {
+ private BalduvianFallenAbility(final BalduvianFallenAbility ability) {
super(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BalduvianFrostwaker.java b/Mage.Sets/src/mage/cards/b/BalduvianFrostwaker.java
index dfe26e4d7d8..2dfa74a2a6c 100644
--- a/Mage.Sets/src/mage/cards/b/BalduvianFrostwaker.java
+++ b/Mage.Sets/src/mage/cards/b/BalduvianFrostwaker.java
@@ -15,7 +15,6 @@ import mage.constants.*;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.game.permanent.token.TokenImpl;
-import mage.game.permanent.token.Token;
import mage.target.TargetPermanent;
/**
@@ -44,7 +43,7 @@ public final class BalduvianFrostwaker extends CardImpl {
this.addAbility(ability);
}
- public BalduvianFrostwaker(final BalduvianFrostwaker card) {
+ private BalduvianFrostwaker(final BalduvianFrostwaker card) {
super(card);
}
@@ -65,7 +64,7 @@ class BalduvianFrostwakerToken extends TokenImpl {
this.toughness = new MageInt(2);
this.addAbility(FlyingAbility.getInstance());
}
- public BalduvianFrostwakerToken(final BalduvianFrostwakerToken token) {
+ private BalduvianFrostwakerToken(final BalduvianFrostwakerToken token) {
super(token);
}
diff --git a/Mage.Sets/src/mage/cards/b/BalduvianRage.java b/Mage.Sets/src/mage/cards/b/BalduvianRage.java
index 832c748b7c4..9f3e910722f 100644
--- a/Mage.Sets/src/mage/cards/b/BalduvianRage.java
+++ b/Mage.Sets/src/mage/cards/b/BalduvianRage.java
@@ -25,7 +25,7 @@ public final class BalduvianRage extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{R}");
// Target attacking creature gets +X/+0 until end of turn.
- this.getSpellAbility().addEffect(new BoostTargetEffect(new ManacostVariableValue(), new StaticValue(0), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(ManacostVariableValue.instance, new StaticValue(0), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(new FilterAttackingCreature()));
// Draw a card at the beginning of the next turn's upkeep.
diff --git a/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java b/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java
index 4a18b913d88..7cc93560240 100644
--- a/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java
+++ b/Mage.Sets/src/mage/cards/b/BalduvianWarlord.java
@@ -51,7 +51,7 @@ public final class BalduvianWarlord extends CardImpl {
this.addAbility(ability, new BlockedByOnlyOneCreatureThisCombatWatcher());
}
- public BalduvianWarlord(final BalduvianWarlord card) {
+ private BalduvianWarlord(final BalduvianWarlord card) {
super(card);
}
@@ -69,7 +69,7 @@ class BalduvianWarlordUnblockEffect extends OneShotEffect {
this.staticText = " Remove target blocking creature from combat. Creatures it was blocking that hadn't become blocked by another creature this combat become unblocked, then it blocks an attacking creature of your choice";
}
- public BalduvianWarlordUnblockEffect(final BalduvianWarlordUnblockEffect effect) {
+ private BalduvianWarlordUnblockEffect(final BalduvianWarlordUnblockEffect effect) {
super(effect);
}
diff --git a/Mage.Sets/src/mage/cards/b/BallistaSquad.java b/Mage.Sets/src/mage/cards/b/BallistaSquad.java
index 232a7b75f18..b52ad56e1d1 100644
--- a/Mage.Sets/src/mage/cards/b/BallistaSquad.java
+++ b/Mage.Sets/src/mage/cards/b/BallistaSquad.java
@@ -30,7 +30,7 @@ public final class BallistaSquad extends CardImpl {
this.toughness = new MageInt(2);
// {X}{W}, {T}: Ballista Squad deals X damage to target attacking or blocking creature.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}{W}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{W}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetAttackingOrBlockingCreature());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java b/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java
index e37a695bc91..a68033931f4 100644
--- a/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java
+++ b/Mage.Sets/src/mage/cards/b/BaneOfTheLiving.java
@@ -32,7 +32,7 @@ public final class BaneOfTheLiving extends CardImpl {
// Morph {X}{B}{B}
this.addAbility(new MorphAbility(this, new ManaCostsImpl("{X}{B}{B}")));
// When Bane of the Living is turned face up, all creatures get -X/-X until end of turn.
- DynamicValue morphX = new SignInversionDynamicValue(new MorphManacostVariableValue());
+ DynamicValue morphX = new SignInversionDynamicValue(MorphManacostVariableValue.instance);
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new BoostAllEffect(morphX, morphX, Duration.EndOfTurn, new FilterCreaturePermanent("all creatures"), false, "", true)));
}
diff --git a/Mage.Sets/src/mage/cards/b/Banefire.java b/Mage.Sets/src/mage/cards/b/Banefire.java
index 29d3a6a2fcc..b74cddb4a94 100644
--- a/Mage.Sets/src/mage/cards/b/Banefire.java
+++ b/Mage.Sets/src/mage/cards/b/Banefire.java
@@ -106,7 +106,7 @@ class BaneFireEffect extends OneShotEffect {
class BanefireCantCounterEffect extends ContinuousRuleModifyingEffectImpl {
- Condition condition = new testCondition(new ManacostVariableValue(), 5);
+ Condition condition = new testCondition(ManacostVariableValue.instance, 5);
public BanefireCantCounterEffect() {
super(Duration.WhileOnStack, Outcome.Benefit);
diff --git a/Mage.Sets/src/mage/cards/b/Banshee.java b/Mage.Sets/src/mage/cards/b/Banshee.java
index b2392191ad1..3d0b460a5d5 100644
--- a/Mage.Sets/src/mage/cards/b/Banshee.java
+++ b/Mage.Sets/src/mage/cards/b/Banshee.java
@@ -32,9 +32,9 @@ public final class Banshee extends CardImpl {
this.toughness = new MageInt(1);
// {X}, {T}: Banshee deals half X damage, rounded down, to any target, and half X damage, rounded up, to you.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new HalfValue(new ManacostVariableValue(), false)).setText("Banshee deals half X damage, rounded down, to any target,"), new ManaCostsImpl("{X}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new HalfValue(ManacostVariableValue.instance, false)).setText("Banshee deals half X damage, rounded down, to any target,"), new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
- ability.addEffect(new DamageControllerEffect(new HalfValue(new ManacostVariableValue(), true)).setText(" and half X damage, rounded up, to you"));
+ ability.addEffect(new DamageControllerEffect(new HalfValue(ManacostVariableValue.instance, true)).setText(" and half X damage, rounded up, to you"));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BarrageTyrant.java b/Mage.Sets/src/mage/cards/b/BarrageTyrant.java
index 350f221c345..8f4b20d1274 100644
--- a/Mage.Sets/src/mage/cards/b/BarrageTyrant.java
+++ b/Mage.Sets/src/mage/cards/b/BarrageTyrant.java
@@ -45,7 +45,7 @@ public final class BarrageTyrant extends CardImpl {
this.addAbility(new DevoidAbility(this.color));
// {2}{R}, Sacrifice another colorless creature: Barrage Tyrant deals damage equal to the sacrificed creature's power to any target.
- Effect effect = new DamageTargetEffect(new SacrificeCostCreaturesPower());
+ Effect effect = new DamageTargetEffect(SacrificeCostCreaturesPower.instance);
effect.setText("{this} deals damage equal to the sacrificed creature's power to any target");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}{R}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter)));
diff --git a/Mage.Sets/src/mage/cards/b/BattleAtTheBridge.java b/Mage.Sets/src/mage/cards/b/BattleAtTheBridge.java
index b7d906149ef..6aced560b88 100644
--- a/Mage.Sets/src/mage/cards/b/BattleAtTheBridge.java
+++ b/Mage.Sets/src/mage/cards/b/BattleAtTheBridge.java
@@ -27,10 +27,10 @@ public final class BattleAtTheBridge extends CardImpl {
addAbility(new ImproviseAbility());
// Target creature gets -X/-X until end of turn. You gain X life.
- DynamicValue x = new SignInversionDynamicValue(new ManacostVariableValue());
+ DynamicValue x = new SignInversionDynamicValue(ManacostVariableValue.instance);
this.getSpellAbility().addEffect(new BoostTargetEffect(x, x, Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new GainLifeEffect(ManacostVariableValue.instance));
}
public BattleAtTheBridge(final BattleAtTheBridge card) {
diff --git a/Mage.Sets/src/mage/cards/b/BedeckBedazzle.java b/Mage.Sets/src/mage/cards/b/BedeckBedazzle.java
index 272627c8564..83c3d03a178 100644
--- a/Mage.Sets/src/mage/cards/b/BedeckBedazzle.java
+++ b/Mage.Sets/src/mage/cards/b/BedeckBedazzle.java
@@ -40,7 +40,7 @@ public final class BedeckBedazzle extends SplitCard {
// Destroy target nonbasic land. Bedazzle deals 2 damage to target opponent or planeswalker.
this.getRightHalfCard().getSpellAbility().addEffect(new BedazzleEffect());
this.getRightHalfCard().getSpellAbility().addTarget(new TargetLandPermanent());
- this.getSpellAbility().addTarget(new TargetOpponentOrPlaneswalker());
+ this.getRightHalfCard().getSpellAbility().addTarget(new TargetOpponentOrPlaneswalker());
}
private BedeckBedazzle(final BedeckBedazzle card) {
diff --git a/Mage.Sets/src/mage/cards/b/Bedlam.java b/Mage.Sets/src/mage/cards/b/Bedlam.java
index 2e76947e5a1..f305f65a97b 100644
--- a/Mage.Sets/src/mage/cards/b/Bedlam.java
+++ b/Mage.Sets/src/mage/cards/b/Bedlam.java
@@ -2,9 +2,7 @@
package mage.cards.b;
import java.util.UUID;
-import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
-import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.combat.CantBlockAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -12,8 +10,6 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.StaticFilters;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
/**
*
@@ -28,7 +24,7 @@ public final class Bedlam extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantBlockAllEffect(StaticFilters.FILTER_PERMANENT_CREATURES, Duration.WhileOnBattlefield)));
}
- public Bedlam(final Bedlam card) {
+ private Bedlam(final Bedlam card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/BelbesArmor.java b/Mage.Sets/src/mage/cards/b/BelbesArmor.java
index e1e54a3e326..d9cc57f6a26 100644
--- a/Mage.Sets/src/mage/cards/b/BelbesArmor.java
+++ b/Mage.Sets/src/mage/cards/b/BelbesArmor.java
@@ -29,8 +29,8 @@ public final class BelbesArmor extends CardImpl {
Ability ability = new SimpleActivatedAbility(
Zone.BATTLEFIELD,
new BoostTargetEffect(
- new MultipliedValue(new ManacostVariableValue(), -1),
- new ManacostVariableValue(),
+ new MultipliedValue(ManacostVariableValue.instance, -1),
+ ManacostVariableValue.instance,
Duration.EndOfTurn
),
new ManaCostsImpl("{X}"));
diff --git a/Mage.Sets/src/mage/cards/b/BendOrBreak.java b/Mage.Sets/src/mage/cards/b/BendOrBreak.java
index e7bdfa74f98..19cd360d8f9 100644
--- a/Mage.Sets/src/mage/cards/b/BendOrBreak.java
+++ b/Mage.Sets/src/mage/cards/b/BendOrBreak.java
@@ -82,7 +82,7 @@ class BendOrBreakEffect extends OneShotEffect {
Player nextPlayer;
UUID firstNextPlayer = null;
- while (!getNextPlayerInDirection(true, playerList, game).equals(firstNextPlayer) && controller.canRespond()) {
+ while (!getNextPlayerInDirection(true, playerList).equals(firstNextPlayer) && controller.canRespond()) {
nextPlayer = game.getPlayer(playerList.get());
if (nextPlayer == null) {
return false;
@@ -187,7 +187,7 @@ class BendOrBreakEffect extends OneShotEffect {
return false;
}
- private UUID getNextPlayerInDirection(boolean left, PlayerList playerList, Game game) {
+ private UUID getNextPlayerInDirection(boolean left, PlayerList playerList) {
UUID nextPlayerId;
if (left) {
nextPlayerId = playerList.getNext();
diff --git a/Mage.Sets/src/mage/cards/b/Berserk.java b/Mage.Sets/src/mage/cards/b/Berserk.java
index dc4065a0c82..d1f990e57e3 100644
--- a/Mage.Sets/src/mage/cards/b/Berserk.java
+++ b/Mage.Sets/src/mage/cards/b/Berserk.java
@@ -43,7 +43,7 @@ public final class Berserk extends CardImpl {
Effect effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
effect.setText("Target creature gains trample");
this.getSpellAbility().addEffect(effect);
- effect = new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true);
+ effect = new BoostTargetEffect(TargetPermanentPowerCount.instance, new StaticValue(0), Duration.EndOfTurn, true);
effect.setText("and gets +X/+0 until end of turn, where X is its power");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addEffect(new BerserkDestroyEffect());
diff --git a/Mage.Sets/src/mage/cards/b/BiogenicUpgrade.java b/Mage.Sets/src/mage/cards/b/BiogenicUpgrade.java
index e0f0d0b8eb7..8d0622f6e4d 100644
--- a/Mage.Sets/src/mage/cards/b/BiogenicUpgrade.java
+++ b/Mage.Sets/src/mage/cards/b/BiogenicUpgrade.java
@@ -9,10 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
-import mage.constants.TargetController;
import mage.counters.CounterType;
-import mage.filter.common.FilterCreaturePermanent;
-import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanentAmount;
@@ -25,13 +22,6 @@ import java.util.UUID;
*/
public final class BiogenicUpgrade extends CardImpl {
- private static final FilterCreaturePermanent filter
- = new FilterCreaturePermanent("creatures you control");
-
- static {
- filter.add(new ControllerPredicate(TargetController.YOU));
- }
-
public BiogenicUpgrade(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{G}");
@@ -40,7 +30,7 @@ public final class BiogenicUpgrade extends CardImpl {
CounterType.P1P1, 3, false,
"one, two, or three target creatures"
));
- this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(3, filter));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(3));
this.getSpellAbility().addEffect(new BiogenicUpgradeEffect());
}
diff --git a/Mage.Sets/src/mage/cards/b/BiomassMutation.java b/Mage.Sets/src/mage/cards/b/BiomassMutation.java
index eaf52684665..cbd6af34074 100644
--- a/Mage.Sets/src/mage/cards/b/BiomassMutation.java
+++ b/Mage.Sets/src/mage/cards/b/BiomassMutation.java
@@ -22,7 +22,7 @@ public final class BiomassMutation extends CardImpl {
// Creatures you control have base power and toughness X/X until end of turn.
- DynamicValue variableMana = new ManacostVariableValue();
+ DynamicValue variableMana = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new SetPowerToughnessAllEffect(variableMana, variableMana, Duration.EndOfTurn, new FilterControlledCreaturePermanent("Creatures you control"), true));
}
diff --git a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java
index 2423fc449b4..0aa099282e4 100644
--- a/Mage.Sets/src/mage/cards/b/BlackManaBattery.java
+++ b/Mage.Sets/src/mage/cards/b/BlackManaBattery.java
@@ -36,7 +36,7 @@ public final class BlackManaBattery extends CardImpl {
// {tap}, Remove any number of charge counters from Black Mana Battery: Add {B}, then add an additional {B} for each charge counter removed this way.
ability = new DynamicManaAbility(
Mana.BlackMana(1),
- new IntPlusDynamicValue(1, new RemovedCountersForCostValue()),
+ new IntPlusDynamicValue(1, RemovedCountersForCostValue.instance),
new TapSourceCost(),
"Add {B}, then add {B} for each charge counter removed this way",
true, new CountersSourceCount(CounterType.CHARGE));
diff --git a/Mage.Sets/src/mage/cards/b/BlastfireBolt.java b/Mage.Sets/src/mage/cards/b/BlastfireBolt.java
index b83dcb3e741..681b81191fe 100644
--- a/Mage.Sets/src/mage/cards/b/BlastfireBolt.java
+++ b/Mage.Sets/src/mage/cards/b/BlastfireBolt.java
@@ -1,22 +1,13 @@
package mage.cards.b;
-import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DestroyAllAttachedEquipmentEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Outcome;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
-import java.util.ArrayList;
-import java.util.List;
import java.util.UUID;
/**
@@ -35,7 +26,7 @@ public final class BlastfireBolt extends CardImpl {
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
- public BlastfireBolt(final BlastfireBolt card) {
+ private BlastfireBolt(final BlastfireBolt card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/Blaze.java b/Mage.Sets/src/mage/cards/b/Blaze.java
index bbeead84810..d2b4c019217 100644
--- a/Mage.Sets/src/mage/cards/b/Blaze.java
+++ b/Mage.Sets/src/mage/cards/b/Blaze.java
@@ -20,7 +20,7 @@ public final class Blaze extends CardImpl {
// Blaze deals X damage to any target.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/b/BlazingShoal.java b/Mage.Sets/src/mage/cards/b/BlazingShoal.java
index 79e19d154d5..9f6238b97e4 100644
--- a/Mage.Sets/src/mage/cards/b/BlazingShoal.java
+++ b/Mage.Sets/src/mage/cards/b/BlazingShoal.java
@@ -38,7 +38,7 @@ public final class BlazingShoal extends CardImpl {
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter),true)));
// Target creature gets +X/+0 until end of turn.
- this.getSpellAbility().addEffect(new BoostTargetEffect(new ExileFromHandCostCardConvertedMana(), new StaticValue(0), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(ExileFromHandCostCardConvertedMana.instance, new StaticValue(0), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/b/BlinkmothNexus.java b/Mage.Sets/src/mage/cards/b/BlinkmothNexus.java
index 1c9f8379517..172b43b805a 100644
--- a/Mage.Sets/src/mage/cards/b/BlinkmothNexus.java
+++ b/Mage.Sets/src/mage/cards/b/BlinkmothNexus.java
@@ -4,7 +4,6 @@ package mage.cards.b;
import java.util.UUID;
-import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
@@ -21,8 +20,6 @@ import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
-import mage.game.permanent.token.TokenImpl;
-import mage.game.permanent.token.Token;
import mage.game.permanent.token.custom.CreatureToken;
import mage.target.TargetPermanent;
@@ -59,7 +56,7 @@ public final class BlinkmothNexus extends CardImpl {
}
- public BlinkmothNexus(final BlinkmothNexus card) {
+ private BlinkmothNexus(final BlinkmothNexus card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java b/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java
index 2c5135dbebc..a05a7f28575 100644
--- a/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java
+++ b/Mage.Sets/src/mage/cards/b/BloodChinFanatic.java
@@ -42,9 +42,9 @@ public final class BloodChinFanatic extends CardImpl {
this.toughness = new MageInt(3);
// {1}{B}, Sacrifice another Warrior creature: Target player loses X life and you gain X life, where X is the sacrificed creature's power.
- Effect effect = new LoseLifeTargetEffect(new SacrificeCostCreaturesPower());
+ Effect effect = new LoseLifeTargetEffect(SacrificeCostCreaturesPower.instance);
effect.setText("Target player loses X life");
- Effect effect2 = new GainLifeEffect(new SacrificeCostCreaturesPower());
+ Effect effect2 = new GainLifeEffect(SacrificeCostCreaturesPower.instance);
effect2.setText("and you gain X life, where X is the sacrificed creature's power");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}{B}"));
ability.addEffect(effect2);
diff --git a/Mage.Sets/src/mage/cards/b/BloodSun.java b/Mage.Sets/src/mage/cards/b/BloodSun.java
index efa84ba2eb0..227b656eaf9 100644
--- a/Mage.Sets/src/mage/cards/b/BloodSun.java
+++ b/Mage.Sets/src/mage/cards/b/BloodSun.java
@@ -1,7 +1,6 @@
package mage.cards.b;
-import java.util.Iterator;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -14,7 +13,6 @@ import mage.constants.AbilityType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
-import static mage.constants.Layer.AbilityAddingRemovingEffects_6;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
@@ -39,7 +37,7 @@ public final class BloodSun extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BloodSunEffect(Duration.WhileOnBattlefield)));
}
- public BloodSun(final BloodSun card) {
+ private BloodSun(final BloodSun card) {
super(card);
}
@@ -56,7 +54,7 @@ class BloodSunEffect extends ContinuousEffectImpl {
staticText = "all lands lose all abilities except mana abilities";
}
- public BloodSunEffect(final BloodSunEffect effect) {
+ private BloodSunEffect(final BloodSunEffect effect) {
super(effect);
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodcrazedPaladin.java b/Mage.Sets/src/mage/cards/b/BloodcrazedPaladin.java
index 979494a69d5..85cfe792f6c 100644
--- a/Mage.Sets/src/mage/cards/b/BloodcrazedPaladin.java
+++ b/Mage.Sets/src/mage/cards/b/BloodcrazedPaladin.java
@@ -34,7 +34,7 @@ public final class BloodcrazedPaladin extends CardImpl {
// Bloodcrazed Paladin enters the battlefield with a +1/+1 counter on it for each creature that died this turn.
Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance(0),
- new CreaturesDiedThisTurnCount(), true);
+ CreaturesDiedThisTurnCount.instance, true);
effect.setText("with a +1/+1 counter on it for each creature that died this turn.");
this.addAbility(new EntersBattlefieldAbility(effect), new CreaturesDiedWatcher());
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodcurdlingScream.java b/Mage.Sets/src/mage/cards/b/BloodcurdlingScream.java
index 405349caa76..50d803fc36c 100644
--- a/Mage.Sets/src/mage/cards/b/BloodcurdlingScream.java
+++ b/Mage.Sets/src/mage/cards/b/BloodcurdlingScream.java
@@ -21,7 +21,7 @@ public final class BloodcurdlingScream extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B}");
// Target creature gets +X/+0 until end of turn.
- this.getSpellAbility().addEffect(new BoostTargetEffect(new ExileFromHandCostCardConvertedMana(), new StaticValue(0), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(ExileFromHandCostCardConvertedMana.instance, new StaticValue(0), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodhuskRitualist.java b/Mage.Sets/src/mage/cards/b/BloodhuskRitualist.java
index 4fb929dd9f9..d3cc620816a 100644
--- a/Mage.Sets/src/mage/cards/b/BloodhuskRitualist.java
+++ b/Mage.Sets/src/mage/cards/b/BloodhuskRitualist.java
@@ -32,7 +32,7 @@ public final class BloodhuskRitualist extends CardImpl {
this.addAbility(new MultikickerAbility("{B}"));
// When Bloodhusk Ritualist enters the battlefield, target opponent discards a card for each time it was kicked.
- Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(new MultikickerCount()));
+ Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardTargetEffect(MultikickerCount.instance));
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/b/BloodshotCyclops.java b/Mage.Sets/src/mage/cards/b/BloodshotCyclops.java
index 80aa19dbbb8..7cbe947de4d 100644
--- a/Mage.Sets/src/mage/cards/b/BloodshotCyclops.java
+++ b/Mage.Sets/src/mage/cards/b/BloodshotCyclops.java
@@ -33,7 +33,7 @@ public final class BloodshotCyclops extends CardImpl {
// {T}, Sacrifice a creature: Bloodshot Cyclops deals damage equal to the sacrificed
// creature's power to any target.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new DamageTargetEffect(new SacrificeCostCreaturesPower()),
+ new DamageTargetEffect(SacrificeCostCreaturesPower.instance),
new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
ability.addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/b/BloodtallowCandle.java b/Mage.Sets/src/mage/cards/b/BloodtallowCandle.java
index fe875013e25..5cc30915a8f 100644
--- a/Mage.Sets/src/mage/cards/b/BloodtallowCandle.java
+++ b/Mage.Sets/src/mage/cards/b/BloodtallowCandle.java
@@ -6,13 +6,9 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
-import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.filter.StaticFilters;
-import mage.target.common.TargetCardInLibrary;
import java.util.UUID;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
@@ -39,7 +35,7 @@ public final class BloodtallowCandle extends CardImpl {
this.addAbility(ability);
}
- public BloodtallowCandle(final BloodtallowCandle card) {
+ private BloodtallowCandle(final BloodtallowCandle card) {
super(card);
}
diff --git a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java
index 9283e18893c..05ad3bfc873 100644
--- a/Mage.Sets/src/mage/cards/b/BlueManaBattery.java
+++ b/Mage.Sets/src/mage/cards/b/BlueManaBattery.java
@@ -36,7 +36,7 @@ public final class BlueManaBattery extends CardImpl {
// {tap}, Remove any number of charge counters from Blue Mana Battery: Add {U}, then add an additional {U} for each charge counter removed this way.
ability = new DynamicManaAbility(
Mana.BlueMana(1),
- new IntPlusDynamicValue(1, new RemovedCountersForCostValue()),
+ new IntPlusDynamicValue(1, RemovedCountersForCostValue.instance),
new TapSourceCost(),
"Add {U}, then add {U} for each charge counter removed this way",
true, new CountersSourceCount(CounterType.CHARGE));
diff --git a/Mage.Sets/src/mage/cards/b/BlueSunsZenith.java b/Mage.Sets/src/mage/cards/b/BlueSunsZenith.java
index 72d74af31fb..2e94941db50 100644
--- a/Mage.Sets/src/mage/cards/b/BlueSunsZenith.java
+++ b/Mage.Sets/src/mage/cards/b/BlueSunsZenith.java
@@ -21,7 +21,7 @@ public final class BlueSunsZenith extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}{U}{U}");
// Target player draws X cards. Shuffle Blue Sun's Zenith into its owner's library.
- this.getSpellAbility().addEffect(new DrawCardTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addEffect(ShuffleSpellEffect.getInstance());
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/b/BondOfAgony.java b/Mage.Sets/src/mage/cards/b/BondOfAgony.java
index 761c1ad9886..a6da60f30ec 100644
--- a/Mage.Sets/src/mage/cards/b/BondOfAgony.java
+++ b/Mage.Sets/src/mage/cards/b/BondOfAgony.java
@@ -18,7 +18,7 @@ public final class BondOfAgony extends CardImpl {
public BondOfAgony(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B}");
- DynamicValue xValue = new ManacostVariableValue();
+ DynamicValue xValue = ManacostVariableValue.instance;
// As an additional cost to cast Bond of Agony, pay X life.
// magenoxx: here we don't use PayVariableLifeCost as {X} shouldn't actually be announced
diff --git a/Mage.Sets/src/mage/cards/b/BorrowingTheEastWind.java b/Mage.Sets/src/mage/cards/b/BorrowingTheEastWind.java
index 9d5ab407c52..53f13e39bef 100644
--- a/Mage.Sets/src/mage/cards/b/BorrowingTheEastWind.java
+++ b/Mage.Sets/src/mage/cards/b/BorrowingTheEastWind.java
@@ -27,7 +27,7 @@ public final class BorrowingTheEastWind extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{G}{G}");
// Borrowing the East Wind deals X damage to each creature with horsemanship and each player.
- this.getSpellAbility().addEffect(new DamageEverythingEffect(new ManacostVariableValue(), filter)); }
+ this.getSpellAbility().addEffect(new DamageEverythingEffect(ManacostVariableValue.instance, filter)); }
public BorrowingTheEastWind(final BorrowingTheEastWind card) {
super(card);
diff --git a/Mage.Sets/src/mage/cards/b/BottleOfSuleiman.java b/Mage.Sets/src/mage/cards/b/BottleOfSuleiman.java
index efc5271eff4..9d82fd071f8 100644
--- a/Mage.Sets/src/mage/cards/b/BottleOfSuleiman.java
+++ b/Mage.Sets/src/mage/cards/b/BottleOfSuleiman.java
@@ -61,7 +61,7 @@ class BottleOfSuleimanEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
- if (you.flipCoin(game)) {
+ if (you.flipCoin(source, game, true)) {
DjinnToken token = new DjinnToken();
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
return true;
diff --git a/Mage.Sets/src/mage/cards/b/BottomlessVault.java b/Mage.Sets/src/mage/cards/b/BottomlessVault.java
index 8bd5f7fa137..caad3bf15cd 100644
--- a/Mage.Sets/src/mage/cards/b/BottomlessVault.java
+++ b/Mage.Sets/src/mage/cards/b/BottomlessVault.java
@@ -44,7 +44,7 @@ public final class BottomlessVault extends CardImpl {
// {tap}, Remove any number of storage counters from Bottomless Vault: Add {B} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.BlackMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {B} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/b/BrainInAJar.java b/Mage.Sets/src/mage/cards/b/BrainInAJar.java
index 161a5c9fcc3..78969941889 100644
--- a/Mage.Sets/src/mage/cards/b/BrainInAJar.java
+++ b/Mage.Sets/src/mage/cards/b/BrainInAJar.java
@@ -118,7 +118,7 @@ class BrainInAJarScryEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- int x = new RemovedCountersForCostValue().calculate(game, source, this);
+ int x = RemovedCountersForCostValue.instance.calculate(game, source, this);
if (x > 0) {
return controller.scry(x, source, game);
}
diff --git a/Mage.Sets/src/mage/cards/b/Braingeyser.java b/Mage.Sets/src/mage/cards/b/Braingeyser.java
index f3bd4083b03..75dad9a4f61 100644
--- a/Mage.Sets/src/mage/cards/b/Braingeyser.java
+++ b/Mage.Sets/src/mage/cards/b/Braingeyser.java
@@ -21,7 +21,7 @@ public final class Braingeyser extends CardImpl {
// Target player draws X cards.
- this.getSpellAbility().addEffect(new DrawCardTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/b/Brightflame.java b/Mage.Sets/src/mage/cards/b/Brightflame.java
index 8e70b4a364b..54f8ab2edf0 100644
--- a/Mage.Sets/src/mage/cards/b/Brightflame.java
+++ b/Mage.Sets/src/mage/cards/b/Brightflame.java
@@ -29,7 +29,7 @@ public final class Brightflame extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}{R}{W}{W}");
// Radiance - Brightflame deals X damage to target creature and each other creature that shares a color with it. You gain life equal to the damage dealt this way.
- this.getSpellAbility().addEffect(new BrightflameEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new BrightflameEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().setAbilityWord(AbilityWord.RADIANCE);
}
diff --git a/Mage.Sets/src/mage/cards/b/BrokenAmbitions.java b/Mage.Sets/src/mage/cards/b/BrokenAmbitions.java
index 484e49a2109..b9d4be4d1a3 100644
--- a/Mage.Sets/src/mage/cards/b/BrokenAmbitions.java
+++ b/Mage.Sets/src/mage/cards/b/BrokenAmbitions.java
@@ -30,7 +30,7 @@ public final class BrokenAmbitions extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}");
// Counter target spell unless its controller pays {X}. Clash with an opponent. If you win, that spell's controller puts the top four cards of their library into their graveyard.
- this.getSpellAbility().addEffect(new BrokenAmbitionsEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new BrokenAmbitionsEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetSpell());
}
diff --git a/Mage.Sets/src/mage/cards/b/BurnAtTheStake.java b/Mage.Sets/src/mage/cards/b/BurnAtTheStake.java
index 7931708785d..7707490f2de 100644
--- a/Mage.Sets/src/mage/cards/b/BurnAtTheStake.java
+++ b/Mage.Sets/src/mage/cards/b/BurnAtTheStake.java
@@ -69,7 +69,7 @@ class BurnAtTheStakeEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- int amount = (new GetXValue()).calculate(game, source, this) * 3;
+ int amount = (GetXValue.instance).calculate(game, source, this) * 3;
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) {
diff --git a/Mage.Sets/src/mage/cards/c/CabalInterrogator.java b/Mage.Sets/src/mage/cards/c/CabalInterrogator.java
index 7e8862fdb93..4fd7e496e3d 100644
--- a/Mage.Sets/src/mage/cards/c/CabalInterrogator.java
+++ b/Mage.Sets/src/mage/cards/c/CabalInterrogator.java
@@ -78,7 +78,7 @@ class CabalInterrogatorEffect extends OneShotEffect {
return false;
}
- int amountToReveal = (new ManacostVariableValue()).calculate(game, source, this);
+ int amountToReveal = (ManacostVariableValue.instance).calculate(game, source, this);
Cards revealedCards = new CardsImpl();
if (amountToReveal > 0 && targetPlayer.getHand().size() > amountToReveal) {
diff --git a/Mage.Sets/src/mage/cards/c/CacklingWitch.java b/Mage.Sets/src/mage/cards/c/CacklingWitch.java
index ec76eecd38d..37f93e1542a 100644
--- a/Mage.Sets/src/mage/cards/c/CacklingWitch.java
+++ b/Mage.Sets/src/mage/cards/c/CacklingWitch.java
@@ -33,7 +33,7 @@ public final class CacklingWitch extends CardImpl {
this.toughness = new MageInt(1);
// {X}{B}, {tap}, Discard a card: Target creature gets +X/+0 until end of turn.
- ManacostVariableValue manaX = new ManacostVariableValue();
+ ManacostVariableValue manaX = ManacostVariableValue.instance;
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new BoostTargetEffect(manaX, new StaticValue(0), Duration.EndOfTurn),
new ManaCostsImpl("{X}{B}"));
diff --git a/Mage.Sets/src/mage/cards/c/CalciformPools.java b/Mage.Sets/src/mage/cards/c/CalciformPools.java
index 72702e77fde..9d123691915 100644
--- a/Mage.Sets/src/mage/cards/c/CalciformPools.java
+++ b/Mage.Sets/src/mage/cards/c/CalciformPools.java
@@ -36,7 +36,7 @@ public final class CalciformPools extends CardImpl {
this.addAbility(ability);
// {1}, Remove X storage counters from Calciform Pools: Add X mana in any combination of {W} and/or {U}.
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
- new AddManaInAnyCombinationEffect(new RemovedCountersForCostValue(), ColoredManaSymbol.W, ColoredManaSymbol.U),
+ new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.W, ColoredManaSymbol.U),
new GenericManaCost(1));
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/c/CaptiveAudience.java b/Mage.Sets/src/mage/cards/c/CaptiveAudience.java
index 53a38a2dec6..342849027dc 100644
--- a/Mage.Sets/src/mage/cards/c/CaptiveAudience.java
+++ b/Mage.Sets/src/mage/cards/c/CaptiveAudience.java
@@ -41,7 +41,9 @@ public final class CaptiveAudience extends CardImpl {
// At the beginning of your upkeep, choose one that hasn't been chosen —
// • Your life total becomes 4.
- Ability ability = new BeginningOfUpkeepTriggeredAbility(new SetPlayerLifeSourceEffect(4), TargetController.YOU, false);
+ Ability ability = new BeginningOfUpkeepTriggeredAbility(
+ new SetPlayerLifeSourceEffect(4), TargetController.YOU, false
+ );
ability.getModes().setEachModeOnlyOnce(true);
// • Discard your hand.
@@ -96,9 +98,9 @@ class CaptiveAudienceETBEffect extends OneShotEffect {
ContinuousEffect continuousEffect = new GainControlTargetEffect(
Duration.WhileOnBattlefield, true, player.getId()
);
- continuousEffect.setTargetPointer(
- new FixedTarget(source.getSourceId(), source.getSourceObjectZoneChangeCounter() + 1)
- );
+ continuousEffect.setTargetPointer(new FixedTarget(
+ source.getSourceId(), source.getSourceObjectZoneChangeCounter()
+ ));
game.addEffect(continuousEffect, source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/c/Carrion.java b/Mage.Sets/src/mage/cards/c/Carrion.java
index 335d1c595a4..befed330ea5 100644
--- a/Mage.Sets/src/mage/cards/c/Carrion.java
+++ b/Mage.Sets/src/mage/cards/c/Carrion.java
@@ -25,7 +25,7 @@ public final class Carrion extends CardImpl {
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
// Put X 0/1 black Insect creature tokens onto the battlefield, where X is the sacrificed creature's power.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new CarrionBlackInsectToken(), new SacrificeCostCreaturesPower()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new CarrionBlackInsectToken(), SacrificeCostCreaturesPower.instance));
}
public Carrion(final Carrion card) {
diff --git a/Mage.Sets/src/mage/cards/c/CavalcadeOfCalamity.java b/Mage.Sets/src/mage/cards/c/CavalcadeOfCalamity.java
index eabf9118a8d..7c7f863bad6 100644
--- a/Mage.Sets/src/mage/cards/c/CavalcadeOfCalamity.java
+++ b/Mage.Sets/src/mage/cards/c/CavalcadeOfCalamity.java
@@ -65,7 +65,7 @@ class CavalcadeOfCalamityEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
return game.damagePlayerOrPlaneswalker(
- game.getCombat().getDefenderId(source.getFirstTarget()), 1,
+ game.getCombat().getDefenderId(targetPointer.getFirst(game, source)), 1,
source.getSourceId(), game, false, true
) > 0;
}
diff --git a/Mage.Sets/src/mage/cards/c/ChamberSentry.java b/Mage.Sets/src/mage/cards/c/ChamberSentry.java
index 60c11825020..7e8969db2a5 100644
--- a/Mage.Sets/src/mage/cards/c/ChamberSentry.java
+++ b/Mage.Sets/src/mage/cards/c/ChamberSentry.java
@@ -44,7 +44,7 @@ public final class ChamberSentry extends CardImpl {
"with a +1/+1 counter on it for each color of mana spent to cast it"));
// {X}, {T}, Remove X +1/+1 counters from Chamber Sentry: It deals X damage to any target.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue())
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance)
.setText("It deals X damage to any target"),
new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java b/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java
index 53634931b27..f8e27453659 100644
--- a/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java
+++ b/Mage.Sets/src/mage/cards/c/ChampionOfStraySouls.java
@@ -82,7 +82,7 @@ enum ChampionOfStraySoulsAdjuster implements TargetAdjuster {
public void adjustTargets(Ability ability, Game game) {
for (Effect effect : ability.getEffects()) {
if (effect instanceof ReturnFromGraveyardToBattlefieldTargetEffect) {
- int xValue = new GetXValue().calculate(game, ability, null);
+ int xValue = GetXValue.instance.calculate(game, ability, null);
ability.getTargets().clear();
ability.addTarget(new TargetCardInYourGraveyard(xValue, xValue, new FilterCreatureCard("creature cards from your graveyard")));
}
diff --git a/Mage.Sets/src/mage/cards/c/ChanceEncounter.java b/Mage.Sets/src/mage/cards/c/ChanceEncounter.java
index 84d4fbbac84..20801608a89 100644
--- a/Mage.Sets/src/mage/cards/c/ChanceEncounter.java
+++ b/Mage.Sets/src/mage/cards/c/ChanceEncounter.java
@@ -1,7 +1,6 @@
package mage.cards.c;
-import java.util.UUID;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
@@ -16,27 +15,29 @@ import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
+import mage.game.events.CoinFlippedEvent;
import mage.game.events.GameEvent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class ChanceEncounter extends CardImpl {
public ChanceEncounter(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}{R}");
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}");
// Whenever you win a coin flip, put a luck counter on Chance Encounter.
this.addAbility(new ChanceEncounterTriggeredAbility());
-
+
// At the beginning of your upkeep, if Chance Encounter has ten or more luck counters on it, you win the game.
- TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new WinGameSourceControllerEffect(), TargetController.YOU, false);
+ TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new WinGameSourceControllerEffect(), TargetController.YOU, false);
this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, new SourceHasCounterCondition(CounterType.LUCK, 10, Integer.MAX_VALUE),
"At the beginning of your upkeep, if {this} has ten or more luck counters on it, you win the game"));
}
- public ChanceEncounter(final ChanceEncounter card) {
+ private ChanceEncounter(final ChanceEncounter card) {
super(card);
}
@@ -47,30 +48,33 @@ public final class ChanceEncounter extends CardImpl {
}
class ChanceEncounterTriggeredAbility extends TriggeredAbilityImpl {
-
- public ChanceEncounterTriggeredAbility() {
+
+ ChanceEncounterTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.LUCK.createInstance()), false);
}
-
- public ChanceEncounterTriggeredAbility(final ChanceEncounterTriggeredAbility ability) {
+
+ private ChanceEncounterTriggeredAbility(final ChanceEncounterTriggeredAbility ability) {
super(ability);
}
-
+
@Override
public ChanceEncounterTriggeredAbility copy() {
return new ChanceEncounterTriggeredAbility(this);
}
-
+
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.COIN_FLIPPED;
}
-
+
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- return this.isControlledBy(event.getPlayerId()) && event.getFlag();
+ CoinFlippedEvent flipEvent = (CoinFlippedEvent) event;
+ return flipEvent.getPlayerId().equals(controllerId)
+ && flipEvent.isWinnable()
+ && (flipEvent.getChosen() == flipEvent.getResult());
}
-
+
@Override
public String getRule() {
return "Whenever you win a coin flip, " + super.getRule();
diff --git a/Mage.Sets/src/mage/cards/c/ChaosLord.java b/Mage.Sets/src/mage/cards/c/ChaosLord.java
new file mode 100644
index 00000000000..b7f2cca6ba3
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/ChaosLord.java
@@ -0,0 +1,163 @@
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.condition.common.ControlsPermanentsComparedToOpponentsCondition;
+import mage.abilities.effects.AsThoughEffectImpl;
+import mage.abilities.effects.ContinuousEffectImpl;
+import mage.constants.SubType;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.AsThoughEffectType;
+import mage.constants.CardType;
+import mage.constants.ComparisonType;
+import mage.constants.Duration;
+import mage.constants.Layer;
+import mage.constants.Outcome;
+import mage.constants.SubLayer;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.filter.FilterPermanent;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetOpponent;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public final class ChaosLord extends CardImpl {
+
+ public ChaosLord(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}{R}");
+
+ this.subtype.add(SubType.HUMAN);
+ this.power = new MageInt(7);
+ this.toughness = new MageInt(7);
+
+ // First strike
+ this.addAbility(FirstStrikeAbility.getInstance());
+
+ // At the beginning of your upkeep, target opponent gains control of Chaos Lord if the number of permanents is even.
+ Ability ability = new ChaosLordTriggeredAbility();
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+
+ // Chaos Lord can attack as though it had haste unless it entered the battlefield this turn.
+ this.addAbility(new SimpleStaticAbility(
+ Zone.BATTLEFIELD,
+ new ChaosLordEffect()));
+
+ }
+
+ private ChaosLord(final ChaosLord card) {
+ super(card);
+ }
+
+ @Override
+ public ChaosLord copy() {
+ return new ChaosLord(this);
+ }
+}
+
+class ChaosLordTriggeredAbility extends BeginningOfUpkeepTriggeredAbility {
+
+ public ChaosLordTriggeredAbility() {
+ super(Zone.BATTLEFIELD,
+ new GainControlSourceEffect(),
+ TargetController.YOU,
+ false);
+ }
+
+ public ChaosLordTriggeredAbility(ChaosLordTriggeredAbility ability) {
+ super(ability);
+ }
+
+ @Override
+ public BeginningOfUpkeepTriggeredAbility copy() {
+ return new ChaosLordTriggeredAbility(this);
+ }
+
+ @Override
+ public boolean checkInterveningIfClause(Game game) {
+ Condition condition = new ControlsPermanentsComparedToOpponentsCondition(
+ ComparisonType.EQUAL_TO,
+ new FilterPermanent());
+ Player controller = game.getPlayer(controllerId);
+ if (controller != null
+ && condition.apply(game, this)) {
+ return super.checkInterveningIfClause(game);
+ }
+ return false;
+ }
+
+ @Override
+ public String getRule() {
+ return "At the beginning of your upkeep, target opponent gains control of {this} if the number of permanents is even.";
+ }
+
+}
+
+class GainControlSourceEffect extends ContinuousEffectImpl {
+
+ public GainControlSourceEffect() {
+ super(Duration.Custom, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
+ staticText = "target opponent gains control of {this}";
+ }
+
+ public GainControlSourceEffect(final GainControlSourceEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public GainControlSourceEffect copy() {
+ return new GainControlSourceEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game);
+ if (permanent != null) {
+ return permanent.changeControllerId(source.getFirstTarget(), game);
+ } else {
+ discard();
+ }
+ return false;
+ }
+}
+
+class ChaosLordEffect extends AsThoughEffectImpl {
+
+ public ChaosLordEffect() {
+ super(AsThoughEffectType.ATTACK_AS_HASTE, Duration.WhileOnBattlefield, Outcome.Benefit);
+ staticText = "Chaos Lord can attack as though it had haste unless it entered the battlefield this turn";
+ }
+
+ public ChaosLordEffect(final ChaosLordEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ return true;
+ }
+
+ @Override
+ public ChaosLordEffect copy() {
+ return new ChaosLordEffect(this);
+ }
+
+ @Override
+ public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
+ Permanent chaosLord = game.getPermanent(objectId);
+ return chaosLord != null
+ && objectId == source.getSourceId()
+ && chaosLord.getTurnsOnBattlefield() > 0;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/ChaoticGoo.java b/Mage.Sets/src/mage/cards/c/ChaoticGoo.java
index 9e80008f076..d66c6778fea 100644
--- a/Mage.Sets/src/mage/cards/c/ChaoticGoo.java
+++ b/Mage.Sets/src/mage/cards/c/ChaoticGoo.java
@@ -67,7 +67,7 @@ class ChaoticGooEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
game.informPlayers("Chaotic Goo: Won flip. Put a +1/+1 counter on Chaotic Goo.");
new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)).apply(game, source);
return true;
diff --git a/Mage.Sets/src/mage/cards/c/ChaoticStrike.java b/Mage.Sets/src/mage/cards/c/ChaoticStrike.java
index 49424f17232..2c97e2a4150 100644
--- a/Mage.Sets/src/mage/cards/c/ChaoticStrike.java
+++ b/Mage.Sets/src/mage/cards/c/ChaoticStrike.java
@@ -65,7 +65,7 @@ class ChaoticStrikeEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
game.addEffect(new BoostTargetEffect(1, 1, Duration.EndOfTurn), source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/c/ChillHaunting.java b/Mage.Sets/src/mage/cards/c/ChillHaunting.java
index 2730c08155f..d13c2420f26 100644
--- a/Mage.Sets/src/mage/cards/c/ChillHaunting.java
+++ b/Mage.Sets/src/mage/cards/c/ChillHaunting.java
@@ -28,7 +28,7 @@ public final class ChillHaunting extends CardImpl {
// Target creature gets -X/-X until end of turn.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- DynamicValue xval = new SignInversionDynamicValue(new GetXValue());
+ DynamicValue xval = new SignInversionDynamicValue(GetXValue.instance);
this.getSpellAbility().addEffect(new BoostTargetEffect(xval, xval, Duration.EndOfTurn));
}
diff --git a/Mage.Sets/src/mage/cards/c/CinderElemental.java b/Mage.Sets/src/mage/cards/c/CinderElemental.java
index 8adeae708e2..16a0dfcae52 100644
--- a/Mage.Sets/src/mage/cards/c/CinderElemental.java
+++ b/Mage.Sets/src/mage/cards/c/CinderElemental.java
@@ -31,7 +31,7 @@ public final class CinderElemental extends CardImpl {
this.toughness = new MageInt(2);
// {X}{R}, {tap}, Sacrifice Cinder Elemental: Cinder Elemental deals X damage to any target.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}{R}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{R}"));
ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/c/ClanDefiance.java b/Mage.Sets/src/mage/cards/c/ClanDefiance.java
index 49d307e93ed..7400b1fb4f7 100644
--- a/Mage.Sets/src/mage/cards/c/ClanDefiance.java
+++ b/Mage.Sets/src/mage/cards/c/ClanDefiance.java
@@ -36,16 +36,16 @@ public final class ClanDefiance extends CardImpl {
this.getSpellAbility().getModes().setMinModes(1);
this.getSpellAbility().getModes().setMaxModes(3);
// Clan Defiance deals X damage to target creature with flying;
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
// Clan Defiance deals X damage to target creature without flying;
Mode mode1 = new Mode();
- mode1.addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ mode1.addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
mode1.addTarget(new TargetCreaturePermanent(filter2));
this.getSpellAbility().addMode(mode1);
// and/or Clan Defiance deals X damage to target player.
Mode mode2 = new Mode();
- mode2.addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ mode2.addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
mode2.addTarget(new TargetPlayerOrPlaneswalker());
this.getSpellAbility().addMode(mode2);
diff --git a/Mage.Sets/src/mage/cards/c/ClashOfWills.java b/Mage.Sets/src/mage/cards/c/ClashOfWills.java
index 0108bc26916..a16fe93da3d 100644
--- a/Mage.Sets/src/mage/cards/c/ClashOfWills.java
+++ b/Mage.Sets/src/mage/cards/c/ClashOfWills.java
@@ -19,7 +19,7 @@ public final class ClashOfWills extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{U}");
// Counter target spell unless its controller pays {X}.
- this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetSpell());
}
diff --git a/Mage.Sets/src/mage/cards/c/ClearTheLand.java b/Mage.Sets/src/mage/cards/c/ClearTheLand.java
index abb2b345579..5f1a55058a8 100644
--- a/Mage.Sets/src/mage/cards/c/ClearTheLand.java
+++ b/Mage.Sets/src/mage/cards/c/ClearTheLand.java
@@ -25,7 +25,7 @@ public final class ClearTheLand extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{G}");
- // Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest.
+ // Each player reveals the top five cards of their library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest.
getSpellAbility().addEffect(new ClearTheLandEffect());
}
@@ -43,7 +43,7 @@ class ClearTheLandEffect extends OneShotEffect {
public ClearTheLandEffect() {
super(Outcome.Benefit);
- this.staticText = "Each player reveals the top five cards of his or her library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest.";
+ this.staticText = "Each player reveals the top five cards of their library, puts all land cards revealed this way onto the battlefield tapped, and exiles the rest.";
}
public ClearTheLandEffect(final ClearTheLandEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/ClearTheMind.java b/Mage.Sets/src/mage/cards/c/ClearTheMind.java
index 878ceb162ee..b92b0ae932a 100644
--- a/Mage.Sets/src/mage/cards/c/ClearTheMind.java
+++ b/Mage.Sets/src/mage/cards/c/ClearTheMind.java
@@ -58,7 +58,7 @@ class ClearTheMindEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getControllerId());
+ Player player = game.getPlayer(source.getFirstTarget());
if (player == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/ClearTheStage.java b/Mage.Sets/src/mage/cards/c/ClearTheStage.java
index 6f49a7091d0..fd5266eddff 100644
--- a/Mage.Sets/src/mage/cards/c/ClearTheStage.java
+++ b/Mage.Sets/src/mage/cards/c/ClearTheStage.java
@@ -68,7 +68,7 @@ class ClearTheStageEffect extends OneShotEffect {
if (!FerociousCondition.instance.apply(game, source)) {
return true;
}
- Player player = game.getPlayer(source.getSourceId());
+ Player player = game.getPlayer(source.getControllerId());
if (player == null || !player.chooseUse(Outcome.Benefit, "Return a creature card from your graveyard to your hand?", source, game)) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/c/ClockworkAvian.java b/Mage.Sets/src/mage/cards/c/ClockworkAvian.java
index 7eabddb97fa..696fca568a1 100644
--- a/Mage.Sets/src/mage/cards/c/ClockworkAvian.java
+++ b/Mage.Sets/src/mage/cards/c/ClockworkAvian.java
@@ -63,7 +63,7 @@ public final class ClockworkAvian extends CardImpl {
Zone.BATTLEFIELD,
new AvianAddCountersSourceEffect(
CounterType.P1P0.createInstance(),
- new ManacostVariableValue(),
+ ManacostVariableValue.instance,
true, true
),
new ManaCostsImpl("{X}"),
diff --git a/Mage.Sets/src/mage/cards/c/ClockworkBeast.java b/Mage.Sets/src/mage/cards/c/ClockworkBeast.java
index e02f4434b43..9fa1356e13e 100644
--- a/Mage.Sets/src/mage/cards/c/ClockworkBeast.java
+++ b/Mage.Sets/src/mage/cards/c/ClockworkBeast.java
@@ -59,7 +59,7 @@ public final class ClockworkBeast extends CardImpl {
Zone.BATTLEFIELD,
new BeastAddCountersSourceEffect(
CounterType.P1P0.createInstance(),
- new ManacostVariableValue(),
+ ManacostVariableValue.instance,
true, true
),
new ManaCostsImpl("{X}"),
diff --git a/Mage.Sets/src/mage/cards/c/ClockworkSteed.java b/Mage.Sets/src/mage/cards/c/ClockworkSteed.java
index fe4557ef8dd..c2975f53d2c 100644
--- a/Mage.Sets/src/mage/cards/c/ClockworkSteed.java
+++ b/Mage.Sets/src/mage/cards/c/ClockworkSteed.java
@@ -70,7 +70,7 @@ public final class ClockworkSteed extends CardImpl {
Zone.BATTLEFIELD,
new ClockworkSteedAddCountersSourceEffect(
CounterType.P1P0.createInstance(),
- new ManacostVariableValue(),
+ ManacostVariableValue.instance,
true, true
),
new ManaCostsImpl("{X}"),
diff --git a/Mage.Sets/src/mage/cards/c/ClockworkSwarm.java b/Mage.Sets/src/mage/cards/c/ClockworkSwarm.java
index 4480d844ced..0cd0288d2e2 100644
--- a/Mage.Sets/src/mage/cards/c/ClockworkSwarm.java
+++ b/Mage.Sets/src/mage/cards/c/ClockworkSwarm.java
@@ -73,7 +73,7 @@ public final class ClockworkSwarm extends CardImpl {
Zone.BATTLEFIELD,
new SwarmAddCountersSourceEffect(
CounterType.P1P0.createInstance(),
- new ManacostVariableValue(),
+ ManacostVariableValue.instance,
true, true
),
new ManaCostsImpl("{X}"),
diff --git a/Mage.Sets/src/mage/cards/c/Cocoon.java b/Mage.Sets/src/mage/cards/c/Cocoon.java
new file mode 100644
index 00000000000..ce5d8be5c5f
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/c/Cocoon.java
@@ -0,0 +1,115 @@
+
+package mage.cards.c;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldTriggeredAbility;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.condition.common.SourceHasCounterCondition;
+import mage.abilities.decorator.ConditionalContinuousRuleModifyingEffect;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.DontUntapInControllersUntapStepEnchantedEffect;
+import mage.abilities.effects.common.TapEnchantedEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.effects.common.counter.AddCountersTargetEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetControlledCreaturePermanent;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ * @author L_J
+ */
+public final class Cocoon extends CardImpl {
+
+ public Cocoon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{G}");
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature you control
+ TargetPermanent auraTarget = new TargetControlledCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
+ this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
+
+ // When Cocoon enters the battlefield, tap enchanted creature and put three pupa counters on Cocoon.
+ Ability ability = new EntersBattlefieldTriggeredAbility(new TapEnchantedEffect());
+ ability.addEffect(new AddCountersSourceEffect(CounterType.PUPA.createInstance(3)));
+ this.addAbility(ability);
+
+ // Enchanted creature doesn’t untap during your untap step if Cocoon has a pupa counter on it.
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousRuleModifyingEffect(new DontUntapInControllersUntapStepEnchantedEffect(),
+ new SourceHasCounterCondition(CounterType.PUPA)).setText("Enchanted creature doesn't untap during its controller's untap step if Cocoon has a pupa counter on it")));
+
+ // At the beginning of your upkeep, remove a pupa counter from Cocoon. If you can’t, sacrifice it, put a +1/+1 counter on enchanted creature, and that creature gains flying.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CocoonEffect(), TargetController.YOU, false));
+
+ }
+
+ public Cocoon(final Cocoon card) {
+ super(card);
+ }
+
+ @Override
+ public Cocoon copy() {
+ return new Cocoon(this);
+ }
+}
+
+class CocoonEffect extends OneShotEffect {
+
+ CocoonEffect() {
+ super(Outcome.Sacrifice);
+ staticText = "remove a pupa counter from {this}. If you can’t, sacrifice it, put a +1/+1 counter on enchanted creature, and that creature gains flying";
+ }
+
+ CocoonEffect(final CocoonEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (permanent != null) {
+ int amount = permanent.getCounters(game).getCount(CounterType.PUPA);
+ if (amount > 0) {
+ permanent.removeCounters(CounterType.PUPA.createInstance(), game);
+ } else {
+ Permanent enchantedPermanent = game.getPermanent(permanent.getAttachedTo());
+ permanent.sacrifice(source.getSourceId(), game);
+ if (enchantedPermanent != null) {
+ Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance());
+ effect.setTargetPointer(new FixedTarget(enchantedPermanent, game));
+ effect.apply(game, source);
+ ContinuousEffect effect2 = new GainAbilityTargetEffect(FlyingAbility.getInstance(), Duration.Custom);
+ effect2.setTargetPointer(new FixedTarget(enchantedPermanent, game));
+ game.addEffect(effect2, source);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public CocoonEffect copy() {
+ return new CocoonEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/c/CodeOfConstraint.java b/Mage.Sets/src/mage/cards/c/CodeOfConstraint.java
index 95330ab9a3b..f548ade2784 100644
--- a/Mage.Sets/src/mage/cards/c/CodeOfConstraint.java
+++ b/Mage.Sets/src/mage/cards/c/CodeOfConstraint.java
@@ -1,15 +1,17 @@
package mage.cards.c;
+import mage.abilities.Ability;
import mage.abilities.condition.common.AddendumCondition;
-import mage.abilities.decorator.ConditionalContinuousEffect;
-import mage.abilities.decorator.ConditionalOneShotEffect;
-import mage.abilities.effects.common.DontUntapInControllersNextUntapStepSourceEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.game.Game;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@@ -30,16 +32,7 @@ public final class CodeOfConstraint extends CardImpl {
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
// Addendum — If you cast this spell during your main phase, tap that creature and it doesn't untap during its controller's next untap step.
- this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new TapTargetEffect(), AddendumCondition.instance,
- "
Addendum — If you cast this spell " +
- "during your main phase, tap that creature"
- ));
- this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
- new DontUntapInControllersNextUntapStepSourceEffect(),
- AddendumCondition.instance, "and it doesn't untap " +
- "during its controller's next untap step."
- ));
+ this.getSpellAbility().addEffect(new CodeOfConstraintEffect());
}
private CodeOfConstraint(final CodeOfConstraint card) {
@@ -51,3 +44,30 @@ public final class CodeOfConstraint extends CardImpl {
return new CodeOfConstraint(this);
}
}
+
+class CodeOfConstraintEffect extends OneShotEffect {
+
+ CodeOfConstraintEffect() {
+ super(Outcome.Benefit);
+ staticText = "
Addendum — If you cast this spell during your main phase, " +
+ "tap that creature and it doesn't untap during its controller's next untap step.";
+ }
+
+ private CodeOfConstraintEffect(final CodeOfConstraintEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public CodeOfConstraintEffect copy() {
+ return new CodeOfConstraintEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (AddendumCondition.instance.apply(game, source)) {
+ new TapTargetEffect().apply(game, source);
+ game.addEffect(new DontUntapInControllersNextUntapStepTargetEffect(), source);
+ }
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/c/CometStorm.java b/Mage.Sets/src/mage/cards/c/CometStorm.java
index 0c331d3d7bd..41c3de1510c 100644
--- a/Mage.Sets/src/mage/cards/c/CometStorm.java
+++ b/Mage.Sets/src/mage/cards/c/CometStorm.java
@@ -49,7 +49,7 @@ enum CometStormAdjuster implements TargetAdjuster {
@Override
public void adjustTargets(Ability ability, Game game) {
ability.getTargets().clear();
- int numbTargets = new MultikickerCount().calculate(game, ability, null) + 1;
+ int numbTargets = MultikickerCount.instance.calculate(game, ability, null) + 1;
ability.addTarget(new TargetAnyTarget(numbTargets));
}
}
diff --git a/Mage.Sets/src/mage/cards/c/Condescend.java b/Mage.Sets/src/mage/cards/c/Condescend.java
index 05ce5af84c0..26c8ceb6f9c 100644
--- a/Mage.Sets/src/mage/cards/c/Condescend.java
+++ b/Mage.Sets/src/mage/cards/c/Condescend.java
@@ -21,7 +21,7 @@ public final class Condescend extends CardImpl {
// Counter target spell unless its controller pays {X}.
- this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetSpell());
// Scry 2.
this.getSpellAbility().addEffect(new ScryEffect(2));
diff --git a/Mage.Sets/src/mage/cards/c/CopperLeafAngel.java b/Mage.Sets/src/mage/cards/c/CopperLeafAngel.java
index 8fe61fdfd93..a894eec2486 100644
--- a/Mage.Sets/src/mage/cards/c/CopperLeafAngel.java
+++ b/Mage.Sets/src/mage/cards/c/CopperLeafAngel.java
@@ -35,7 +35,7 @@ public final class CopperLeafAngel extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// {tap}, Sacrifice X lands: Put X +1/+1 counters on Copper-Leaf Angel.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(),new GetXValue(), false), new TapSourceCost());
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.P1P1.createInstance(),GetXValue.instance, false), new TapSourceCost());
ability.addCost(new SacrificeXTargetCost(new FilterControlledLandPermanent("lands"), false));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/c/CorrosiveGale.java b/Mage.Sets/src/mage/cards/c/CorrosiveGale.java
index 3a4ca7d2346..e5a5ccb8e41 100644
--- a/Mage.Sets/src/mage/cards/c/CorrosiveGale.java
+++ b/Mage.Sets/src/mage/cards/c/CorrosiveGale.java
@@ -27,7 +27,7 @@ public final class CorrosiveGale extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{G/P}");
- this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), filter));
+ this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, filter));
}
public CorrosiveGale(final CorrosiveGale card) {
diff --git a/Mage.Sets/src/mage/cards/c/CratersClaws.java b/Mage.Sets/src/mage/cards/c/CratersClaws.java
index 7d212220f11..acdea1c74a7 100644
--- a/Mage.Sets/src/mage/cards/c/CratersClaws.java
+++ b/Mage.Sets/src/mage/cards/c/CratersClaws.java
@@ -24,8 +24,8 @@ public final class CratersClaws extends CardImpl {
// Crater's Claws deals X damage to any target.
// Ferocious — Crater's Claws deals X plus 2 damage to that creature or player instead if you control a creature with power 4 or greater.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetEffect(new IntPlusDynamicValue(2, new ManacostVariableValue())),
- new DamageTargetEffect(new ManacostVariableValue()),
+ new DamageTargetEffect(new IntPlusDynamicValue(2, ManacostVariableValue.instance)),
+ new DamageTargetEffect(ManacostVariableValue.instance),
FerociousCondition.instance,
"{this} deals X damage to any target."
+ "
Ferocious — {this} deals X plus 2 damage to that permanent or player instead if you control a creature with power 4 or greater"));
diff --git a/Mage.Sets/src/mage/cards/c/CrazedFirecat.java b/Mage.Sets/src/mage/cards/c/CrazedFirecat.java
index fdc96f3f9ae..dac9cfa97ac 100644
--- a/Mage.Sets/src/mage/cards/c/CrazedFirecat.java
+++ b/Mage.Sets/src/mage/cards/c/CrazedFirecat.java
@@ -66,7 +66,7 @@ class CrazedFirecatEffect extends OneShotEffect {
Permanent sourceObject = game.getPermanent(source.getSourceId());
if (controller != null && sourceObject != null) {
int flipsWon = 0;
- while (controller.flipCoin(game)) {
+ while (controller.flipCoin(source, game, true)) {
flipsWon++;
}
sourceObject.addCounters(CounterType.P1P1.createInstance(flipsWon), source, game);
diff --git a/Mage.Sets/src/mage/cards/c/CreatureBond.java b/Mage.Sets/src/mage/cards/c/CreatureBond.java
index a1a84630738..7a6fff4437a 100644
--- a/Mage.Sets/src/mage/cards/c/CreatureBond.java
+++ b/Mage.Sets/src/mage/cards/c/CreatureBond.java
@@ -35,7 +35,7 @@ public final class CreatureBond extends CardImpl {
this.addAbility(ability);
// When enchanted creature dies, Creature Bond deals damage equal to that creature's toughness to the creature's controller.
- this.addAbility( new DiesAttachedTriggeredAbility(new DamageAttachedControllerEffect(new AttachedPermanentToughnessValue()), "enchanted creature"));
+ this.addAbility( new DiesAttachedTriggeredAbility(new DamageAttachedControllerEffect(AttachedPermanentToughnessValue.instance), "enchanted creature"));
}
public CreatureBond(final CreatureBond card) {
diff --git a/Mage.Sets/src/mage/cards/c/CreepyDoll.java b/Mage.Sets/src/mage/cards/c/CreepyDoll.java
index ad0b08e0992..71c3056523a 100644
--- a/Mage.Sets/src/mage/cards/c/CreepyDoll.java
+++ b/Mage.Sets/src/mage/cards/c/CreepyDoll.java
@@ -100,7 +100,7 @@ class CreepyDollEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- if (player.flipCoin(game)) {
+ if (player.flipCoin(source, game, true)) {
UUID targetId = getTargetPointer().getFirst(game, source);
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
diff --git a/Mage.Sets/src/mage/cards/c/CrimsonHellkite.java b/Mage.Sets/src/mage/cards/c/CrimsonHellkite.java
index a929af7dfd1..f9f867142d4 100644
--- a/Mage.Sets/src/mage/cards/c/CrimsonHellkite.java
+++ b/Mage.Sets/src/mage/cards/c/CrimsonHellkite.java
@@ -43,7 +43,7 @@ public final class CrimsonHellkite extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// {X}, {tap}: Crimson Hellkite deals X damage to target creature. Spend only red mana on X.
- Effect effect = new DamageTargetEffect(new ManacostVariableValue());
+ Effect effect = new DamageTargetEffect(ManacostVariableValue.instance);
effect.setText("{this} deals X damage to target creature. Spend only red mana on X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/c/CrookedScales.java b/Mage.Sets/src/mage/cards/c/CrookedScales.java
index 6a0e880cf7e..0b19ce0bc44 100644
--- a/Mage.Sets/src/mage/cards/c/CrookedScales.java
+++ b/Mage.Sets/src/mage/cards/c/CrookedScales.java
@@ -72,7 +72,7 @@ class CrookedScalesEffect extends OneShotEffect {
Cost cost;
String message = "You lost the flip. Pay {3} to prevent your creature from being destroyed?";
do {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
if (theirGuy != null) {
theirGuy.destroy(controller.getId(), game, false);
}
diff --git a/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java b/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java
index 1eb974792d8..0b8fe29b228 100644
--- a/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java
+++ b/Mage.Sets/src/mage/cards/c/CrucibleOfTheSpiritDragon.java
@@ -44,7 +44,7 @@ public final class CrucibleOfTheSpiritDragon extends CardImpl {
// {T}, Remove X storage counters from Crucible of the Spirit Dragon: Add X mana in any combination of colors. Spend this mana only to cast Dragon spells or activate abilities of Dragons.
ability = new ConditionalAnyColorManaAbility(
new TapSourceCost(),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new CrucibleOfTheSpiritDragonManaBuilder(),
false
);
diff --git a/Mage.Sets/src/mage/cards/c/CruelSadist.java b/Mage.Sets/src/mage/cards/c/CruelSadist.java
index 3be03cd96ea..63e7c85fac2 100644
--- a/Mage.Sets/src/mage/cards/c/CruelSadist.java
+++ b/Mage.Sets/src/mage/cards/c/CruelSadist.java
@@ -44,7 +44,7 @@ public final class CruelSadist extends CardImpl {
this.addAbility(ability);
// {2}{B}, {T}, Remove X +1/+1 counters from Cruel Sadist: Cruel Sadist deals X damage to target creature.
- Effect effect = new DamageTargetEffect(new RemovedCountersForCostValue());
+ Effect effect = new DamageTargetEffect(RemovedCountersForCostValue.instance);
effect.setText("{this} deals X damage to target creature");
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}{B}"));
ability.addCost(new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java b/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java
index 175626dcd4b..23ac8658fcb 100644
--- a/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java
+++ b/Mage.Sets/src/mage/cards/c/CryOfTheCarnarium.java
@@ -85,7 +85,7 @@ class CryOfTheCarnariumReplacementEffect extends ReplacementEffectImpl {
CryOfTheCarnariumReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Exile);
- staticText = "If a creature would die this turn, exile it instead.";
+ staticText = " If a creature would die this turn, exile it instead.";
}
private CryOfTheCarnariumReplacementEffect(final CryOfTheCarnariumReplacementEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/c/CryptOfTheEternals.java b/Mage.Sets/src/mage/cards/c/CryptOfTheEternals.java
index 05433c0e5fa..8dae5457187 100644
--- a/Mage.Sets/src/mage/cards/c/CryptOfTheEternals.java
+++ b/Mage.Sets/src/mage/cards/c/CryptOfTheEternals.java
@@ -12,7 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.UUID;
@@ -23,18 +23,15 @@ public final class CryptOfTheEternals extends CardImpl {
// When Crypt of the Eternals enters the battlefield, you gain 1 life.
this.addAbility(new EntersBattlefieldTriggeredAbility(new GainLifeEffect(1)));
-
+
// {T}: Add {C}.
this.addAbility(new ColorlessManaAbility());
// {1}, {T}: Add {U}, {B}, or {R}.
- List list = new ArrayList() {{
- add(Mana.BlueMana(1));
- add(Mana.BlackMana(1));
- add(Mana.RedMana(1));
- }};
-
- for(Mana m: list) {
+ List list = Arrays.asList(Mana.BlueMana(1), Mana.BlackMana(1), Mana.RedMana(1));
+
+
+ for (Mana m : list) {
SimpleManaAbility uAbility = new SimpleManaAbility(Zone.BATTLEFIELD, m, new ManaCostsImpl("{1}"));
uAbility.addCost(new TapSourceCost());
this.addAbility(uAbility);
diff --git a/Mage.Sets/src/mage/cards/c/CryptRats.java b/Mage.Sets/src/mage/cards/c/CryptRats.java
index f19332295b1..d5dfc118933 100644
--- a/Mage.Sets/src/mage/cards/c/CryptRats.java
+++ b/Mage.Sets/src/mage/cards/c/CryptRats.java
@@ -38,7 +38,7 @@ public final class CryptRats extends CardImpl {
this.toughness = new MageInt(1);
// {X}: Crypt Rats deals X damage to each creature and each player. Spend only black mana on X.
- Effect effect = new DamageEverythingEffect(new ManacostVariableValue());
+ Effect effect = new DamageEverythingEffect(ManacostVariableValue.instance);
effect.setText("{this} deals X damage to each creature and each player. Spend only black mana on X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect,new ManaCostsImpl("{X}"));
VariableCost variableCost = ability.getManaCostsToPay().getVariableCosts().get(0);
diff --git a/Mage.Sets/src/mage/cards/c/CutRibbons.java b/Mage.Sets/src/mage/cards/c/CutRibbons.java
index 3d373dd9fbd..b29a27ae096 100644
--- a/Mage.Sets/src/mage/cards/c/CutRibbons.java
+++ b/Mage.Sets/src/mage/cards/c/CutRibbons.java
@@ -29,7 +29,7 @@ public final class CutRibbons extends SplitCard {
// Ribbons
// Each opponent loses X life.
getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true));
- getRightHalfCard().getSpellAbility().addEffect(new LoseLifeOpponentsEffect(new ManacostVariableValue()));
+ getRightHalfCard().getSpellAbility().addEffect(new LoseLifeOpponentsEffect(ManacostVariableValue.instance));
}
diff --git a/Mage.Sets/src/mage/cards/d/DamiaSageOfStone.java b/Mage.Sets/src/mage/cards/d/DamiaSageOfStone.java
index 2ca4be33812..4b750825856 100644
--- a/Mage.Sets/src/mage/cards/d/DamiaSageOfStone.java
+++ b/Mage.Sets/src/mage/cards/d/DamiaSageOfStone.java
@@ -59,7 +59,7 @@ public final class DamiaSageOfStone extends CardImpl {
class DamiaSageOfStoneTriggeredAbility extends BeginningOfUpkeepTriggeredAbility {
DamiaSageOfStoneTriggeredAbility() {
- super(new DrawCardSourceControllerEffect(new IntPlusDynamicValue(7, new MultipliedValue(new CardsInControllerHandCount(), -1))), TargetController.YOU, false);
+ super(new DrawCardSourceControllerEffect(new IntPlusDynamicValue(7, new MultipliedValue(CardsInControllerHandCount.instance, -1))), TargetController.YOU, false);
}
DamiaSageOfStoneTriggeredAbility(final DamiaSageOfStoneTriggeredAbility ability) {
diff --git a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java
index 8abf13e932d..713cded9566 100644
--- a/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java
+++ b/Mage.Sets/src/mage/cards/d/DarettiIngeniousIconoclast.java
@@ -1,12 +1,10 @@
package mage.cards.d;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
@@ -14,32 +12,36 @@ import mage.abilities.effects.common.DoIfCostPaid;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
+import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
+import mage.filter.StaticFilters;
import mage.filter.common.FilterArtifactCard;
-import mage.filter.common.FilterControlledArtifactPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
-import mage.game.Game;
import mage.game.permanent.token.DarettiConstructToken;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInGraveyardOrBattlefield;
import mage.target.common.TargetControlledPermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class DarettiIngeniousIconoclast extends CardImpl {
- private static final FilterPermanent filter = new FilterPermanent("artifact or creature");
+ private static final FilterPermanent filter
+ = new FilterPermanent("artifact or creature (to destroy)");
+ private static final FilterCard filter2
+ = new FilterArtifactCard("artifact card in a graveyard or artifact on the battlefield");
static {
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
- new CardTypePredicate(CardType.CREATURE)));
+ new CardTypePredicate(CardType.CREATURE)
+ ));
}
public DarettiIngeniousIconoclast(UUID ownerId, CardSetInfo setInfo) {
@@ -50,27 +52,31 @@ public final class DarettiIngeniousIconoclast extends CardImpl {
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// +1: Create a 1/1 colorless Construct artifact creature token with defender.
- LoyaltyAbility ability = new LoyaltyAbility(new CreateTokenEffect(new DarettiConstructToken()), 1);
- this.addAbility(ability);
+ this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new DarettiConstructToken()), 1));
// -1: You may sacrifice an artifact. If you do, destroy target artifact or creature.
- ability = new LoyaltyAbility(
- new DoIfCostPaid(new DestroyTargetEffect(""), new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledArtifactPermanent("an artifact")))),
- -1);
+ Ability ability = new LoyaltyAbility(
+ new DoIfCostPaid(
+ new DestroyTargetEffect("destroy target artifact or creature"),
+ new SacrificeTargetCost(new TargetControlledPermanent(
+ StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT_AN
+ ))
+ ), -1
+ );
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
// -6: Choose target artifact card in a graveyard or artifact on the battlefield. Create three tokens that are copies of it.
ability = new LoyaltyAbility(
new CreateTokenCopyTargetEffect(null, null, false, 3)
- .setText("Choose target artifact card in a graveyard or artifact on the battlefield. Create three tokens that are copies of it"),
- -6);
- ability.addTarget(new TargetCardInGraveyardOrBattlefield(new FilterArtifactCard("artifact card in a graveyard or artifact on the battlefield")));
+ .setText("Choose target artifact card in a graveyard or artifact on the battlefield. " +
+ "Create three tokens that are copies of it"), -6
+ );
+ ability.addTarget(new TargetCardInGraveyardOrBattlefield(filter2));
this.addAbility(ability);
-
}
- public DarettiIngeniousIconoclast(final DarettiIngeniousIconoclast card) {
+ private DarettiIngeniousIconoclast(final DarettiIngeniousIconoclast card) {
super(card);
}
@@ -79,25 +85,3 @@ public final class DarettiIngeniousIconoclast extends CardImpl {
return new DarettiIngeniousIconoclast(this);
}
}
-
-class DarettiIngeniousIconoclastEffect extends OneShotEffect {
-
- public DarettiIngeniousIconoclastEffect() {
- super(Outcome.Benefit);
- this.staticText = "Choose target artifact card in a graveyard or artifact on the battlefield. Create three tokens that are copies of it";
- }
-
- public DarettiIngeniousIconoclastEffect(final DarettiIngeniousIconoclastEffect effect) {
- super(effect);
- }
-
- @Override
- public DarettiIngeniousIconoclastEffect copy() {
- return new DarettiIngeniousIconoclastEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- return false;
- }
-}
diff --git a/Mage.Sets/src/mage/cards/d/DarkSalvation.java b/Mage.Sets/src/mage/cards/d/DarkSalvation.java
index 30100994acd..9c0b24555c4 100644
--- a/Mage.Sets/src/mage/cards/d/DarkSalvation.java
+++ b/Mage.Sets/src/mage/cards/d/DarkSalvation.java
@@ -34,7 +34,7 @@ public final class DarkSalvation extends CardImpl {
// Target player creates X 2/2 black Zombie creature tokens, then up to one target creature gets -1/-1 until end of turn for each Zombie that player controls.
this.getSpellAbility().addTarget(new TargetPlayer());
- Effect effect = new CreateTokenTargetEffect(new ZombieToken(), new ManacostVariableValue());
+ Effect effect = new CreateTokenTargetEffect(new ZombieToken(), ManacostVariableValue.instance);
effect.setText("Target player creates X 2/2 black Zombie creature tokens");
this.getSpellAbility().addEffect(effect);
DynamicValue value = new ZombiesControlledByTargetPlayerCount();
diff --git a/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java b/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java
index a6527a52fee..7faec30b05a 100644
--- a/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java
+++ b/Mage.Sets/src/mage/cards/d/DawnglowInfusion.java
@@ -25,7 +25,7 @@ public final class DawnglowInfusion extends CardImpl {
// You gain X life if {G} was spent to cast Dawnglow Infusion and X life if {W} was spent to cast it.
- DynamicValue xValue = new ManacostVariableValue();
+ DynamicValue xValue = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new GainLifeEffect(xValue),
new ManaWasSpentCondition(ColoredManaSymbol.G), "You gain X life if {G} was spent to cast {this}"));
diff --git a/Mage.Sets/src/mage/cards/d/DeathCloud.java b/Mage.Sets/src/mage/cards/d/DeathCloud.java
index c239907ad62..1ce4f411208 100644
--- a/Mage.Sets/src/mage/cards/d/DeathCloud.java
+++ b/Mage.Sets/src/mage/cards/d/DeathCloud.java
@@ -25,7 +25,7 @@ public final class DeathCloud extends CardImpl {
// Each player loses X life, discards X cards, sacrifices X creatures, then sacrifices X lands.
- DynamicValue xValue = new ManacostVariableValue();
+ DynamicValue xValue = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new LoseLifeAllPlayersEffect(xValue));
Effect effect = new DiscardEachPlayerEffect(xValue, false);
effect.setText(", discards X cards");
diff --git a/Mage.Sets/src/mage/cards/d/DeathGrasp.java b/Mage.Sets/src/mage/cards/d/DeathGrasp.java
index e0e3426b6e5..114635e43cc 100644
--- a/Mage.Sets/src/mage/cards/d/DeathGrasp.java
+++ b/Mage.Sets/src/mage/cards/d/DeathGrasp.java
@@ -21,8 +21,8 @@ public final class DeathGrasp extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{W}{B}");
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
- this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
+ this.getSpellAbility().addEffect(new GainLifeEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/d/DeathMutation.java b/Mage.Sets/src/mage/cards/d/DeathMutation.java
index d24bec85c23..879b21f6d89 100644
--- a/Mage.Sets/src/mage/cards/d/DeathMutation.java
+++ b/Mage.Sets/src/mage/cards/d/DeathMutation.java
@@ -35,7 +35,7 @@ public final class DeathMutation extends CardImpl {
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));
this.getSpellAbility().addTarget(new TargetPermanent(filter));
// create X 1/1 green Saproling creature tokens, where X is that creature's converted mana cost.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), new TargetConvertedManaCost()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), TargetConvertedManaCost.instance));
}
public DeathMutation(final DeathMutation card) {
diff --git a/Mage.Sets/src/mage/cards/d/DeathWind.java b/Mage.Sets/src/mage/cards/d/DeathWind.java
index 69fbaadadfc..663ba2f6043 100644
--- a/Mage.Sets/src/mage/cards/d/DeathWind.java
+++ b/Mage.Sets/src/mage/cards/d/DeathWind.java
@@ -22,7 +22,7 @@ public final class DeathWind extends CardImpl {
// Target creature gets -X/-X until end of turn.
- DynamicValue x = new SignInversionDynamicValue(new ManacostVariableValue());
+ DynamicValue x = new SignInversionDynamicValue(ManacostVariableValue.instance);
this.getSpellAbility().addEffect(new BoostTargetEffect(x, x, Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/d/DeathforgeShaman.java b/Mage.Sets/src/mage/cards/d/DeathforgeShaman.java
index a9c707fd5a9..7ebbe2c241c 100644
--- a/Mage.Sets/src/mage/cards/d/DeathforgeShaman.java
+++ b/Mage.Sets/src/mage/cards/d/DeathforgeShaman.java
@@ -69,7 +69,7 @@ class DeathforgeShamanEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- DynamicValue value = new MultikickerCount();
+ DynamicValue value = MultikickerCount.instance;
int damage = value.calculate(game, source, this) * 2;
return new DamageTargetEffect(damage).apply(game, source);
}
diff --git a/Mage.Sets/src/mage/cards/d/DeathsShadow.java b/Mage.Sets/src/mage/cards/d/DeathsShadow.java
index 2591c2d11fa..5fa0ee15d9d 100644
--- a/Mage.Sets/src/mage/cards/d/DeathsShadow.java
+++ b/Mage.Sets/src/mage/cards/d/DeathsShadow.java
@@ -28,7 +28,7 @@ public final class DeathsShadow extends CardImpl {
this.toughness = new MageInt(13);
// Death's Shadow gets -X/-X, where X is your life total.
- SignInversionDynamicValue x = new SignInversionDynamicValue(new ControllerLifeCount(), false);
+ SignInversionDynamicValue x = new SignInversionDynamicValue(ControllerLifeCount.instance, false);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(x, x, Duration.WhileOnBattlefield)));
}
diff --git a/Mage.Sets/src/mage/cards/d/DecreeOfJustice.java b/Mage.Sets/src/mage/cards/d/DecreeOfJustice.java
index 27aa099dcd8..2da79ce805e 100644
--- a/Mage.Sets/src/mage/cards/d/DecreeOfJustice.java
+++ b/Mage.Sets/src/mage/cards/d/DecreeOfJustice.java
@@ -32,7 +32,7 @@ public final class DecreeOfJustice extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{2}{W}{W}");
// Create X 4/4 white Angel creature tokens with flying.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new AngelToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new AngelToken(), ManacostVariableValue.instance));
// Cycling {2}{W}
this.addAbility(new CyclingAbility(new ManaCostsImpl<>("{2}{W}")));
diff --git a/Mage.Sets/src/mage/cards/d/Deface.java b/Mage.Sets/src/mage/cards/d/Deface.java
index ec0d4afc23b..fa2d602b2e2 100644
--- a/Mage.Sets/src/mage/cards/d/Deface.java
+++ b/Mage.Sets/src/mage/cards/d/Deface.java
@@ -35,7 +35,7 @@ public final class Deface extends CardImpl {
// • Destroy target creature with defender.
Mode mode = new Mode(new DestroyTargetEffect());
- mode.addTarget(new TargetPermanent());
+ mode.addTarget(new TargetPermanent(filter));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/d/DelayTactic.java b/Mage.Sets/src/mage/cards/d/DelayTactic.java
index a51d607b436..7607fe00f80 100644
--- a/Mage.Sets/src/mage/cards/d/DelayTactic.java
+++ b/Mage.Sets/src/mage/cards/d/DelayTactic.java
@@ -41,7 +41,7 @@ public final class DelayTactic extends CardImpl {
this.getSpellAbility().addEffect(new GainAbilityAllEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, new FilterControlledCreaturePermanent())
.setText("Creatures you control gain hexproof until end of turn"));
- // Creatures target opponent controls don't untap during his or her next untap step.
+ // Creatures target opponent controls don't untap during their next untap step.
Mode mode = new Mode();
mode.addEffect(new DelayTacticEffect());
mode.addTarget(new TargetOpponent());
@@ -63,7 +63,7 @@ class DelayTacticEffect extends OneShotEffect {
DelayTacticEffect() {
super(Outcome.Benefit);
- this.staticText = "Creatures target opponent controls don't untap during his or her next untap step";
+ this.staticText = "Creatures target opponent controls don't untap during their next untap step";
}
DelayTacticEffect(final DelayTacticEffect effect) {
diff --git a/Mage.Sets/src/mage/cards/d/Demonfire.java b/Mage.Sets/src/mage/cards/d/Demonfire.java
index 71711b70c12..b8dfbc7148c 100644
--- a/Mage.Sets/src/mage/cards/d/Demonfire.java
+++ b/Mage.Sets/src/mage/cards/d/Demonfire.java
@@ -31,7 +31,7 @@ public final class Demonfire extends CardImpl {
// Demonfire deals X damage to any target.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetEffect(new ManacostVariableValue()),
+ new DamageTargetEffect(ManacostVariableValue.instance),
new InvertCondition(HellbentCondition.instance),
"{this} deals X damage to any target"));
@@ -41,7 +41,7 @@ public final class Demonfire extends CardImpl {
// Hellbent - If you have no cards in hand, Demonfire can't be countered and the damage can't be prevented.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetEffect(new ManacostVariableValue(), false),
+ new DamageTargetEffect(ManacostVariableValue.instance, false),
HellbentCondition.instance,
"
Hellbent — If you have no cards in hand, this spell can't be countered and the damage can't be prevented."));
// can't be countered
diff --git a/Mage.Sets/src/mage/cards/d/DescendantOfSoramaro.java b/Mage.Sets/src/mage/cards/d/DescendantOfSoramaro.java
index aad9696a80d..ce8cde5bd0d 100644
--- a/Mage.Sets/src/mage/cards/d/DescendantOfSoramaro.java
+++ b/Mage.Sets/src/mage/cards/d/DescendantOfSoramaro.java
@@ -28,7 +28,7 @@ public final class DescendantOfSoramaro extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// {1}{U}: Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order.
- Effect effect = new LookLibraryControllerEffect(new CardsInControllerHandCount());
+ Effect effect = new LookLibraryControllerEffect(CardsInControllerHandCount.instance);
effect.setText("Look at the top X cards of your library, where X is the number of cards in your hand, then put them back in any order");
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
effect, new ManaCostsImpl("{1}{U}")));
diff --git a/Mage.Sets/src/mage/cards/d/DesperateGambit.java b/Mage.Sets/src/mage/cards/d/DesperateGambit.java
index bce9512aa1d..80351f9dd66 100644
--- a/Mage.Sets/src/mage/cards/d/DesperateGambit.java
+++ b/Mage.Sets/src/mage/cards/d/DesperateGambit.java
@@ -8,7 +8,6 @@ import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.PreventionEffectImpl;
-import mage.abilities.effects.common.PreventDamageBySourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@@ -21,7 +20,6 @@ import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.filter.FilterObject;
-import mage.filter.predicate.permanent.ControllerPredicate;
import mage.players.Player;
import mage.target.TargetSource;
import mage.util.CardUtil;
@@ -70,7 +68,7 @@ class DesperateGambitEffect extends PreventionEffectImpl {
this.target.choose(Outcome.Benefit, source.getControllerId(), source.getSourceId(), game);
Player you = game.getPlayer(source.getControllerId());
if(you != null) {
- wonFlip = you.flipCoin(game);
+ wonFlip = you.flipCoin(source, game, true);
super.init(source, game);
}
}
diff --git a/Mage.Sets/src/mage/cards/d/Detonate.java b/Mage.Sets/src/mage/cards/d/Detonate.java
index de1a4096edc..782f5af864c 100644
--- a/Mage.Sets/src/mage/cards/d/Detonate.java
+++ b/Mage.Sets/src/mage/cards/d/Detonate.java
@@ -29,7 +29,7 @@ public final class Detonate extends CardImpl {
// Destroy target artifact with converted mana cost X. It can't be regenerated. Detonate deals X damage to that artifact's controller.
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));
this.getSpellAbility().addTarget(new TargetArtifactPermanent(new FilterArtifactPermanent("artifact with converted mana cost X")));
- Effect effect = new DamageTargetControllerEffect(new ManacostVariableValue());
+ Effect effect = new DamageTargetControllerEffect(ManacostVariableValue.instance);
effect.setText("{this} deals X damage to that artifact's controller");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().setTargetAdjuster(DetonateAdjuster.instance);
diff --git a/Mage.Sets/src/mage/cards/d/DevastatingDreams.java b/Mage.Sets/src/mage/cards/d/DevastatingDreams.java
index cebed2d85a4..ee0d2b5b276 100644
--- a/Mage.Sets/src/mage/cards/d/DevastatingDreams.java
+++ b/Mage.Sets/src/mage/cards/d/DevastatingDreams.java
@@ -32,10 +32,10 @@ public final class DevastatingDreams extends CardImpl {
this.getSpellAbility().addCost(new DevastatingDreamsAdditionalCost());
// Each player sacrifices X lands.
- this.getSpellAbility().addEffect(new SacrificeAllEffect(new GetXValue(), new FilterControlledLandPermanent("lands")));
+ this.getSpellAbility().addEffect(new SacrificeAllEffect(GetXValue.instance, new FilterControlledLandPermanent("lands")));
// Devastating Dreams deals X damage to each creature.
- this.getSpellAbility().addEffect(new DamageAllEffect(new GetXValue(), new FilterCreaturePermanent()));
+ this.getSpellAbility().addEffect(new DamageAllEffect(GetXValue.instance, new FilterCreaturePermanent()));
}
public DevastatingDreams(final DevastatingDreams card) {
diff --git a/Mage.Sets/src/mage/cards/d/DevastatingSummons.java b/Mage.Sets/src/mage/cards/d/DevastatingSummons.java
index e15ae2af9f5..c5521add77c 100644
--- a/Mage.Sets/src/mage/cards/d/DevastatingSummons.java
+++ b/Mage.Sets/src/mage/cards/d/DevastatingSummons.java
@@ -55,8 +55,8 @@ class DevastatingSummonsEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
DevastatingSummonsElementalToken token = new DevastatingSummonsElementalToken();
- token.getPower().modifyBaseValue(new GetXValue().calculate(game, source, this));
- token.getToughness().modifyBaseValue(new GetXValue().calculate(game, source, this));
+ token.getPower().modifyBaseValue(GetXValue.instance.calculate(game, source, this));
+ token.getToughness().modifyBaseValue(GetXValue.instance.calculate(game, source, this));
token.putOntoBattlefield(2, game, source.getSourceId(), source.getControllerId());
diff --git a/Mage.Sets/src/mage/cards/d/DevilsPlay.java b/Mage.Sets/src/mage/cards/d/DevilsPlay.java
index 111f906c868..fad1267f4cb 100644
--- a/Mage.Sets/src/mage/cards/d/DevilsPlay.java
+++ b/Mage.Sets/src/mage/cards/d/DevilsPlay.java
@@ -23,7 +23,7 @@ public final class DevilsPlay extends CardImpl {
// Devil's Play deals X damage to any target.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
// Flashback {X}{R}{R}{R}
this.addAbility(new FlashbackAbility(new ManaCostsImpl("{X}{R}{R}{R}"), TimingRule.SORCERY));
diff --git a/Mage.Sets/src/mage/cards/d/DiabolicRevelation.java b/Mage.Sets/src/mage/cards/d/DiabolicRevelation.java
index cd93dc22aa1..bdac351e7ba 100644
--- a/Mage.Sets/src/mage/cards/d/DiabolicRevelation.java
+++ b/Mage.Sets/src/mage/cards/d/DiabolicRevelation.java
@@ -58,7 +58,7 @@ class DiabolicRevelationEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- int amount = new ManacostVariableValue().calculate(game, source, this);
+ int amount = ManacostVariableValue.instance.calculate(game, source, this);
TargetCardInLibrary target = new TargetCardInLibrary(0, amount, new FilterCard());
Player player = game.getPlayer(source.getControllerId());
diff --git a/Mage.Sets/src/mage/cards/d/DiamondValley.java b/Mage.Sets/src/mage/cards/d/DiamondValley.java
index a1a75bb9486..530bbee905c 100644
--- a/Mage.Sets/src/mage/cards/d/DiamondValley.java
+++ b/Mage.Sets/src/mage/cards/d/DiamondValley.java
@@ -25,7 +25,7 @@ public final class DiamondValley extends CardImpl {
public DiamondValley(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
- Effect effect = new GainLifeEffect(new SacrificeCostCreaturesToughness());
+ Effect effect = new GainLifeEffect(SacrificeCostCreaturesToughness.instance);
effect.setText("You gain life equal to the sacrificed creature's toughness");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
diff --git a/Mage.Sets/src/mage/cards/d/Disintegrate.java b/Mage.Sets/src/mage/cards/d/Disintegrate.java
index bcd68137633..8b0f12edb55 100644
--- a/Mage.Sets/src/mage/cards/d/Disintegrate.java
+++ b/Mage.Sets/src/mage/cards/d/Disintegrate.java
@@ -23,7 +23,7 @@ public final class Disintegrate extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}");
// Disintegrate deals X damage to any target. That creature can't be regenerated this turn. If the creature would die this turn, exile it instead.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addEffect(new CantRegenerateTargetEffect(Duration.EndOfTurn, "That creature"));
Effect effect = new ExileTargetIfDiesEffect();
effect.setText("If the creature would die this turn, exile it instead");
diff --git a/Mage.Sets/src/mage/cards/d/DivineOffering.java b/Mage.Sets/src/mage/cards/d/DivineOffering.java
index 8682ffefdd8..02ddd7a87e8 100644
--- a/Mage.Sets/src/mage/cards/d/DivineOffering.java
+++ b/Mage.Sets/src/mage/cards/d/DivineOffering.java
@@ -23,7 +23,7 @@ public final class DivineOffering extends CardImpl {
// Destroy target artifact. You gain life equal to its converted mana cost.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
- Effect effect = new GainLifeEffect(new TargetConvertedManaCost());
+ Effect effect = new GainLifeEffect(TargetConvertedManaCost.instance);
effect.setText("You gain life equal to its converted mana cost");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetArtifactPermanent());
diff --git a/Mage.Sets/src/mage/cards/d/DomriChaosBringer.java b/Mage.Sets/src/mage/cards/d/DomriChaosBringer.java
index d1f796f2214..d05415185a7 100644
--- a/Mage.Sets/src/mage/cards/d/DomriChaosBringer.java
+++ b/Mage.Sets/src/mage/cards/d/DomriChaosBringer.java
@@ -3,29 +3,28 @@ package mage.cards.d;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.dynamicvalue.common.StaticValue;
-import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
-import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.effects.common.ManaEffect;
+import mage.abilities.effects.common.continuous.GainAbilityControlledSpellsEffect;
import mage.abilities.effects.mana.BasicManaEffect;
import mage.abilities.keyword.RiotAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
+import mage.filter.FilterSpell;
import mage.filter.StaticFilters;
+import mage.filter.predicate.mageobject.CardIdPredicate;
import mage.game.Game;
import mage.game.command.emblems.DomriChaosBringerEmblem;
import mage.game.events.GameEvent;
-import mage.game.events.ZoneChangeEvent;
-import mage.game.stack.Spell;
-import mage.target.targetpointer.FixedTarget;
-import mage.watchers.Watcher;
+import mage.players.Player;
-import java.util.ArrayList;
-import java.util.List;
import java.util.UUID;
/**
@@ -41,15 +40,7 @@ public final class DomriChaosBringer extends CardImpl {
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(5));
// +1: Add {R} or {G}. If that mana is spent on a creature spell, it gains riot.
- // TODO: make this into a single ability, also make this, Generator Servant and Hall of the Bandit Lord work without card scope watchers
- Mana mana = Mana.RedMana(1);
- mana.setFlag(true);
- Ability ability = new LoyaltyAbility(new BasicManaEffect(mana).setText("Add {R}. If that mana is spent on a creature spell, it gains riot"), 1);
- this.addAbility(ability, new HallOfTheBanditLordWatcher(ability));
- mana = Mana.GreenMana(1);
- mana.setFlag(true);
- ability = new LoyaltyAbility(new BasicManaEffect(mana).setText("Add {G}. If that mana is spent on a creature spell, it gains riot"), 1);
- this.addAbility(ability, new HallOfTheBanditLordWatcher(ability));
+ this.addAbility(new LoyaltyAbility(new DomriChaosBringerEffect(), 1));
// −3: Look at the top four cards of your library. You may reveal up to two creature cards from among them and put them into your hand. Put the rest on the bottom of your library in a random order.
this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(
@@ -77,68 +68,77 @@ public final class DomriChaosBringer extends CardImpl {
}
}
-class HallOfTheBanditLordWatcher extends Watcher {
+class DomriChaosBringerEffect extends OneShotEffect {
- private final Ability source;
- private final List creatures = new ArrayList<>();
-
- HallOfTheBanditLordWatcher(Ability source) {
- super(HallOfTheBanditLordWatcher.class.getSimpleName(), WatcherScope.CARD);
- this.source = source;
+ DomriChaosBringerEffect() {
+ super(Outcome.Benefit);
+ staticText = "Add {R} or {G}. If that mana is spent on a creature spell, it gains riot.";
}
- private HallOfTheBanditLordWatcher(final HallOfTheBanditLordWatcher watcher) {
- super(watcher);
- this.creatures.addAll(watcher.creatures);
- this.source = watcher.source;
+ private DomriChaosBringerEffect(final DomriChaosBringerEffect effect) {
+ super(effect);
}
@Override
- public HallOfTheBanditLordWatcher copy() {
- return new HallOfTheBanditLordWatcher(this);
+ public DomriChaosBringerEffect copy() {
+ return new DomriChaosBringerEffect(this);
}
@Override
- public void watch(GameEvent event, Game game) {
- if (event.getType() == GameEvent.EventType.MANA_PAID) {
- MageObject target = game.getObject(event.getTargetId());
- if (event.getSourceId() != null
- && event.getSourceId().equals(this.getSourceId())
- && target != null && target.isCreature()
- && event.getFlag()) {
- if (target instanceof Spell) {
- this.creatures.add(((Spell) target).getCard().getId());
- }
- }
+ public boolean apply(Game game, Ability source) {
+ Player player = game.getPlayer(source.getControllerId());
+ if (player == null) {
+ return false;
}
- if (event.getType() == GameEvent.EventType.COUNTERED) {
- if (creatures.contains(event.getTargetId())) {
- creatures.remove(event.getSourceId());
- }
- }
- if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
- if (creatures.contains(event.getSourceId())) {
- ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
- // spell was e.g. exiled and goes again to stack, so previous cast has not resolved.
- if (zEvent.getToZone() == Zone.STACK) {
- creatures.remove(event.getSourceId());
- }
- }
- }
- if (event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD) {
- if (creatures.contains(event.getSourceId())) {
- ContinuousEffect effect = new GainAbilityTargetEffect(new RiotAbility(), Duration.Custom);
- effect.setTargetPointer(new FixedTarget(event.getSourceId()));
- game.addEffect(effect, source);
- creatures.remove(event.getSourceId());
- }
+ ManaEffect manaEffect;
+ if (player.chooseUse(Outcome.PutManaInPool, "Choose red or green mana", "", "Red", "Green", source, game)) {
+ manaEffect = new BasicManaEffect(Mana.RedMana(1));
+ } else {
+ manaEffect = new BasicManaEffect(Mana.GreenMana(1));
}
+ game.addDelayedTriggeredAbility(new DomriChaosBringerTriggeredAbility(source.getSourceId()), source);
+ return manaEffect.apply(game, source);
+ }
+}
+
+class DomriChaosBringerTriggeredAbility extends DelayedTriggeredAbility {
+
+ private final UUID spellId;
+
+ DomriChaosBringerTriggeredAbility(UUID spellId) {
+ super(null, Duration.EndOfStep, true);
+ this.spellId = spellId;
+ this.usesStack = false;
+ }
+
+ private DomriChaosBringerTriggeredAbility(final DomriChaosBringerTriggeredAbility ability) {
+ super(ability);
+ this.spellId = ability.spellId;
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == GameEvent.EventType.MANA_PAID;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (!event.getSourceId().equals(spellId)) {
+ return false;
+ }
+ MageObject mo = game.getObject(event.getTargetId());
+ if (mo == null || !mo.isCreature()) {
+ return false;
+ }
+ this.getEffects().clear();
+ FilterSpell filter = new FilterSpell();
+ filter.add(new CardIdPredicate(event.getTargetId()));
+ this.addEffect(new GainAbilityControlledSpellsEffect(new RiotAbility(), filter));
+ return true;
+ }
+
+ @Override
+ public DomriChaosBringerTriggeredAbility copy() {
+ return new DomriChaosBringerTriggeredAbility(this);
}
-
- @Override
- public void reset() {
- super.reset();
- creatures.clear();
- }
-
}
diff --git a/Mage.Sets/src/mage/cards/d/DovinGrandArbiter.java b/Mage.Sets/src/mage/cards/d/DovinGrandArbiter.java
index ddf32aaf734..ea2400d975b 100644
--- a/Mage.Sets/src/mage/cards/d/DovinGrandArbiter.java
+++ b/Mage.Sets/src/mage/cards/d/DovinGrandArbiter.java
@@ -51,7 +51,7 @@ public final class DovinGrandArbiter extends CardImpl {
new StaticValue(3), StaticFilters.FILTER_CARD,
Zone.LIBRARY, false, false, false,
Zone.HAND, false, false, false
- ).setText("Look at the top ten cards of your library. " +
+ ).setBackInRandomOrder(true).setText("Look at the top ten cards of your library. " +
"Put three of them into your hand and the rest " +
"on the bottom of your library in a random order."
), -7));
@@ -70,7 +70,7 @@ public final class DovinGrandArbiter extends CardImpl {
class DovinGrandArbiterDelayedTriggeredAbility extends DelayedTriggeredAbility {
DovinGrandArbiterDelayedTriggeredAbility() {
- super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance()), Duration.EndOfTurn);
+ super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance()), Duration.EndOfTurn, false);
}
private DovinGrandArbiterDelayedTriggeredAbility(final DovinGrandArbiterDelayedTriggeredAbility ability) {
diff --git a/Mage.Sets/src/mage/cards/d/DranaKalastriaBloodchief.java b/Mage.Sets/src/mage/cards/d/DranaKalastriaBloodchief.java
index 025eb357746..404fafb5f75 100644
--- a/Mage.Sets/src/mage/cards/d/DranaKalastriaBloodchief.java
+++ b/Mage.Sets/src/mage/cards/d/DranaKalastriaBloodchief.java
@@ -37,8 +37,8 @@ public final class DranaKalastriaBloodchief extends CardImpl {
this.toughness = new MageInt(4);
this.addAbility(FlyingAbility.getInstance());
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(new StaticValue(0), new SignInversionDynamicValue(new ManacostVariableValue()), Duration.EndOfTurn), new ManaCostsImpl("{X}{B}{B}"));
- ability.addEffect(new BoostSourceEffect(new ManacostVariableValue(), new StaticValue(0), Duration.EndOfTurn));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(new StaticValue(0), new SignInversionDynamicValue(ManacostVariableValue.instance), Duration.EndOfTurn), new ManaCostsImpl("{X}{B}{B}"));
+ ability.addEffect(new BoostSourceEffect(ManacostVariableValue.instance, new StaticValue(0), Duration.EndOfTurn));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/d/DreadSlag.java b/Mage.Sets/src/mage/cards/d/DreadSlag.java
index dd7548175b1..bebbcd720d7 100644
--- a/Mage.Sets/src/mage/cards/d/DreadSlag.java
+++ b/Mage.Sets/src/mage/cards/d/DreadSlag.java
@@ -32,7 +32,7 @@ public final class DreadSlag extends CardImpl {
// Trample
this.addAbility(TrampleAbility.getInstance());
// Dread Slag gets -4/-4 for each card in your hand.
- DynamicValue amount = new MultipliedValue(new CardsInControllerHandCount(), -4);
+ DynamicValue amount = new MultipliedValue(CardsInControllerHandCount.instance, -4);
Effect effect = new BoostSourceEffect(amount, amount, Duration.WhileOnBattlefield);
effect.setText("{this} gets -4/-4 for each card in your hand");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
diff --git a/Mage.Sets/src/mage/cards/d/DreadshipReef.java b/Mage.Sets/src/mage/cards/d/DreadshipReef.java
index 7073e04f11d..53a75729b99 100644
--- a/Mage.Sets/src/mage/cards/d/DreadshipReef.java
+++ b/Mage.Sets/src/mage/cards/d/DreadshipReef.java
@@ -36,7 +36,7 @@ public final class DreadshipReef extends CardImpl {
this.addAbility(ability);
// {1}, Remove X storage counters from Dreadship Reef: Add X mana in any combination of {U} and/or {B}.
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
- new AddManaInAnyCombinationEffect(new RemovedCountersForCostValue(), ColoredManaSymbol.U, ColoredManaSymbol.B),
+ new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.U, ColoredManaSymbol.B),
new GenericManaCost(1));
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/d/DreambornMuse.java b/Mage.Sets/src/mage/cards/d/DreambornMuse.java
index 66cc27162bd..169107a55c2 100644
--- a/Mage.Sets/src/mage/cards/d/DreambornMuse.java
+++ b/Mage.Sets/src/mage/cards/d/DreambornMuse.java
@@ -25,7 +25,7 @@ public final class DreambornMuse extends CardImpl {
this.toughness = new MageInt(2);
// At the beginning of each player's upkeep, that player puts the top X cards of their library into their graveyard, where X is the number of cards in their hand.
- PutLibraryIntoGraveTargetEffect effect = new PutLibraryIntoGraveTargetEffect(new CardsInTargetPlayerHandCount());
+ PutLibraryIntoGraveTargetEffect effect = new PutLibraryIntoGraveTargetEffect(CardsInTargetPlayerHandCount.instance);
effect.setText("that player puts the top X cards of their library into their graveyard, where X is the number of cards in their hand.");
this.addAbility(new BeginningOfUpkeepTriggeredAbility(effect, TargetController.ANY, false));
diff --git a/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java b/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java
index 082731e051d..06412ef6bf5 100644
--- a/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java
+++ b/Mage.Sets/src/mage/cards/d/DregsOfSorrow.java
@@ -28,7 +28,7 @@ public final class DregsOfSorrow extends CardImpl {
// Destroy X target nonblack creatures. Draw X cards.
this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy X target nonblack creatures"));
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(ManacostVariableValue.instance));
this.getSpellAbility().setTargetAdjuster(DregsOfSorrowAdjuster.instance);
}
diff --git a/Mage.Sets/src/mage/cards/d/DrippingTongueZubera.java b/Mage.Sets/src/mage/cards/d/DrippingTongueZubera.java
index a5d6b4d3f33..ed36a32932b 100644
--- a/Mage.Sets/src/mage/cards/d/DrippingTongueZubera.java
+++ b/Mage.Sets/src/mage/cards/d/DrippingTongueZubera.java
@@ -27,7 +27,7 @@ public final class DrippingTongueZubera extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(2);
- this.addAbility(new DiesTriggeredAbility(new CreateTokenEffect(new SpiritToken(), new ZuberasDiedDynamicValue()), false), new ZuberasDiedWatcher());
+ this.addAbility(new DiesTriggeredAbility(new CreateTokenEffect(new SpiritToken(), ZuberasDiedDynamicValue.instance), false), new ZuberasDiedWatcher());
}
public DrippingTongueZubera (final DrippingTongueZubera card) {
diff --git a/Mage.Sets/src/mage/cards/d/DwarvenHold.java b/Mage.Sets/src/mage/cards/d/DwarvenHold.java
index bfc1a8c95c1..5c8e97d9e2f 100644
--- a/Mage.Sets/src/mage/cards/d/DwarvenHold.java
+++ b/Mage.Sets/src/mage/cards/d/DwarvenHold.java
@@ -44,7 +44,7 @@ public final class DwarvenHold extends CardImpl {
// {tap}, Remove any number of storage counters from Dwarven Hold: Add {R} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.RedMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {R} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/e/Earthquake.java b/Mage.Sets/src/mage/cards/e/Earthquake.java
index d653f3182d3..da844b150df 100644
--- a/Mage.Sets/src/mage/cards/e/Earthquake.java
+++ b/Mage.Sets/src/mage/cards/e/Earthquake.java
@@ -29,7 +29,7 @@ public final class Earthquake extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}");
// Hurricane deals X damage to each creature with flying and each player.
- this.getSpellAbility().addEffect(new DamageEverythingEffect(new ManacostVariableValue(), filter));
+ this.getSpellAbility().addEffect(new DamageEverythingEffect(ManacostVariableValue.instance, filter));
}
public Earthquake(final Earthquake card) {
diff --git a/Mage.Sets/src/mage/cards/e/Electrodominance.java b/Mage.Sets/src/mage/cards/e/Electrodominance.java
index 2d87841a40c..4b9342fcaac 100644
--- a/Mage.Sets/src/mage/cards/e/Electrodominance.java
+++ b/Mage.Sets/src/mage/cards/e/Electrodominance.java
@@ -19,9 +19,9 @@ public final class Electrodominance extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}{R}");
// Electrodominance deals X damage to any target. You may cast a card with converted mana cost X or less from your hand without paying its mana cost.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
- this.getSpellAbility().addEffect(new CastWithoutPayingManaCostEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CastWithoutPayingManaCostEffect(ManacostVariableValue.instance));
}
private Electrodominance(final Electrodominance card) {
diff --git a/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java b/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java
index 03ad3ea31bb..34910dc22e6 100644
--- a/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java
+++ b/Mage.Sets/src/mage/cards/e/EliminateTheCompetition.java
@@ -50,7 +50,7 @@ enum EliminateTheCompetitionAdjuster implements TargetAdjuster {
@Override
public void adjustTargets(Ability ability, Game game) {
ability.getTargets().clear();
- int sac = new GetXValue().calculate(game, ability, null);
+ int sac = GetXValue.instance.calculate(game, ability, null);
ability.addTarget(new TargetCreaturePermanent(sac, sac));
}
}
diff --git a/Mage.Sets/src/mage/cards/e/EmberFistZubera.java b/Mage.Sets/src/mage/cards/e/EmberFistZubera.java
index 0a79c71c41e..acfe8a486ca 100644
--- a/Mage.Sets/src/mage/cards/e/EmberFistZubera.java
+++ b/Mage.Sets/src/mage/cards/e/EmberFistZubera.java
@@ -28,7 +28,7 @@ public final class EmberFistZubera extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(2);
- Ability ability = new DiesTriggeredAbility(new DamageTargetEffect(new ZuberasDiedDynamicValue()));
+ Ability ability = new DiesTriggeredAbility(new DamageTargetEffect(ZuberasDiedDynamicValue.instance));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability, new ZuberasDiedWatcher());
}
diff --git a/Mage.Sets/src/mage/cards/e/EmergencyPowers.java b/Mage.Sets/src/mage/cards/e/EmergencyPowers.java
index 652aaaf58ea..e2495e3607e 100644
--- a/Mage.Sets/src/mage/cards/e/EmergencyPowers.java
+++ b/Mage.Sets/src/mage/cards/e/EmergencyPowers.java
@@ -1,7 +1,8 @@
package mage.cards.e;
+import mage.abilities.Ability;
import mage.abilities.condition.common.AddendumCondition;
-import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DrawCardAllEffect;
import mage.abilities.effects.common.ExileSpellEffect;
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
@@ -10,8 +11,10 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
+import mage.constants.Outcome;
import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
+import mage.game.Game;
import java.util.UUID;
@@ -20,30 +23,15 @@ import java.util.UUID;
*/
public final class EmergencyPowers extends CardImpl {
- public static final FilterPermanentCard filter
- = new FilterPermanentCard("a permanent card with converted mana cost 7 or less");
-
- static {
- filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 8));
- }
-
public EmergencyPowers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{5}{W}{U}");
// Each player shuffles their hand and graveyard into their library, then draws seven cards. Exile Emergency Powers.
this.getSpellAbility().addEffect(new ShuffleHandGraveyardAllEffect());
this.getSpellAbility().addEffect(new DrawCardAllEffect(7).setText(", then draws seven cards"));
- this.getSpellAbility().addEffect(ExileSpellEffect.getInstance());
// Addendum — If you cast this spell during your main phase, you may put a permanent card with converted mana cost 7 or less from your hand onto the battlefield.
- this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new PutCardFromHandOntoBattlefieldEffect(filter),
- AddendumCondition.instance,
- "
Addendum — " +
- "If you cast this spell during your main phase, " +
- "you may put a permanent card with converted mana cost 7 or less " +
- "from your hand onto the battlefield."
- ));
+ this.getSpellAbility().addEffect(new EmergencyPowersEffect());
}
private EmergencyPowers(final EmergencyPowers card) {
@@ -55,4 +43,37 @@ public final class EmergencyPowers extends CardImpl {
return new EmergencyPowers(this);
}
}
+
+class EmergencyPowersEffect extends OneShotEffect {
+
+ public static final FilterPermanentCard filter
+ = new FilterPermanentCard("a permanent card with converted mana cost 7 or less");
+
+ static {
+ filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 8));
+ }
+
+ EmergencyPowersEffect() {
+ super(Outcome.Benefit);
+ staticText = "Exile {this}.
Addendum — If you cast this spell during your main phase, " +
+ "you may put a permanent card with converted mana cost 7 or less from your hand onto the battlefield.";
+ }
+
+ private EmergencyPowersEffect(final EmergencyPowersEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public EmergencyPowersEffect copy() {
+ return new EmergencyPowersEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ if (AddendumCondition.instance.apply(game, source)) {
+ new PutCardFromHandOntoBattlefieldEffect(filter).apply(game, source);
+ }
+ return ExileSpellEffect.getInstance().apply(game, source);
+ }
+}
// I am the senate!
diff --git a/Mage.Sets/src/mage/cards/e/EmptyThePits.java b/Mage.Sets/src/mage/cards/e/EmptyThePits.java
index f2bfbd27fb1..fb2337fd5e6 100644
--- a/Mage.Sets/src/mage/cards/e/EmptyThePits.java
+++ b/Mage.Sets/src/mage/cards/e/EmptyThePits.java
@@ -24,7 +24,7 @@ public final class EmptyThePits extends CardImpl {
this.addAbility(new DelveAbility());
// create X 2/2 black Zombie creature tokens tapped.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new ZombieToken(), new ManacostVariableValue(), true, false));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new ZombieToken(), ManacostVariableValue.instance, true, false));
}
public EmptyThePits(final EmptyThePits card) {
diff --git a/Mage.Sets/src/mage/cards/e/EmpyrialArmor.java b/Mage.Sets/src/mage/cards/e/EmpyrialArmor.java
index 9ae1b61d026..de4b1ffa237 100644
--- a/Mage.Sets/src/mage/cards/e/EmpyrialArmor.java
+++ b/Mage.Sets/src/mage/cards/e/EmpyrialArmor.java
@@ -38,7 +38,7 @@ public final class EmpyrialArmor extends CardImpl {
this.addAbility(ability);
// Enchanted creature gets +1/+1 for each card in your hand.
- DynamicValue xValue = new CardsInControllerHandCount();
+ DynamicValue xValue = CardsInControllerHandCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(xValue, xValue, Duration.WhileOnBattlefield)));
}
diff --git a/Mage.Sets/src/mage/cards/e/EmpyrialPlate.java b/Mage.Sets/src/mage/cards/e/EmpyrialPlate.java
index d43fe32b16d..4116555856a 100644
--- a/Mage.Sets/src/mage/cards/e/EmpyrialPlate.java
+++ b/Mage.Sets/src/mage/cards/e/EmpyrialPlate.java
@@ -25,7 +25,7 @@ public final class EmpyrialPlate extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +1/+1 for each card in your hand.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(new CardsInControllerHandCount(), new CardsInControllerHandCount())));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(CardsInControllerHandCount.instance, CardsInControllerHandCount.instance)));
// Equip {2}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2)));
diff --git a/Mage.Sets/src/mage/cards/e/EnclaveElite.java b/Mage.Sets/src/mage/cards/e/EnclaveElite.java
index 58f5df9c835..de61d1239d1 100644
--- a/Mage.Sets/src/mage/cards/e/EnclaveElite.java
+++ b/Mage.Sets/src/mage/cards/e/EnclaveElite.java
@@ -36,7 +36,7 @@ public final class EnclaveElite extends CardImpl {
// Enclave Elite enters the battlefield with a +1/+1 counter on it for each time it was kicked.
this.addAbility(new EntersBattlefieldAbility(
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new MultikickerCount(), true),
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), MultikickerCount.instance, true),
"with a +1/+1 counter on it for each time it was kicked"));
}
diff --git a/Mage.Sets/src/mage/cards/e/EndlessSwarm.java b/Mage.Sets/src/mage/cards/e/EndlessSwarm.java
index f3eac93fad2..a33c4084634 100644
--- a/Mage.Sets/src/mage/cards/e/EndlessSwarm.java
+++ b/Mage.Sets/src/mage/cards/e/EndlessSwarm.java
@@ -22,7 +22,7 @@ public final class EndlessSwarm extends CardImpl {
// Create a 1/1 green Snake creature token for each card in your hand.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SnakeToken(), new CardsInControllerHandCount()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SnakeToken(), CardsInControllerHandCount.instance));
// Epic
this.getSpellAbility().addEffect(new EpicEffect());
diff --git a/Mage.Sets/src/mage/cards/e/EnergyBolt.java b/Mage.Sets/src/mage/cards/e/EnergyBolt.java
index ef5fe784bbc..216c983a537 100644
--- a/Mage.Sets/src/mage/cards/e/EnergyBolt.java
+++ b/Mage.Sets/src/mage/cards/e/EnergyBolt.java
@@ -22,10 +22,10 @@ public final class EnergyBolt extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}{W}");
// Choose one - Energy Bolt deals X damage to target player; or target player gains X life.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
Mode mode = new Mode();
- mode.addEffect(new GainLifeTargetEffect(new ManacostVariableValue()));
+ mode.addEffect(new GainLifeTargetEffect(ManacostVariableValue.instance));
mode.addTarget(new TargetPlayer());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/e/Enrage.java b/Mage.Sets/src/mage/cards/e/Enrage.java
index 83c2876c0ca..9d83d33659c 100644
--- a/Mage.Sets/src/mage/cards/e/Enrage.java
+++ b/Mage.Sets/src/mage/cards/e/Enrage.java
@@ -22,7 +22,7 @@ public final class Enrage extends CardImpl {
// Target creature gets +X/+0 until end of turn.
- this.getSpellAbility().addEffect(new BoostTargetEffect(new ManacostVariableValue(), new StaticValue(0), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(ManacostVariableValue.instance, new StaticValue(0), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java b/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java
index 224dcc1d44b..9dbaf7728b2 100644
--- a/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java
+++ b/Mage.Sets/src/mage/cards/e/EnshrinedMemories.java
@@ -20,7 +20,7 @@ public final class EnshrinedMemories extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}");
// Reveal the top X cards of your library. Put all creature cards revealed this way into your hand and the rest on the bottom of your library in any order.
- this.getSpellAbility().addEffect(new RevealLibraryPutIntoHandEffect(new ManacostVariableValue(), new FilterCreatureCard(), Zone.LIBRARY, true));
+ this.getSpellAbility().addEffect(new RevealLibraryPutIntoHandEffect(ManacostVariableValue.instance, new FilterCreatureCard(), Zone.LIBRARY, true));
}
public EnshrinedMemories(final EnshrinedMemories card) {
diff --git a/Mage.Sets/src/mage/cards/e/EnslavedHorror.java b/Mage.Sets/src/mage/cards/e/EnslavedHorror.java
index 3fbba05fa12..c8362a0ca20 100644
--- a/Mage.Sets/src/mage/cards/e/EnslavedHorror.java
+++ b/Mage.Sets/src/mage/cards/e/EnslavedHorror.java
@@ -32,7 +32,7 @@ public final class EnslavedHorror extends CardImpl {
this.power = new MageInt(4);
this.toughness = new MageInt(4);
- // When Enslaved Horror enters the battlefield, each other player may return a creature card from his or her graveyard to the battlefield.
+ // When Enslaved Horror enters the battlefield, each other player may return a creature card from their graveyard to the battlefield.
this.addAbility(new EntersBattlefieldTriggeredAbility(new EnslavedHorrorEffect()));
}
diff --git a/Mage.Sets/src/mage/cards/e/EntreatTheAngels.java b/Mage.Sets/src/mage/cards/e/EntreatTheAngels.java
index e398ee5b5b1..234618f3517 100644
--- a/Mage.Sets/src/mage/cards/e/EntreatTheAngels.java
+++ b/Mage.Sets/src/mage/cards/e/EntreatTheAngels.java
@@ -22,7 +22,7 @@ public final class EntreatTheAngels extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{W}{W}{W}");
// Create X 4/4 white Angel creature tokens with flying.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new AngelToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new AngelToken(), ManacostVariableValue.instance));
// Miracle {X}{W}{W}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl("{X}{W}{W}")));
diff --git a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java
index 1102b8e1ba3..ef504ece33d 100644
--- a/Mage.Sets/src/mage/cards/e/EntropicSpecter.java
+++ b/Mage.Sets/src/mage/cards/e/EntropicSpecter.java
@@ -1,7 +1,6 @@
package mage.cards.e;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
@@ -19,8 +18,9 @@ import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author jeffwadsworth
*/
public final class EntropicSpecter extends CardImpl {
@@ -42,7 +42,7 @@ public final class EntropicSpecter extends CardImpl {
// Entropic Specter's power and toughness are each equal to the number of cards in the chosen player's hand.
this.addAbility(new SimpleStaticAbility(Zone.ALL,
// back to the graveyard or if the choosen player left the gane it's again a 0/0
- new SetPowerToughnessSourceEffect(new CardsInTargetPlayerHandCount(), Duration.WhileOnBattlefield, SubLayer.CharacteristicDefining_7a)));
+ new SetPowerToughnessSourceEffect(CardsInTargetPlayerHandCount.instance, Duration.WhileOnBattlefield, SubLayer.CharacteristicDefining_7a)));
// Whenever Entropic Specter deals damage to a player, that player discards a card.
this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new DiscardTargetEffect(1, false), false, true));
@@ -58,7 +58,8 @@ public final class EntropicSpecter extends CardImpl {
}
}
-class CardsInTargetPlayerHandCount implements DynamicValue {
+enum CardsInTargetPlayerHandCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -74,7 +75,7 @@ class CardsInTargetPlayerHandCount implements DynamicValue {
@Override
public DynamicValue copy() {
- return new mage.abilities.dynamicvalue.common.CardsInControllerHandCount();
+ return instance;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/e/EssenceCapture.java b/Mage.Sets/src/mage/cards/e/EssenceCapture.java
index 42e758726da..7af749c4492 100644
--- a/Mage.Sets/src/mage/cards/e/EssenceCapture.java
+++ b/Mage.Sets/src/mage/cards/e/EssenceCapture.java
@@ -6,6 +6,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
+import mage.filter.common.FilterCreatureSpell;
import mage.target.TargetSpell;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
@@ -22,7 +23,7 @@ public final class EssenceCapture extends CardImpl {
// Counter target creature spell.
this.getSpellAbility().addEffect(new CounterTargetEffect());
- this.getSpellAbility().addTarget(new TargetSpell());
+ this.getSpellAbility().addTarget(new TargetSpell(new FilterCreatureSpell()));
// Put a +1/+1 counter on up to one target creature you control.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(
diff --git a/Mage.Sets/src/mage/cards/e/EverflowingChalice.java b/Mage.Sets/src/mage/cards/e/EverflowingChalice.java
index 98755ba1972..256f062d985 100644
--- a/Mage.Sets/src/mage/cards/e/EverflowingChalice.java
+++ b/Mage.Sets/src/mage/cards/e/EverflowingChalice.java
@@ -33,7 +33,7 @@ public final class EverflowingChalice extends CardImpl {
// Everflowing Chalice enters the battlefield with a charge counter on it for each time it was kicked.
this.addAbility(new EntersBattlefieldAbility(
- new AddCountersSourceEffect(CounterType.CHARGE.createInstance(0), new MultikickerCount(), true),
+ new AddCountersSourceEffect(CounterType.CHARGE.createInstance(0), MultikickerCount.instance, true),
"with a charge counter on it for each time it was kicked"));
// {T}: Add {C} for each charge counter on Everflowing Chalice.
diff --git a/Mage.Sets/src/mage/cards/e/Excise.java b/Mage.Sets/src/mage/cards/e/Excise.java
index a390e62e309..a232c410858 100644
--- a/Mage.Sets/src/mage/cards/e/Excise.java
+++ b/Mage.Sets/src/mage/cards/e/Excise.java
@@ -28,7 +28,7 @@ public final class Excise extends CardImpl {
// Excise target nonwhite attacking creature unless its controller pays {X}.
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
- this.getSpellAbility().addEffect(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new ExileTargetEffect(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DoUnlessTargetPlayerOrTargetsControllerPaysEffect(new ExileTargetEffect(), ManacostVariableValue.instance));
}
public Excise(final Excise card) {
diff --git a/Mage.Sets/src/mage/cards/f/FallOfTheTitans.java b/Mage.Sets/src/mage/cards/f/FallOfTheTitans.java
index 71a44fc473f..1b45b0e00f7 100644
--- a/Mage.Sets/src/mage/cards/f/FallOfTheTitans.java
+++ b/Mage.Sets/src/mage/cards/f/FallOfTheTitans.java
@@ -21,7 +21,7 @@ public final class FallOfTheTitans extends CardImpl {
// Fall of the Titans deals X damage to each of up to two target creatures and/or players.
this.getSpellAbility().addTarget(new TargetAnyTarget(0, 2));
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
// Surge {X}{R}
addAbility(new SurgeAbility(this, "{X}{R}"));
diff --git a/Mage.Sets/src/mage/cards/f/FanningTheFlames.java b/Mage.Sets/src/mage/cards/f/FanningTheFlames.java
index 4fe03dc2dac..e7d224f7e5f 100644
--- a/Mage.Sets/src/mage/cards/f/FanningTheFlames.java
+++ b/Mage.Sets/src/mage/cards/f/FanningTheFlames.java
@@ -23,7 +23,7 @@ public final class FanningTheFlames extends CardImpl {
this.addAbility(new BuybackAbility("{3}"));
// Fanning the Flames deals X damage to any target.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/f/Fascination.java b/Mage.Sets/src/mage/cards/f/Fascination.java
index d53a9219841..e3aa3f389d9 100644
--- a/Mage.Sets/src/mage/cards/f/Fascination.java
+++ b/Mage.Sets/src/mage/cards/f/Fascination.java
@@ -22,11 +22,11 @@ public final class Fascination extends CardImpl {
// Choose one -
// * Each player draws X cards.
- this.getSpellAbility().addEffect(new DrawCardAllEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardAllEffect(ManacostVariableValue.instance));
// * Each player puts the top X cards of their library into their graveyard.
Mode mode = new Mode();
- mode.addEffect(new PutTopCardOfLibraryIntoGraveEachPlayerEffect(new ManacostVariableValue(), TargetController.ANY));
+ mode.addEffect(new PutTopCardOfLibraryIntoGraveEachPlayerEffect(ManacostVariableValue.instance, TargetController.ANY));
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/f/FatalFrenzy.java b/Mage.Sets/src/mage/cards/f/FatalFrenzy.java
index a3e9ebd5d32..6b074158208 100644
--- a/Mage.Sets/src/mage/cards/f/FatalFrenzy.java
+++ b/Mage.Sets/src/mage/cards/f/FatalFrenzy.java
@@ -35,7 +35,7 @@ public final class FatalFrenzy extends CardImpl {
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn)
.setText("Until end of turn, target creature you control gains trample")
);
- this.getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true)
+ this.getSpellAbility().addEffect(new BoostTargetEffect(TargetPermanentPowerCount.instance, new StaticValue(0), Duration.EndOfTurn, true)
.setText("and gets +X/+0, where X is its power.")
);
this.getSpellAbility().addEffect(new FatalFrenzyEffect());
diff --git a/Mage.Sets/src/mage/cards/f/FatefulShowdown.java b/Mage.Sets/src/mage/cards/f/FatefulShowdown.java
index 02b4db6762f..11f60f05011 100644
--- a/Mage.Sets/src/mage/cards/f/FatefulShowdown.java
+++ b/Mage.Sets/src/mage/cards/f/FatefulShowdown.java
@@ -21,7 +21,7 @@ public final class FatefulShowdown extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{R}{R}");
// Fateful Showdown deals damage to any target equal to the number of cards in your hand. Discard all the cards in your hand, then draw that many cards.
- Effect effect = new DamageTargetEffect(new CardsInControllerHandCount());
+ Effect effect = new DamageTargetEffect(CardsInControllerHandCount.instance);
effect.setText("{this} deals damage to any target equal to the number of cards in your hand");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/f/Feint.java b/Mage.Sets/src/mage/cards/f/Feint.java
new file mode 100644
index 00000000000..bccd33ddceb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/f/Feint.java
@@ -0,0 +1,85 @@
+
+package mage.cards.f;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.PreventionEffect;
+import mage.abilities.effects.common.PreventDamageByTargetEffect;
+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.combat.CombatGroup;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetAttackingCreature;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author L_J
+ */
+public final class Feint extends CardImpl {
+
+ public Feint(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{R}");
+
+ // Tap all creatures blocking target attacking creature. Prevent all combat damage that would be dealt this turn by that creature and each creature blocking it.
+ this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true).setText(""));
+ this.getSpellAbility().addEffect(new FeintEffect());
+ this.getSpellAbility().addTarget(new TargetAttackingCreature());
+ }
+
+ public Feint(final Feint card) {
+ super(card);
+ }
+
+ @Override
+ public Feint copy() {
+ return new Feint(this);
+ }
+
+}
+
+class FeintEffect extends OneShotEffect {
+
+ public FeintEffect() {
+ super(Outcome.ReturnToHand);
+ this.staticText = "Tap all creatures blocking target attacking creature. Prevent all combat damage that would be dealt this turn by that creature and each creature blocking it";
+ }
+
+ public FeintEffect(final FeintEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public FeintEffect copy() {
+ return new FeintEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (controller != null && creature != null) {
+ for (CombatGroup combatGroup : game.getCombat().getGroups()) {
+ if (combatGroup.getAttackers().contains(creature.getId())) {
+ for (UUID blockerId : combatGroup.getBlockers()) {
+ Permanent blocker = game.getPermanent(blockerId);
+ if (blocker != null) {
+ blocker.tap(game);
+ PreventionEffect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn, true);
+ effect.setTargetPointer(new FixedTarget(blocker.getId()));
+ game.addEffect(effect, source);
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/f/FestivalOfTheGuildpact.java b/Mage.Sets/src/mage/cards/f/FestivalOfTheGuildpact.java
index 414368c1abb..be5027f5187 100644
--- a/Mage.Sets/src/mage/cards/f/FestivalOfTheGuildpact.java
+++ b/Mage.Sets/src/mage/cards/f/FestivalOfTheGuildpact.java
@@ -20,7 +20,7 @@ public final class FestivalOfTheGuildpact extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{W}");
// Prevent the next X damage that would be dealt to you this turn.
- this.getSpellAbility().addEffect(new PreventDamageToControllerEffect(Duration.EndOfTurn, false, true, new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new PreventDamageToControllerEffect(Duration.EndOfTurn, false, true, ManacostVariableValue.instance));
// Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
diff --git a/Mage.Sets/src/mage/cards/f/FickleEfreet.java b/Mage.Sets/src/mage/cards/f/FickleEfreet.java
index 3d0cf974d48..4e67afe38fa 100644
--- a/Mage.Sets/src/mage/cards/f/FickleEfreet.java
+++ b/Mage.Sets/src/mage/cards/f/FickleEfreet.java
@@ -71,7 +71,7 @@ class FickleEfreetChangeControlEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller != null) {
- if (!controller.flipCoin(game)) {
+ if (!controller.flipCoin(source, game, true)) {
if (sourcePermanent != null) {
Target target = new TargetOpponent(true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
diff --git a/Mage.Sets/src/mage/cards/f/FieryGambit.java b/Mage.Sets/src/mage/cards/f/FieryGambit.java
index 3a5ab06bdf3..36177cf86d1 100644
--- a/Mage.Sets/src/mage/cards/f/FieryGambit.java
+++ b/Mage.Sets/src/mage/cards/f/FieryGambit.java
@@ -64,7 +64,7 @@ class FieryGambitEffect extends OneShotEffect {
if (controller != null && sourceObject != null) {
int flipsWon = 0;
boolean controllerStopped = false;
- while (controller.flipCoin(game)) {
+ while (controller.flipCoin(source, game, true)) {
++flipsWon;
if (!controller.chooseUse(outcome, "You won " + flipsWon + (flipsWon == 1 ? " flip." : " flips.") +
" Flip another coin?", source, game)) {
diff --git a/Mage.Sets/src/mage/cards/f/FightingChance.java b/Mage.Sets/src/mage/cards/f/FightingChance.java
index 896e01dcfea..d67bef03c3d 100644
--- a/Mage.Sets/src/mage/cards/f/FightingChance.java
+++ b/Mage.Sets/src/mage/cards/f/FightingChance.java
@@ -61,7 +61,7 @@ class FightingChanceEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
for (UUID blocker : game.getCombat().getBlockers()) {
- if (player.flipCoin(game)) {
+ if (player.flipCoin(source, game, true)) {
PreventDamageByTargetEffect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn, true);
effect.setTargetPointer(new FixedTarget(blocker));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/f/FinalStrike.java b/Mage.Sets/src/mage/cards/f/FinalStrike.java
index 4cd4c7f1670..6881b640206 100644
--- a/Mage.Sets/src/mage/cards/f/FinalStrike.java
+++ b/Mage.Sets/src/mage/cards/f/FinalStrike.java
@@ -26,7 +26,7 @@ public final class FinalStrike extends CardImpl {
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
// Final Strike deals damage to target opponent equal to the sacrificed creature's power.
- Effect effect = new DamageTargetEffect(new SacrificeCostCreaturesPower());
+ Effect effect = new DamageTargetEffect(SacrificeCostCreaturesPower.instance);
effect.setText("{this} deals damage to target opponent or planeswalker equal to the sacrificed creature's power");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetOpponentOrPlaneswalker());
diff --git a/Mage.Sets/src/mage/cards/f/FireCovenant.java b/Mage.Sets/src/mage/cards/f/FireCovenant.java
index ae9870a467a..80f8f729097 100644
--- a/Mage.Sets/src/mage/cards/f/FireCovenant.java
+++ b/Mage.Sets/src/mage/cards/f/FireCovenant.java
@@ -25,7 +25,7 @@ public final class FireCovenant extends CardImpl {
this.getSpellAbility().addCost(new PayVariableLifeCost(true));
// Fire Covenant deals X damage divided as you choose among any number of target creatures.
- DynamicValue xValue = new GetXValue();
+ DynamicValue xValue = GetXValue.instance;
this.getSpellAbility().addEffect(new DamageMultiEffect(xValue));
this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(xValue));
}
diff --git a/Mage.Sets/src/mage/cards/f/Firestorm.java b/Mage.Sets/src/mage/cards/f/Firestorm.java
index ba503d37905..b489ee21b62 100644
--- a/Mage.Sets/src/mage/cards/f/Firestorm.java
+++ b/Mage.Sets/src/mage/cards/f/Firestorm.java
@@ -48,7 +48,7 @@ enum FirestormAdjuster implements TargetAdjuster {
@Override
public void adjustTargets(Ability ability, Game game) {
- int xValue = new GetXValue().calculate(game, ability, null);
+ int xValue = GetXValue.instance.calculate(game, ability, null);
if (xValue > 0) {
Target target = new TargetAnyTarget(xValue);
ability.addTarget(target);
@@ -70,7 +70,7 @@ class FirestormEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
- int amount = (new GetXValue()).calculate(game, source, this);
+ int amount = (GetXValue.instance).calculate(game, source, this);
if (you != null) {
if (!source.getTargets().isEmpty()) {
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
diff --git a/Mage.Sets/src/mage/cards/f/FleshAllergy.java b/Mage.Sets/src/mage/cards/f/FleshAllergy.java
index 6206824743b..b14d2f10ee5 100644
--- a/Mage.Sets/src/mage/cards/f/FleshAllergy.java
+++ b/Mage.Sets/src/mage/cards/f/FleshAllergy.java
@@ -54,13 +54,13 @@ public final class FleshAllergy extends CardImpl {
class FleshAllergyWatcher extends Watcher {
- public int creaturesDiedThisTurn = 0;
+ private int creaturesDiedThisTurn = 0;
public FleshAllergyWatcher() {
super(FleshAllergyWatcher.class, WatcherScope.GAME);
}
- public FleshAllergyWatcher(final FleshAllergyWatcher watcher) {
+ private FleshAllergyWatcher(final FleshAllergyWatcher watcher) {
super(watcher);
}
@@ -79,6 +79,10 @@ class FleshAllergyWatcher extends Watcher {
}
}
+ public int getCreaturesDiedThisTurn(){
+ return creaturesDiedThisTurn;
+ }
+
@Override
public void reset() {
super.reset();
@@ -94,7 +98,7 @@ class FleshAllergyEffect extends OneShotEffect {
staticText = "Its controller loses life equal to the number of creatures that died this turn";
}
- public FleshAllergyEffect(final FleshAllergyEffect effect) {
+ private FleshAllergyEffect(final FleshAllergyEffect effect) {
super(effect);
}
@@ -110,7 +114,7 @@ class FleshAllergyEffect extends OneShotEffect {
if (permanent != null && watcher != null) {
Player player = game.getPlayer(permanent.getControllerId());
if (player != null) {
- int amount = watcher.creaturesDiedThisTurn;
+ int amount = watcher.getCreaturesDiedThisTurn();
if (amount > 0) {
player.loseLife(amount, game, false);
return true;
diff --git a/Mage.Sets/src/mage/cards/f/Fling.java b/Mage.Sets/src/mage/cards/f/Fling.java
index 422ec3263ee..67de60eca99 100644
--- a/Mage.Sets/src/mage/cards/f/Fling.java
+++ b/Mage.Sets/src/mage/cards/f/Fling.java
@@ -22,7 +22,7 @@ public final class Fling extends CardImpl {
public Fling(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
- Effect effect = new DamageTargetEffect(new SacrificeCostCreaturesPower());
+ Effect effect = new DamageTargetEffect(SacrificeCostCreaturesPower.instance);
effect.setText("{this} deals damage equal to the sacrificed creature's power to any target");
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
this.getSpellAbility().addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/f/FloatingDreamZubera.java b/Mage.Sets/src/mage/cards/f/FloatingDreamZubera.java
index a5aa32a32a1..f2e77e0b509 100644
--- a/Mage.Sets/src/mage/cards/f/FloatingDreamZubera.java
+++ b/Mage.Sets/src/mage/cards/f/FloatingDreamZubera.java
@@ -25,7 +25,7 @@ public final class FloatingDreamZubera extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(2);
- this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(new ZuberasDiedDynamicValue())), new ZuberasDiedWatcher());
+ this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(ZuberasDiedDynamicValue.instance)), new ZuberasDiedWatcher());
}
public FloatingDreamZubera(final FloatingDreamZubera card) {
diff --git a/Mage.Sets/src/mage/cards/f/FlockOfRabidSheep.java b/Mage.Sets/src/mage/cards/f/FlockOfRabidSheep.java
index 79ac3e5e977..018f5f3b239 100644
--- a/Mage.Sets/src/mage/cards/f/FlockOfRabidSheep.java
+++ b/Mage.Sets/src/mage/cards/f/FlockOfRabidSheep.java
@@ -59,7 +59,7 @@ class FlockOfRabidSheepEffect extends OneShotEffect {
int repeat = source.getManaCostsToPay().getX();
int wonCount = 0;
for (int i = 1; i <= repeat; i++) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
wonCount++;
}
}
diff --git a/Mage.Sets/src/mage/cards/f/FlowstoneSlide.java b/Mage.Sets/src/mage/cards/f/FlowstoneSlide.java
index 479d9f124be..fe68ae63e8b 100644
--- a/Mage.Sets/src/mage/cards/f/FlowstoneSlide.java
+++ b/Mage.Sets/src/mage/cards/f/FlowstoneSlide.java
@@ -20,8 +20,8 @@ public final class FlowstoneSlide extends CardImpl {
public FlowstoneSlide(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{2}{R}{R}");
- DynamicValue xPos = new ManacostVariableValue();
- DynamicValue xNeg = new SignInversionDynamicValue(new ManacostVariableValue());
+ DynamicValue xPos = ManacostVariableValue.instance;
+ DynamicValue xNeg = new SignInversionDynamicValue(ManacostVariableValue.instance);
// All creatures get +X/-X until end of turn.
this.getSpellAbility().addEffect(new BoostAllEffect(xPos, xNeg, Duration.EndOfTurn));
diff --git a/Mage.Sets/src/mage/cards/f/FontOfAgonies.java b/Mage.Sets/src/mage/cards/f/FontOfAgonies.java
index 984192d8462..4abcc4eb09a 100644
--- a/Mage.Sets/src/mage/cards/f/FontOfAgonies.java
+++ b/Mage.Sets/src/mage/cards/f/FontOfAgonies.java
@@ -14,6 +14,7 @@ import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
@@ -31,6 +32,7 @@ public final class FontOfAgonies extends CardImpl {
// {1}{B}, Remove four blood counters from Font of Agonies: Destroy target creature.
Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new ManaCostsImpl("{1}{B}"));
ability.addCost(new RemoveCountersSourceCost(CounterType.BLOOD.createInstance(4)));
+ ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/f/ForceLightning.java b/Mage.Sets/src/mage/cards/f/ForceLightning.java
index 64b07aa29d1..46793dcd5d9 100644
--- a/Mage.Sets/src/mage/cards/f/ForceLightning.java
+++ b/Mage.Sets/src/mage/cards/f/ForceLightning.java
@@ -24,7 +24,7 @@ public final class ForceLightning extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}{R}");
// Force Lightning deals X damage to any target.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
// Scry X.
diff --git a/Mage.Sets/src/mage/cards/f/Foresight.java b/Mage.Sets/src/mage/cards/f/Foresight.java
index 96ce3b1792f..6f3ebfe1d52 100644
--- a/Mage.Sets/src/mage/cards/f/Foresight.java
+++ b/Mage.Sets/src/mage/cards/f/Foresight.java
@@ -70,9 +70,9 @@ class ForesightEffect extends SearchEffect {
card.moveToExile(null, null, targetId, game);
}
}
+ player.shuffleLibrary(source, game);
return true;
}
- player.shuffleLibrary(source, game);
return false;
}
diff --git a/Mage.Sets/src/mage/cards/f/FountainOfCho.java b/Mage.Sets/src/mage/cards/f/FountainOfCho.java
index 566c64e58f9..1686099ab5e 100644
--- a/Mage.Sets/src/mage/cards/f/FountainOfCho.java
+++ b/Mage.Sets/src/mage/cards/f/FountainOfCho.java
@@ -34,7 +34,7 @@ public final class FountainOfCho extends CardImpl {
// {T}, Remove any number of storage counters from Fountain of Cho: Add {W} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.WhiteMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {W} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/f/FreneticEfreet.java b/Mage.Sets/src/mage/cards/f/FreneticEfreet.java
index b2f407420be..e5d37014a01 100644
--- a/Mage.Sets/src/mage/cards/f/FreneticEfreet.java
+++ b/Mage.Sets/src/mage/cards/f/FreneticEfreet.java
@@ -69,7 +69,7 @@ class FreneticEfreetEffect extends OneShotEffect {
if (controller == null) {
return false;
}
- boolean flip = controller.flipCoin(game);
+ boolean flip = controller.flipCoin(source, game, true);
if (permanent == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/f/FreneticSliver.java b/Mage.Sets/src/mage/cards/f/FreneticSliver.java
index 6655f21dbd4..e054ecb968f 100644
--- a/Mage.Sets/src/mage/cards/f/FreneticSliver.java
+++ b/Mage.Sets/src/mage/cards/f/FreneticSliver.java
@@ -76,7 +76,7 @@ class FreneticSliverEffect extends OneShotEffect {
if (player == null || perm == null) {
return false;
}
- if (player.flipCoin(game)) {
+ if (player.flipCoin(source, game, true)) {
return new ExileReturnBattlefieldOwnerNextEndStepSourceEffect(true).apply(game, source);
} else {
return perm.sacrifice(source.getSourceId(), game);
diff --git a/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java b/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java
index 3343f039e4c..92a0ce7e204 100644
--- a/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java
+++ b/Mage.Sets/src/mage/cards/f/FreyaliseSupplicant.java
@@ -43,7 +43,7 @@ public final class FreyaliseSupplicant extends CardImpl {
this.toughness = new MageInt(1);
// {tap}, Sacrifice a red or white creature: Freyalise Supplicant deals damage to any target equal to half the sacrificed creature's power, rounded down.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new HalfValue(new SacrificeCostCreaturesPower(), false)), new TapSourceCost());
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new HalfValue(SacrificeCostCreaturesPower.instance, false)), new TapSourceCost());
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(filter)));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/f/FungalReaches.java b/Mage.Sets/src/mage/cards/f/FungalReaches.java
index 92598fdd615..69f0a3cbe66 100644
--- a/Mage.Sets/src/mage/cards/f/FungalReaches.java
+++ b/Mage.Sets/src/mage/cards/f/FungalReaches.java
@@ -38,7 +38,7 @@ public final class FungalReaches extends CardImpl {
// {1}, Remove X storage counters from Fungal Reaches: Add X mana in any combination of {R} and/or {G}.
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
- new AddManaInAnyCombinationEffect(new RemovedCountersForCostValue(), ColoredManaSymbol.R, ColoredManaSymbol.G),
+ new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.R, ColoredManaSymbol.G),
new GenericManaCost(1));
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/f/FungalSprouting.java b/Mage.Sets/src/mage/cards/f/FungalSprouting.java
index d363b9a9ed4..66923625376 100644
--- a/Mage.Sets/src/mage/cards/f/FungalSprouting.java
+++ b/Mage.Sets/src/mage/cards/f/FungalSprouting.java
@@ -19,7 +19,7 @@ public final class FungalSprouting extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}");
// create X 1/1 green Saproling creature tokens, where X is the greatest power among creatures you control.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), new GreatestPowerAmongControlledCreaturesValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), GreatestPowerAmongControlledCreaturesValue.instance));
}
public FungalSprouting(final FungalSprouting card) {
diff --git a/Mage.Sets/src/mage/cards/g/GameOfChaos.java b/Mage.Sets/src/mage/cards/g/GameOfChaos.java
index 6c5f2f9386c..53010b05fa4 100644
--- a/Mage.Sets/src/mage/cards/g/GameOfChaos.java
+++ b/Mage.Sets/src/mage/cards/g/GameOfChaos.java
@@ -63,7 +63,7 @@ class GameOfChaosEffect extends OneShotEffect {
if (you != null && targetOpponent != null) {
boolean continueFlipping = true;
- boolean youWonFlip = you.flipCoin(game); // controller flips first
+ boolean youWonFlip = you.flipCoin(source, game, true); // controller flips first
boolean youWonLastFlip = false; // tracks if you won the flip last, negation of it means opponent won last
int lifeAmount = 1; // starts stakes with 1 life
@@ -88,7 +88,7 @@ class GameOfChaosEffect extends OneShotEffect {
if (continueFlipping) {
lifeAmount *= 2; // double the life each time
- youWonFlip = youWonLastFlip ? you.flipCoin(game) : !targetOpponent.flipCoin(game); // negate the opponent's results for proper evaluation of if you won in next iteration
+ youWonFlip = youWonLastFlip ? you.flipCoin(source, game, true) : !targetOpponent.flipCoin(source, game, true); // negate the opponent's results for proper evaluation of if you won in next iteration
}
}
diff --git a/Mage.Sets/src/mage/cards/g/GateColossus.java b/Mage.Sets/src/mage/cards/g/GateColossus.java
index 161b449d1dc..0855be3d71c 100644
--- a/Mage.Sets/src/mage/cards/g/GateColossus.java
+++ b/Mage.Sets/src/mage/cards/g/GateColossus.java
@@ -65,7 +65,7 @@ public final class GateColossus extends CardImpl {
class GateColossusCostReductionEffect extends CostModificationEffectImpl {
- static final FilterControlledPermanent filter = new FilterControlledPermanent();
+ static final FilterControlledPermanent filter = new FilterControlledPermanent("a Gate");
static {
filter.add(new SubtypePredicate(SubType.GATE));
diff --git a/Mage.Sets/src/mage/cards/g/GeralfsMasterpiece.java b/Mage.Sets/src/mage/cards/g/GeralfsMasterpiece.java
index 629686108cc..f5137eb43b0 100644
--- a/Mage.Sets/src/mage/cards/g/GeralfsMasterpiece.java
+++ b/Mage.Sets/src/mage/cards/g/GeralfsMasterpiece.java
@@ -41,7 +41,7 @@ public final class GeralfsMasterpiece extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Geralf's Masterpiece gets -1/-1 for each card in your hand.
- DynamicValue count = new SignInversionDynamicValue(new CardsInControllerHandCount());
+ DynamicValue count = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
Effect effect = new BoostSourceEffect(count, count, Duration.WhileOnBattlefield);
effect.setText("{this} gets -1/-1 for each card in your hand");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
diff --git a/Mage.Sets/src/mage/cards/g/GerrardsWisdom.java b/Mage.Sets/src/mage/cards/g/GerrardsWisdom.java
index 23e378f90a5..27694f04d26 100644
--- a/Mage.Sets/src/mage/cards/g/GerrardsWisdom.java
+++ b/Mage.Sets/src/mage/cards/g/GerrardsWisdom.java
@@ -20,7 +20,7 @@ public final class GerrardsWisdom extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}{W}");
// You gain 2 life for each card in your hand.
- this.getSpellAbility().addEffect(new GainLifeEffect(new MultipliedValue(new CardsInControllerHandCount(), 2),
+ this.getSpellAbility().addEffect(new GainLifeEffect(new MultipliedValue(CardsInControllerHandCount.instance, 2),
"You gain 2 life for each card in your hand"));
}
diff --git a/Mage.Sets/src/mage/cards/g/GhituFire.java b/Mage.Sets/src/mage/cards/g/GhituFire.java
index 4da3bde52b3..02c5fb90c3d 100644
--- a/Mage.Sets/src/mage/cards/g/GhituFire.java
+++ b/Mage.Sets/src/mage/cards/g/GhituFire.java
@@ -23,7 +23,7 @@ public final class GhituFire extends CardImpl {
public GhituFire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{R}");
- Effect effect = new DamageTargetEffect(new ManacostVariableValue());
+ Effect effect = new DamageTargetEffect(ManacostVariableValue.instance);
// You may cast Ghitu Fire as though it had flash if you pay {2} more to cast it.
Ability ability = new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl("{2}"));
ability.addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java b/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java
index 273ee197600..89b9458fc49 100644
--- a/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java
+++ b/Mage.Sets/src/mage/cards/g/GhoulcallerGisa.java
@@ -40,7 +40,7 @@ public final class GhoulcallerGisa extends CardImpl {
this.toughness = new MageInt(4);
// {B}, {tap}, Sacrifice another creature: create X 2/2 black Zombie creature tokens, where X is the sacrificed creature's power.
- DynamicValue xValue = new SacrificeCostCreaturesPower();
+ DynamicValue xValue = SacrificeCostCreaturesPower.instance;
Token zombie = new ZombieToken();
zombie.setTokenType(2);
Effect effect = new CreateTokenEffect(zombie, xValue);
diff --git a/Mage.Sets/src/mage/cards/g/GiantSlug.java b/Mage.Sets/src/mage/cards/g/GiantSlug.java
new file mode 100644
index 00000000000..8cfc8d42f3d
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GiantSlug.java
@@ -0,0 +1,104 @@
+
+package mage.cards.g;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.common.delayed.AtTheBeginOfYourNextUpkeepDelayedTriggeredAbility;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
+import mage.abilities.keyword.LandwalkAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.choices.ChoiceBasicLandType;
+import mage.choices.ChoiceImpl;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.common.FilterLandPermanent;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+
+/**
+ *
+ * @author L_J
+ */
+public final class GiantSlug extends CardImpl {
+
+ public GiantSlug(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}");
+ this.subtype.add(SubType.SLUG);
+ this.power = new MageInt(1);
+ this.toughness = new MageInt(1);
+
+ // {5}: At the beginning of your next upkeep, choose a basic land type. Giant Slug gains landwalk of the chosen type until the end of that turn.
+ AtTheBeginOfYourNextUpkeepDelayedTriggeredAbility ability = new AtTheBeginOfYourNextUpkeepDelayedTriggeredAbility(new GiantSlugEffect());
+ this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateDelayedTriggeredAbilityEffect(ability), new ManaCostsImpl("{5}")));
+ }
+
+ public GiantSlug(final GiantSlug card) {
+ super(card);
+ }
+
+ @Override
+ public GiantSlug copy() {
+ return new GiantSlug(this);
+ }
+
+}
+
+class GiantSlugEffect extends OneShotEffect {
+
+ public GiantSlugEffect() {
+ super(Outcome.AddAbility);
+ this.staticText = "At the beginning of your next upkeep, choose a basic land type. {this} gains landwalk of the chosen type until the end of that turn";
+ }
+
+ public GiantSlugEffect(final GiantSlugEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public GiantSlugEffect copy() {
+ return new GiantSlugEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (controller != null && sourcePermanent != null) {
+ ChoiceImpl choices = new ChoiceBasicLandType();
+ if (controller.choose(outcome, choices, game)) {
+ game.informPlayers(sourcePermanent.getName() + ": Chosen basic land type is " + choices.getChoice());
+ FilterLandPermanent filter = new FilterLandPermanent(choices.getChoice());
+ if (choices.getChoice().equals("Plains")) {
+ filter.add(new SubtypePredicate(SubType.PLAINS));
+ }
+ if (choices.getChoice().equals("Island")) {
+ filter.add(new SubtypePredicate(SubType.ISLAND));
+ }
+ if (choices.getChoice().equals("Swamp")) {
+ filter.add(new SubtypePredicate(SubType.SWAMP));
+ }
+ if (choices.getChoice().equals("Mountain")) {
+ filter.add(new SubtypePredicate(SubType.MOUNTAIN));
+ }
+ if (choices.getChoice().equals("Forest")) {
+ filter.add(new SubtypePredicate(SubType.FOREST));
+ }
+ Ability landwalkAbility = new LandwalkAbility(filter);
+ game.addEffect(new GainAbilitySourceEffect(landwalkAbility, Duration.EndOfTurn, false), source);
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java
index 2b0eab220b3..df6f0f4eaee 100644
--- a/Mage.Sets/src/mage/cards/g/Gigantoplasm.java
+++ b/Mage.Sets/src/mage/cards/g/Gigantoplasm.java
@@ -57,7 +57,7 @@ class GigantoplasmApplyToPermanent extends ApplyToPermanent {
@Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
- DynamicValue variableMana = new ManacostVariableValue();
+ DynamicValue variableMana = ManacostVariableValue.instance;
Effect effect = new SetPowerToughnessSourceEffect(variableMana, Duration.WhileOnBattlefield, SubLayer.SetPT_7b);
effect.setText("This creature has base power and toughness X/X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
@@ -67,7 +67,7 @@ class GigantoplasmApplyToPermanent extends ApplyToPermanent {
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
- DynamicValue variableMana = new ManacostVariableValue();
+ DynamicValue variableMana = ManacostVariableValue.instance;
Effect effect = new SetPowerToughnessSourceEffect(variableMana, Duration.WhileOnBattlefield, SubLayer.SetPT_7b);
effect.setText("This creature has base power and toughness X/X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
diff --git a/Mage.Sets/src/mage/cards/g/GlyphOfReincarnation.java b/Mage.Sets/src/mage/cards/g/GlyphOfReincarnation.java
new file mode 100644
index 00000000000..94068e41efb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/g/GlyphOfReincarnation.java
@@ -0,0 +1,129 @@
+
+package mage.cards.g;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
+import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
+import mage.abilities.condition.common.AfterCombatCondition;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.InfoEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.SubType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.StaticFilters;
+import mage.filter.common.FilterCreatureCard;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.mageobject.SubtypePredicate;
+import mage.filter.predicate.other.OwnerIdPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.Target;
+import mage.target.common.TargetCardInGraveyard;
+import mage.target.common.TargetCreaturePermanent;
+import mage.watchers.common.BlockedAttackerWatcher;
+
+/**
+ *
+ * @author L_J
+ */
+public final class GlyphOfReincarnation extends CardImpl {
+
+ private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Wall creature");
+
+ static {
+ filter.add(new SubtypePredicate(SubType.WALL));
+ }
+
+ public GlyphOfReincarnation(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{G}");
+
+ // Cast this spell only after combat.
+ this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, null, AfterCombatCondition.instance, "Cast this spell only after combat"));
+
+ // Destroy all creatures that were blocked by target Wall this turn. They can’t be regenerated. For each creature that died this way, put a creature card from the graveyard of the player who controlled that creature the last time it became blocked by that Wall onto the battlefield under its owner’s control.
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
+ this.getSpellAbility().addEffect(new GlyphOfReincarnationEffect());
+ this.getSpellAbility().addWatcher(new BlockedAttackerWatcher());
+ }
+
+ public GlyphOfReincarnation(final GlyphOfReincarnation card) {
+ super(card);
+ }
+
+ @Override
+ public GlyphOfReincarnation copy() {
+ return new GlyphOfReincarnation(this);
+ }
+}
+
+class GlyphOfReincarnationEffect extends OneShotEffect {
+
+ public GlyphOfReincarnationEffect() {
+ super(Outcome.DestroyPermanent);
+ this.staticText = "Destroy all creatures that were blocked by target Wall this turn. They can’t be regenerated. For each creature that died this way, put a creature card from the graveyard of the player who controlled that creature the last time it became blocked by that Wall onto the battlefield under its owner’s control";
+ }
+
+ public GlyphOfReincarnationEffect(final GlyphOfReincarnationEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public GlyphOfReincarnationEffect copy() {
+ return new GlyphOfReincarnationEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent targetWall = game.getPermanentOrLKIBattlefield(source.getFirstTarget());
+ if (controller != null && targetWall != null) {
+ BlockedAttackerWatcher watcher = (BlockedAttackerWatcher) game.getState().getWatchers().get(BlockedAttackerWatcher.class.getSimpleName());
+ if (watcher != null) {
+ Map destroyed = new HashMap<>();
+ for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
+ if (!creature.getId().equals(targetWall.getId())) {
+ if (watcher.creatureHasBlockedAttacker(new MageObjectReference(creature, game), new MageObjectReference(targetWall, game), game)) {
+ if (creature.destroy(source.getSourceId(), game, true)
+ && game.getState().getZone(creature.getId()) == Zone.GRAVEYARD) { // If a commander is replaced to command zone, the creature does not die
+ Player permController = game.getPlayer(creature.getControllerId());
+ if (permController != null) {
+ destroyed.put(creature.getId(), permController);
+ }
+ }
+ }
+ }
+ }
+ // For each creature that died this way, put a creature card from the graveyard of the player who controlled that creature the last time it became blocked by that Wall
+ // onto the battlefield under its owner’s control
+ for (Map.Entry entry : destroyed.entrySet()) {
+ Permanent permanent = (Permanent) game.getLastKnownInformation(entry.getKey(), Zone.BATTLEFIELD);
+ Player player = entry.getValue();
+ if (permanent != null && player != null) {
+ FilterCreatureCard filter = new FilterCreatureCard("a creature card from " + player.getName() + "'s graveyard");
+ filter.add(new OwnerIdPredicate(player.getId()));
+ Target targetCreature = new TargetCardInGraveyard(filter);
+ targetCreature.setNotTarget(true);
+ if (targetCreature.canChoose(source.getSourceId(), controller.getId(), game)
+ && controller.chooseTarget(outcome, targetCreature, source, game)) {
+ Card card = game.getCard(targetCreature.getFirstTarget());
+ if (card != null && game.getState().getZone(card.getId()) == Zone.GRAVEYARD) {
+ controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/g/GnarlidPack.java b/Mage.Sets/src/mage/cards/g/GnarlidPack.java
index 24ce6b741ac..63e7c60edb7 100644
--- a/Mage.Sets/src/mage/cards/g/GnarlidPack.java
+++ b/Mage.Sets/src/mage/cards/g/GnarlidPack.java
@@ -31,7 +31,7 @@ public final class GnarlidPack extends CardImpl {
// Gnarlid Pack enters the battlefield with a +1/+1 counter on it for each time it was kicked.
this.addAbility(new EntersBattlefieldAbility(
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new MultikickerCount(), true),
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), MultikickerCount.instance, true),
"with a +1/+1 counter on it for each time it was kicked"));
}
diff --git a/Mage.Sets/src/mage/cards/g/GoblinArchaeologist.java b/Mage.Sets/src/mage/cards/g/GoblinArchaeologist.java
index 78a1c2c1944..5b04f0b8fe5 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinArchaeologist.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinArchaeologist.java
@@ -75,7 +75,7 @@ class GoblinArchaeologistEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
- if (!player.flipCoin(game)) {
+ if (!player.flipCoin(source, game, true)) {
permanent.sacrifice(source.getSourceId(), game);
}else{
Permanent targetArtifact = game.getPermanent(source.getFirstTarget());
diff --git a/Mage.Sets/src/mage/cards/g/GoblinArtisans.java b/Mage.Sets/src/mage/cards/g/GoblinArtisans.java
index 97b830bea1a..876e1ee6dc8 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinArtisans.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinArtisans.java
@@ -78,7 +78,7 @@ class GoblinArtisansEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
controller.drawCards(1, game);
} else {
List artifacts = game.getBattlefield().getActivePermanents(new FilterControlledArtifactPermanent(), source.getControllerId(), game);
diff --git a/Mage.Sets/src/mage/cards/g/GoblinAssassin.java b/Mage.Sets/src/mage/cards/g/GoblinAssassin.java
index d872d6b038e..c94cb90e398 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinAssassin.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinAssassin.java
@@ -99,7 +99,7 @@ class GoblinAssassinTriggeredEffect extends OneShotEffect {
if (controller != null) {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
- if (player != null && !player.flipCoin(game)) {
+ if (player != null && !player.flipCoin(source, game, false)) {
TargetControlledCreaturePermanent target = new TargetControlledCreaturePermanent();
target.setNotTarget(true);
if (target.canChoose(player.getId(), game)) {
diff --git a/Mage.Sets/src/mage/cards/g/GoblinBangchuckers.java b/Mage.Sets/src/mage/cards/g/GoblinBangchuckers.java
index 2f7b0c8669f..ff27db96dae 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinBangchuckers.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinBangchuckers.java
@@ -63,7 +63,7 @@ class GoblinBangchuckersEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) {
permanent.damage(2, source.getSourceId(), game, false, true);
diff --git a/Mage.Sets/src/mage/cards/g/GoblinBomb.java b/Mage.Sets/src/mage/cards/g/GoblinBomb.java
index fdab4e863cb..a8ced2d7823 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinBomb.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinBomb.java
@@ -72,7 +72,7 @@ class GoblinBombEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
game.informPlayers("Goblin Bomb: Won flip. Put a fuse counter on Goblin Bomb.");
new AddCountersSourceEffect(CounterType.FUSE.createInstance(1)).apply(game, source);
return true;
diff --git a/Mage.Sets/src/mage/cards/g/GoblinDynamo.java b/Mage.Sets/src/mage/cards/g/GoblinDynamo.java
index 557ca2341d0..207bfd0dfb8 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinDynamo.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinDynamo.java
@@ -35,7 +35,7 @@ public final class GoblinDynamo extends CardImpl {
this.addAbility(ability);
//{X}{R}, {T}, Sacrifice Goblin Dynamo: Goblin Dynamo deals X damage to any target.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}{R}"));
+ ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{R}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/g/GoblinFestival.java b/Mage.Sets/src/mage/cards/g/GoblinFestival.java
index 9c4b52b88f2..e8e202928f3 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinFestival.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinFestival.java
@@ -68,7 +68,7 @@ class GoblinFestivalChangeControlEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (controller != null) {
- if (!controller.flipCoin(game)) {
+ if (!controller.flipCoin(source, game, true)) {
if (sourcePermanent != null) {
Target target = new TargetOpponent(true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)) {
diff --git a/Mage.Sets/src/mage/cards/g/GoblinGoliath.java b/Mage.Sets/src/mage/cards/g/GoblinGoliath.java
index b8ac5dc92cf..a6a7c02f607 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinGoliath.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinGoliath.java
@@ -34,7 +34,7 @@ public final class GoblinGoliath extends CardImpl {
this.toughness = new MageInt(4);
// When Goblin Goliath enters the battlefield, create a number of 1/1 red Goblin creature tokens equal to the number of opponents you have.
- Effect effect = new CreateTokenEffect(new GoblinToken(), new OpponentsCount());
+ Effect effect = new CreateTokenEffect(new GoblinToken(), OpponentsCount.instance);
effect.setText("create a number of 1/1 red Goblin creature tokens equal to the number of opponents you have");
this.addAbility(new EntersBattlefieldTriggeredAbility(effect));
diff --git a/Mage.Sets/src/mage/cards/g/GoblinKaboomist.java b/Mage.Sets/src/mage/cards/g/GoblinKaboomist.java
index 16db093cebf..2df939fa0da 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinKaboomist.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinKaboomist.java
@@ -70,7 +70,7 @@ class GoblinKaboomistFlipCoinEffect extends OneShotEffect {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
- if (!player.flipCoin(game)) {
+ if (!player.flipCoin(source, game, true)) {
String message = permanent.getLogName() + " deals 2 damage to itself";
game.informPlayers(message);
permanent.damage(2, source.getSourceId(), game, false, true);
diff --git a/Mage.Sets/src/mage/cards/g/GoblinKites.java b/Mage.Sets/src/mage/cards/g/GoblinKites.java
index 1f3216e8e3b..cc2e03fef09 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinKites.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinKites.java
@@ -69,7 +69,7 @@ class GoblinKitesEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
return true;
} else {
new SacrificeSourceEffect().apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/g/GoblinLyre.java b/Mage.Sets/src/mage/cards/g/GoblinLyre.java
index e06192a2a50..1626668511f 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinLyre.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinLyre.java
@@ -65,7 +65,7 @@ class GoblinLyreEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayerOrPlaneswalkerController(getTargetPointer().getFirst(game, source));
if (controller != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
int damage = new PermanentsOnBattlefieldCount(new FilterControlledCreaturePermanent()).calculate(game, source, this);
if (opponent != null) {
return game.damagePlayerOrPlaneswalker(source.getFirstTarget(), damage, source.getSourceId(), game, false, true) > 0;
diff --git a/Mage.Sets/src/mage/cards/g/GoblinOffensive.java b/Mage.Sets/src/mage/cards/g/GoblinOffensive.java
index 58cb3f35e5e..326309a34a2 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinOffensive.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinOffensive.java
@@ -19,7 +19,7 @@ public final class GoblinOffensive extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{1}{R}{R}");
// create X 1/1 red Goblin creature tokens.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new GoblinToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new GoblinToken(), ManacostVariableValue.instance));
}
public GoblinOffensive(final GoblinOffensive card) {
diff --git a/Mage.Sets/src/mage/cards/g/GoblinPsychopath.java b/Mage.Sets/src/mage/cards/g/GoblinPsychopath.java
index 611aab051c4..e2499125198 100644
--- a/Mage.Sets/src/mage/cards/g/GoblinPsychopath.java
+++ b/Mage.Sets/src/mage/cards/g/GoblinPsychopath.java
@@ -60,7 +60,7 @@ class GoblinPsychopathEffect extends ReplacementEffectImpl {
@Override
public void init(Ability source, Game game) {
- this.wonFlip = game.getPlayer(source.getControllerId()).flipCoin(game);
+ this.wonFlip = game.getPlayer(source.getControllerId()).flipCoin(source, game, true);
super.init(source, game);
}
diff --git a/Mage.Sets/src/mage/cards/g/GreatDefender.java b/Mage.Sets/src/mage/cards/g/GreatDefender.java
index 44d18590fe4..369c3eafd6f 100644
--- a/Mage.Sets/src/mage/cards/g/GreatDefender.java
+++ b/Mage.Sets/src/mage/cards/g/GreatDefender.java
@@ -22,7 +22,7 @@ public final class GreatDefender extends CardImpl {
// Target creature gets +0/+X until end of turn, where X is its converted mana cost.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true)
+ this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), TargetConvertedManaCost.instance, Duration.EndOfTurn, true)
.setText("Target creature gets +0/+X until end of turn, where X is its converted mana cost.")
);
}
diff --git a/Mage.Sets/src/mage/cards/g/GreaterGood.java b/Mage.Sets/src/mage/cards/g/GreaterGood.java
index 7aa69e4d2bf..7fc94447bc5 100644
--- a/Mage.Sets/src/mage/cards/g/GreaterGood.java
+++ b/Mage.Sets/src/mage/cards/g/GreaterGood.java
@@ -26,7 +26,7 @@ public final class GreaterGood extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{G}");
// Sacrifice a creature: Draw cards equal to the sacrificed creature's power, then discard three cards.
- Effect effect = new DrawCardSourceControllerEffect(new SacrificeCostCreaturesPower());
+ Effect effect = new DrawCardSourceControllerEffect(SacrificeCostCreaturesPower.instance);
effect.setText("Draw cards equal to the sacrificed creature's power");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect,
new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
diff --git a/Mage.Sets/src/mage/cards/g/GreelMindRaker.java b/Mage.Sets/src/mage/cards/g/GreelMindRaker.java
index f3543a1950d..bc79a60e01e 100644
--- a/Mage.Sets/src/mage/cards/g/GreelMindRaker.java
+++ b/Mage.Sets/src/mage/cards/g/GreelMindRaker.java
@@ -36,7 +36,7 @@ public final class GreelMindRaker extends CardImpl {
this.toughness = new MageInt(3);
// {X}{B}, {tap}, Discard two cards: Target player discards X cards at random.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DiscardTargetEffect(new ManacostVariableValue(), true), new ManaCostsImpl("{X}{B}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DiscardTargetEffect(ManacostVariableValue.instance, true), new ManaCostsImpl("{X}{B}"));
ability.addCost(new TapSourceCost());
ability.addCost(new DiscardTargetCost(new TargetCardInHand(2, new FilterCard())));
ability.addTarget(new TargetPlayer());
diff --git a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java
index d0bf8cdfc0b..9669605db22 100644
--- a/Mage.Sets/src/mage/cards/g/GreenManaBattery.java
+++ b/Mage.Sets/src/mage/cards/g/GreenManaBattery.java
@@ -36,7 +36,7 @@ public final class GreenManaBattery extends CardImpl {
// {tap}, Remove any number of charge counters from Green Mana Battery: Add {G}, then add an additional {G} for each charge counter removed this way.
ability = new DynamicManaAbility(
Mana.GreenMana(1),
- new IntPlusDynamicValue(1, new RemovedCountersForCostValue()),
+ new IntPlusDynamicValue(1, RemovedCountersForCostValue.instance),
new TapSourceCost(),
"Add {G}, then add {G} for each charge counter removed this way",
true, new CountersSourceCount(CounterType.CHARGE));
diff --git a/Mage.Sets/src/mage/cards/g/GrimStrider.java b/Mage.Sets/src/mage/cards/g/GrimStrider.java
index 52027151678..816259aad66 100644
--- a/Mage.Sets/src/mage/cards/g/GrimStrider.java
+++ b/Mage.Sets/src/mage/cards/g/GrimStrider.java
@@ -29,7 +29,7 @@ public final class GrimStrider extends CardImpl {
this.toughness = new MageInt(6);
// Grim Strider gets -1/-1 for each card in your hand.
- DynamicValue count = new SignInversionDynamicValue(new CardsInControllerHandCount());
+ DynamicValue count = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
Effect effect = new BoostSourceEffect(count, count, Duration.WhileOnBattlefield);
effect.setText("{this} gets -1/-1 for each card in your hand");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
diff --git a/Mage.Sets/src/mage/cards/g/GrinningTotem.java b/Mage.Sets/src/mage/cards/g/GrinningTotem.java
index fef1f9047d8..326ad8c51c4 100644
--- a/Mage.Sets/src/mage/cards/g/GrinningTotem.java
+++ b/Mage.Sets/src/mage/cards/g/GrinningTotem.java
@@ -86,7 +86,7 @@ class GrinningTotemSearchAndExileEffect extends OneShotEffect {
Card card = targetOpponent.getLibrary().remove(targetCard.getFirstTarget(), game);
if (card != null) {
UUID exileZoneId = CardUtil.getCardExileZoneId(game, source);
- you.moveCardToExileWithInfo(card, exileZoneId, sourceObject != null ? sourceObject.getIdName() : "", source.getSourceId(), game, Zone.LIBRARY, true);
+ you.moveCardToExileWithInfo(card, exileZoneId, sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
ContinuousEffect effect = new GrinningTotemMayPlayEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/g/GuardianProject.java b/Mage.Sets/src/mage/cards/g/GuardianProject.java
index e58e8339138..fe7ac3aa846 100644
--- a/Mage.Sets/src/mage/cards/g/GuardianProject.java
+++ b/Mage.Sets/src/mage/cards/g/GuardianProject.java
@@ -19,6 +19,7 @@ import mage.filter.predicate.other.OwnerIdPredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
+import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
@@ -71,7 +72,7 @@ class GuardianProjectTriggeredAbility extends EntersBattlefieldAllTriggeredAbili
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- Permanent permanent = ((ZoneChangeEvent) event).getTarget();
+ Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
if (!filter.match(permanent, sourceId, controllerId, game)) {
return false;
}
@@ -97,7 +98,7 @@ class GuardianProjectTriggeredAbility extends EntersBattlefieldAllTriggeredAbili
if (player == null) {
return false;
}
- if (!permanent.getName().equals("")) {
+ if (!permanent.getName().isEmpty()) {
FilterCard filterCard = new FilterCard();
filterCard.add(new NamePredicate(permanent.getName()));
filterCard.add(new OwnerIdPredicate(controllerId));
diff --git a/Mage.Sets/src/mage/cards/g/GyrusWakerOfCorpses.java b/Mage.Sets/src/mage/cards/g/GyrusWakerOfCorpses.java
index b7224b44243..298ef39c257 100644
--- a/Mage.Sets/src/mage/cards/g/GyrusWakerOfCorpses.java
+++ b/Mage.Sets/src/mage/cards/g/GyrusWakerOfCorpses.java
@@ -57,7 +57,7 @@ public final class GyrusWakerOfCorpses extends CardImpl {
this.toughness = new MageInt(0);
// Gyrus, Walker of Corpses enters the battlefield with a number of +1/+1 counters on it equal to the amount of mana spent to cast it.
- Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new ManaSpentToCastCount(), true);
+ Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), ManaSpentToCastCount.instance, true);
effect.setText("with a number of +1/+1 counters on it equal to the amount of mana spent to cast it");
this.addAbility(new EntersBattlefieldAbility(effect));
diff --git a/Mage.Sets/src/mage/cards/h/HailOfArrows.java b/Mage.Sets/src/mage/cards/h/HailOfArrows.java
index 6fadd26e165..90020cd2c28 100644
--- a/Mage.Sets/src/mage/cards/h/HailOfArrows.java
+++ b/Mage.Sets/src/mage/cards/h/HailOfArrows.java
@@ -20,8 +20,8 @@ public final class HailOfArrows extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{W}");
// Hail of Arrows deals X damage divided as you choose among any number of target attacking creatures.
- this.getSpellAbility().addEffect(new DamageMultiEffect(new ManacostVariableValue()));
- this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(new ManacostVariableValue(), new FilterAttackingCreature()));
+ this.getSpellAbility().addEffect(new DamageMultiEffect(ManacostVariableValue.instance));
+ this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(ManacostVariableValue.instance, new FilterAttackingCreature()));
}
public HailOfArrows(final HailOfArrows card) {
diff --git a/Mage.Sets/src/mage/cards/h/HarvestPyre.java b/Mage.Sets/src/mage/cards/h/HarvestPyre.java
index 859ec2c1325..1c4f36caecd 100644
--- a/Mage.Sets/src/mage/cards/h/HarvestPyre.java
+++ b/Mage.Sets/src/mage/cards/h/HarvestPyre.java
@@ -26,7 +26,7 @@ public final class HarvestPyre extends CardImpl {
// Harvest Pyre deals X damage to target creature.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new DamageTargetEffect(new GetXValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(GetXValue.instance));
}
public HarvestPyre(final HarvestPyre card) {
diff --git a/Mage.Sets/src/mage/cards/h/Hatred.java b/Mage.Sets/src/mage/cards/h/Hatred.java
index fd01727fbda..1d096e1cb6a 100644
--- a/Mage.Sets/src/mage/cards/h/Hatred.java
+++ b/Mage.Sets/src/mage/cards/h/Hatred.java
@@ -26,7 +26,7 @@ public final class Hatred extends CardImpl {
this.getSpellAbility().addCost(new PayVariableLifeCost(true));
// Target creature gets +X/+0 until end of turn.
- DynamicValue xValue = new GetXValue();
+ DynamicValue xValue = GetXValue.instance;
this.getSpellAbility().addEffect(new BoostTargetEffect(xValue, new StaticValue(0), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/h/HauntingMisery.java b/Mage.Sets/src/mage/cards/h/HauntingMisery.java
index aa4f0f4de2d..a6a2d25197f 100644
--- a/Mage.Sets/src/mage/cards/h/HauntingMisery.java
+++ b/Mage.Sets/src/mage/cards/h/HauntingMisery.java
@@ -24,7 +24,7 @@ public final class HauntingMisery extends CardImpl {
this.getSpellAbility().addCost(new ExileXFromYourGraveCost(new FilterCreatureCard()));
// Haunting Misery deals X damage to target player.
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
- this.getSpellAbility().addEffect(new DamageTargetEffect(new GetXValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(GetXValue.instance));
}
public HauntingMisery(final HauntingMisery card) {
diff --git a/Mage.Sets/src/mage/cards/h/HeatRay.java b/Mage.Sets/src/mage/cards/h/HeatRay.java
index d05f13cf840..571dcae460c 100644
--- a/Mage.Sets/src/mage/cards/h/HeatRay.java
+++ b/Mage.Sets/src/mage/cards/h/HeatRay.java
@@ -19,7 +19,7 @@ public final class HeatRay extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{R}");
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/h/HeavenEarth.java b/Mage.Sets/src/mage/cards/h/HeavenEarth.java
index d823619d35c..51dad694db3 100644
--- a/Mage.Sets/src/mage/cards/h/HeavenEarth.java
+++ b/Mage.Sets/src/mage/cards/h/HeavenEarth.java
@@ -33,13 +33,13 @@ public final class HeavenEarth extends SplitCard {
// Falling
// Falling deals X damage to each creature with flying.
- getLeftHalfCard().getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), filterFlying));
+ getLeftHalfCard().getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, filterFlying));
// to
// Earth
// Earth deals X damage to each creature without flying.
getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true));
- getRightHalfCard().getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), filterWithouFlying));
+ getRightHalfCard().getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, filterWithouFlying));
}
public HeavenEarth(final HeavenEarth card) {
diff --git a/Mage.Sets/src/mage/cards/h/HelixPinnacle.java b/Mage.Sets/src/mage/cards/h/HelixPinnacle.java
index dc62fe13770..268d7f125b0 100644
--- a/Mage.Sets/src/mage/cards/h/HelixPinnacle.java
+++ b/Mage.Sets/src/mage/cards/h/HelixPinnacle.java
@@ -34,7 +34,7 @@ public final class HelixPinnacle extends CardImpl {
// {X}: Put X tower counters on Helix Pinnacle.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new AddCountersSourceEffect(CounterType.TOWER.createInstance(), new ManacostVariableValue(), true),
+ new AddCountersSourceEffect(CounterType.TOWER.createInstance(), ManacostVariableValue.instance, true),
new ManaCostsImpl("{X}")));
// At the beginning of your upkeep, if there are 100 or more tower counters on Helix Pinnacle, you win the game.
diff --git a/Mage.Sets/src/mage/cards/h/HelmOfObedience.java b/Mage.Sets/src/mage/cards/h/HelmOfObedience.java
index 4221686f3a2..bad8be25926 100644
--- a/Mage.Sets/src/mage/cards/h/HelmOfObedience.java
+++ b/Mage.Sets/src/mage/cards/h/HelmOfObedience.java
@@ -49,7 +49,7 @@ public final class HelmOfObedience extends CardImpl {
class HelmOfObedienceEffect extends OneShotEffect {
- private static final ManacostVariableValue amount = new ManacostVariableValue();
+ private static final ManacostVariableValue amount = ManacostVariableValue.instance;
public HelmOfObedienceEffect() {
super(Outcome.Detriment);
diff --git a/Mage.Sets/src/mage/cards/h/HintOfInsanity.java b/Mage.Sets/src/mage/cards/h/HintOfInsanity.java
index a8b3958af2a..1d299587214 100644
--- a/Mage.Sets/src/mage/cards/h/HintOfInsanity.java
+++ b/Mage.Sets/src/mage/cards/h/HintOfInsanity.java
@@ -22,7 +22,7 @@ public final class HintOfInsanity extends CardImpl {
public HintOfInsanity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}");
- // Target player reveals his or her hand. That player discards all nonland cards with the same name as another card in his or her hand.
+ // Target player reveals their hand. That player discards all nonland cards with the same name as another card in their hand.
this.getSpellAbility().addEffect(new HintOfInsanityEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
diff --git a/Mage.Sets/src/mage/cards/h/HollowTrees.java b/Mage.Sets/src/mage/cards/h/HollowTrees.java
index 8213814aa0d..9922ba6e365 100644
--- a/Mage.Sets/src/mage/cards/h/HollowTrees.java
+++ b/Mage.Sets/src/mage/cards/h/HollowTrees.java
@@ -44,7 +44,7 @@ public final class HollowTrees extends CardImpl {
// {tap}, Remove any number of storage counters from Hollow Trees: Add {G} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.GreenMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {G} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/h/HowlFromBeyond.java b/Mage.Sets/src/mage/cards/h/HowlFromBeyond.java
index b580479cfbf..ec2c6e9dd4a 100644
--- a/Mage.Sets/src/mage/cards/h/HowlFromBeyond.java
+++ b/Mage.Sets/src/mage/cards/h/HowlFromBeyond.java
@@ -23,7 +23,7 @@ public final class HowlFromBeyond extends CardImpl {
// Target creature gets +X/+0 until end of turn.
- this.getSpellAbility().addEffect(new BoostTargetEffect(new ManacostVariableValue(), new StaticValue(0), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(ManacostVariableValue.instance, new StaticValue(0), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java b/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java
index 2cc5bf6d79b..2cf27ec2004 100644
--- a/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java
+++ b/Mage.Sets/src/mage/cards/h/HuatliWarriorPoet.java
@@ -45,7 +45,7 @@ public final class HuatliWarriorPoet extends CardImpl {
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(3));
// +2: You gain life equal to the greatest power among creatures you control.
- this.addAbility(new LoyaltyAbility(new GainLifeEffect(new GreatestPowerAmongControlledCreaturesValue(), "You gain life equal to the greatest power among creatures you control"), 2));
+ this.addAbility(new LoyaltyAbility(new GainLifeEffect(GreatestPowerAmongControlledCreaturesValue.instance, "You gain life equal to the greatest power among creatures you control"), 2));
// 0: Create a 3/3 green Dinosaur creature token with trample.
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new DinosaurToken()), 0));
diff --git a/Mage.Sets/src/mage/cards/h/HuntToExtinction.java b/Mage.Sets/src/mage/cards/h/HuntToExtinction.java
index 33ba56f4003..772bd5dce90 100644
--- a/Mage.Sets/src/mage/cards/h/HuntToExtinction.java
+++ b/Mage.Sets/src/mage/cards/h/HuntToExtinction.java
@@ -34,10 +34,10 @@ public final class HuntToExtinction extends CardImpl {
this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent(0, 1));
// Hunt to Extinction deals X damage to each creature.
- this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), new FilterCreaturePermanent()));
+ this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, new FilterCreaturePermanent()));
// Hunt to Exctinction deals an additional X damage to each creature with a bounty counter on it.
- Effect effect = new DamageAllEffect(new ManacostVariableValue(), new FilterCreaturePermanent(filter));
+ Effect effect = new DamageAllEffect(ManacostVariableValue.instance, new FilterCreaturePermanent(filter));
effect.setText("Hunt to Exctinction deals an additional X damage to each creature with a bounty counter on it");
this.getSpellAbility().addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/h/Hurricane.java b/Mage.Sets/src/mage/cards/h/Hurricane.java
index cc1418ce236..b6630989b26 100644
--- a/Mage.Sets/src/mage/cards/h/Hurricane.java
+++ b/Mage.Sets/src/mage/cards/h/Hurricane.java
@@ -28,7 +28,7 @@ public final class Hurricane extends CardImpl {
// Hurricane deals X damage to each creature with flying and each player.
- this.getSpellAbility().addEffect(new DamageEverythingEffect(new ManacostVariableValue(), filter));
+ this.getSpellAbility().addEffect(new DamageEverythingEffect(ManacostVariableValue.instance, filter));
}
public Hurricane(final Hurricane card) {
diff --git a/Mage.Sets/src/mage/cards/i/IcatianStore.java b/Mage.Sets/src/mage/cards/i/IcatianStore.java
index 6e9aa335462..91a3dfecb24 100644
--- a/Mage.Sets/src/mage/cards/i/IcatianStore.java
+++ b/Mage.Sets/src/mage/cards/i/IcatianStore.java
@@ -44,7 +44,7 @@ public final class IcatianStore extends CardImpl {
// {tap}, Remove any number of storage counters from Icatian Store: Add {W} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.WhiteMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {W} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/i/Illuminate.java b/Mage.Sets/src/mage/cards/i/Illuminate.java
index 642379fd37b..558226bcf18 100644
--- a/Mage.Sets/src/mage/cards/i/Illuminate.java
+++ b/Mage.Sets/src/mage/cards/i/Illuminate.java
@@ -28,14 +28,14 @@ public final class Illuminate extends CardImpl {
kickerAbility.addKickerCost("{3}{U}");
this.addAbility(kickerAbility);
// Illuminate deals X damage to target creature. If Illuminate was kicked with its {2}{R} kicker, it deals X damage to that creature's controller. If Illuminate was kicked with its {3}{U} kicker, you draw X cards.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DamageTargetControllerEffect(new ManacostVariableValue()),
+ new DamageTargetControllerEffect(ManacostVariableValue.instance),
new KickedCostCondition("{2}{R}"),
"if this spell was kicked with its {2}{R} kicker, it deals X damage to that creature's controller."));
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
- new DrawCardSourceControllerEffect(new ManacostVariableValue()),
+ new DrawCardSourceControllerEffect(ManacostVariableValue.instance),
new KickedCostCondition("{3}{U}"),
" if this spell was kicked with its {3}{U} kicker, you draw X cards."));
diff --git a/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java b/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java
index 9f243cf8453..1e2ec98a84c 100644
--- a/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java
+++ b/Mage.Sets/src/mage/cards/i/ImpulsiveManeuvers.java
@@ -6,8 +6,6 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAllTriggeredAbility;
import mage.abilities.effects.PreventionEffectImpl;
-import mage.abilities.effects.common.PreventDamageBySourceEffect;
-import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -16,9 +14,7 @@ import mage.constants.SetTargetPointer;
import mage.game.Game;
import mage.game.events.DamageEvent;
import mage.game.events.GameEvent;
-import mage.game.permanent.Permanent;
import mage.filter.StaticFilters;
-import mage.filter.predicate.permanent.ControllerPredicate;
import mage.players.Player;
import mage.util.CardUtil;
@@ -61,7 +57,7 @@ class ImpulsiveManeuversEffect extends PreventionEffectImpl {
@Override
public void init(Ability source, Game game) {
- this.wonFlip = game.getPlayer(source.getControllerId()).flipCoin(game);
+ this.wonFlip = game.getPlayer(source.getControllerId()).flipCoin(source, game, true);
super.init(source, game);
}
diff --git a/Mage.Sets/src/mage/cards/i/InfusedArrows.java b/Mage.Sets/src/mage/cards/i/InfusedArrows.java
index 5975fdc4fa6..904cde89546 100644
--- a/Mage.Sets/src/mage/cards/i/InfusedArrows.java
+++ b/Mage.Sets/src/mage/cards/i/InfusedArrows.java
@@ -32,7 +32,7 @@ public final class InfusedArrows extends CardImpl {
// Sunburst
this.addAbility(new SunburstAbility(this));
// {tap}, Remove X charge counters from Infused Arrows: Target creature gets -X/-X until end of turn.
- DynamicValue value = new SignInversionDynamicValue(new RemovedCountersForCostValue());
+ DynamicValue value = new SignInversionDynamicValue(RemovedCountersForCostValue.instance);
Effect effect = new BoostTargetEffect(value, value, Duration.EndOfTurn);
effect.setText("Target creature gets -X/-X until end of turn");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/i/InnerCalmOuterStrength.java b/Mage.Sets/src/mage/cards/i/InnerCalmOuterStrength.java
index 90e6f848e8a..7dbf40bb737 100644
--- a/Mage.Sets/src/mage/cards/i/InnerCalmOuterStrength.java
+++ b/Mage.Sets/src/mage/cards/i/InnerCalmOuterStrength.java
@@ -25,7 +25,7 @@ public final class InnerCalmOuterStrength extends CardImpl {
this.subtype.add(SubType.ARCANE);
// Target creature gets +X/+X until end of turn, where X is the number of cards in your hand.
- DynamicValue xValue= new CardsInControllerHandCount();
+ DynamicValue xValue= CardsInControllerHandCount.instance;
Effect effect = new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn, true);
effect.setText("Target creature gets +X/+X until end of turn, where X is the number of cards in your hand");
this.getSpellAbility().addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/i/InnerFire.java b/Mage.Sets/src/mage/cards/i/InnerFire.java
index d7f2671f735..42a4da2dd46 100644
--- a/Mage.Sets/src/mage/cards/i/InnerFire.java
+++ b/Mage.Sets/src/mage/cards/i/InnerFire.java
@@ -20,7 +20,7 @@ public final class InnerFire extends CardImpl {
// Add {R} for each card in your hand.
- this.getSpellAbility().addEffect(new DynamicManaEffect(Mana.RedMana(1), new CardsInControllerHandCount()));
+ this.getSpellAbility().addEffect(new DynamicManaEffect(Mana.RedMana(1), CardsInControllerHandCount.instance));
}
public InnerFire(final InnerFire card) {
diff --git a/Mage.Sets/src/mage/cards/i/InsidiousDreams.java b/Mage.Sets/src/mage/cards/i/InsidiousDreams.java
index 53429733745..b163be9b12d 100644
--- a/Mage.Sets/src/mage/cards/i/InsidiousDreams.java
+++ b/Mage.Sets/src/mage/cards/i/InsidiousDreams.java
@@ -74,7 +74,7 @@ class InsidiousDreamsEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
- int amount = new GetXValue().calculate(game, source, this);
+ int amount = GetXValue.instance.calculate(game, source, this);
if (controller != null && sourceObject != null) {
TargetCardInLibrary target = new TargetCardInLibrary(0, amount, new FilterCard());
diff --git a/Mage.Sets/src/mage/cards/i/InspiredSphinx.java b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java
index f3e793d77e6..22e2f94442c 100644
--- a/Mage.Sets/src/mage/cards/i/InspiredSphinx.java
+++ b/Mage.Sets/src/mage/cards/i/InspiredSphinx.java
@@ -33,7 +33,7 @@ public final class InspiredSphinx extends CardImpl {
// When Inspired Sphinx enters the battlefield, draw cards equal to the number of opponents you have.
this.addAbility(new EntersBattlefieldTriggeredAbility(
- new DrawCardSourceControllerEffect(new OpponentsCount()).setText("draw cards equal to the number of opponents you have")
+ new DrawCardSourceControllerEffect(OpponentsCount.instance).setText("draw cards equal to the number of opponents you have")
));
// {3}{U}: Create a colorless 1/1 Thopter artifact creature token with flying.
diff --git a/Mage.Sets/src/mage/cards/i/InvokeTheFiremind.java b/Mage.Sets/src/mage/cards/i/InvokeTheFiremind.java
index 9e74d88bb52..a61d8a4d1f8 100644
--- a/Mage.Sets/src/mage/cards/i/InvokeTheFiremind.java
+++ b/Mage.Sets/src/mage/cards/i/InvokeTheFiremind.java
@@ -21,9 +21,9 @@ public final class InvokeTheFiremind extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}{U}{R}");
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(ManacostVariableValue.instance));
Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ mode.addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
mode.addTarget(new TargetAnyTarget());
this.getSpellAbility().addMode(mode);
}
diff --git a/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java b/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java
index f3226b55642..e895731ea58 100644
--- a/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java
+++ b/Mage.Sets/src/mage/cards/j/JaradGolgariLichLord.java
@@ -53,7 +53,7 @@ public final class JaradGolgariLichLord extends CardImpl {
this.addAbility(ability);
// {1}{B}{G}, Sacrifice another creature: Each opponent loses life equal to the sacrificed creature's power.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(new SacrificeCostCreaturesPower()), new ManaCostsImpl("{1}{B}{G}"));
+ ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LoseLifeOpponentsEffect(SacrificeCostCreaturesPower.instance), new ManaCostsImpl("{1}{B}{G}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, false)));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/j/JayasImmolatingInferno.java b/Mage.Sets/src/mage/cards/j/JayasImmolatingInferno.java
index b1e6320f946..7f04db05596 100644
--- a/Mage.Sets/src/mage/cards/j/JayasImmolatingInferno.java
+++ b/Mage.Sets/src/mage/cards/j/JayasImmolatingInferno.java
@@ -25,7 +25,7 @@ public final class JayasImmolatingInferno extends CardImpl {
this.addAbility(new LegendarySpellAbility());
// Jaya's Immolating Inferno deals X damage to each of up to three targets.
- Effect effect = new DamageTargetEffect(new ManacostVariableValue());
+ Effect effect = new DamageTargetEffect(ManacostVariableValue.instance);
effect.setText("{this} deals X damage to each of up to three targets");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAnyTarget(1, 3));
diff --git a/Mage.Sets/src/mage/cards/j/JiwariTheEarthAflame.java b/Mage.Sets/src/mage/cards/j/JiwariTheEarthAflame.java
index fb3d834a8e4..e72e7debbfe 100644
--- a/Mage.Sets/src/mage/cards/j/JiwariTheEarthAflame.java
+++ b/Mage.Sets/src/mage/cards/j/JiwariTheEarthAflame.java
@@ -44,13 +44,13 @@ public final class JiwariTheEarthAflame extends CardImpl {
this.toughness = new MageInt(3);
// {X}{R}, {tap}: Jiwari, the Earth Aflame deals X damage to target creature without flying.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}{R}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{R}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
// Channel - {X}{R}{R}{R}, Discard Jiwari: Jiwari deals X damage to each creature without flying.
- this.addAbility(new ChannelAbility("{X}{R}{R}{R}", new DamageAllEffect(new ManacostVariableValue(), filter)));
+ this.addAbility(new ChannelAbility("{X}{R}{R}{R}", new DamageAllEffect(ManacostVariableValue.instance, filter)));
}
public JiwariTheEarthAflame(final JiwariTheEarthAflame card) {
diff --git a/Mage.Sets/src/mage/cards/j/JoragaWarcaller.java b/Mage.Sets/src/mage/cards/j/JoragaWarcaller.java
index c7751476a84..ca2464b6589 100644
--- a/Mage.Sets/src/mage/cards/j/JoragaWarcaller.java
+++ b/Mage.Sets/src/mage/cards/j/JoragaWarcaller.java
@@ -48,7 +48,7 @@ public final class JoragaWarcaller extends CardImpl {
// Joraga Warcaller enters the battlefield with a +1/+1 counter on it for each time it was kicked.
this.addAbility(new EntersBattlefieldAbility(
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new MultikickerCount(), true),
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), MultikickerCount.instance, true),
"with a +1/+1 counter on it for each time it was kicked"));
diff --git a/Mage.Sets/src/mage/cards/j/JushiApprentice.java b/Mage.Sets/src/mage/cards/j/JushiApprentice.java
index 88ac5754ba5..c6f19a2652c 100644
--- a/Mage.Sets/src/mage/cards/j/JushiApprentice.java
+++ b/Mage.Sets/src/mage/cards/j/JushiApprentice.java
@@ -71,7 +71,7 @@ class TomoyaTheRevealer extends TokenImpl {
toughness = new MageInt(3);
// {3}{U}{U},{T} : Target player draws X cards, where X is the number of cards in your hand.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardTargetEffect(new CardsInControllerHandCount()), new ManaCostsImpl("{3}{U}{U}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardTargetEffect(CardsInControllerHandCount.instance), new ManaCostsImpl("{3}{U}{U}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/k/KaerveksTorch.java b/Mage.Sets/src/mage/cards/k/KaerveksTorch.java
index 9c299f3f2d2..f003c596253 100644
--- a/Mage.Sets/src/mage/cards/k/KaerveksTorch.java
+++ b/Mage.Sets/src/mage/cards/k/KaerveksTorch.java
@@ -34,7 +34,7 @@ public final class KaerveksTorch extends CardImpl {
// As long as Kaervek's Torch is on the stack, spells that target it cost {2} more to cast.
this.addAbility(new SimpleStaticAbility(Zone.STACK, new KaerveksTorchCostIncreaseEffect()));
// Kaervek's Torch deals X damage to any target.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/k/KagemaroFirstToSuffer.java b/Mage.Sets/src/mage/cards/k/KagemaroFirstToSuffer.java
index a8249cef2d2..06e5e8d550b 100644
--- a/Mage.Sets/src/mage/cards/k/KagemaroFirstToSuffer.java
+++ b/Mage.Sets/src/mage/cards/k/KagemaroFirstToSuffer.java
@@ -37,7 +37,7 @@ public final class KagemaroFirstToSuffer extends CardImpl {
this.power = new MageInt(0);
this.toughness = new MageInt(0);
- DynamicValue xValue = new CardsInControllerHandCount();
+ DynamicValue xValue = CardsInControllerHandCount.instance;
// Kagemaro, First to Suffer's power and toughness are each equal to the number of cards in your hand.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame)));
// {B}, Sacrifice Kagemaro: All creatures get -X/-X until end of turn, where X is the number of cards in your hand.
diff --git a/Mage.Sets/src/mage/cards/k/KagemarosClutch.java b/Mage.Sets/src/mage/cards/k/KagemarosClutch.java
index 1736f8cd3ee..679f3bfc1aa 100644
--- a/Mage.Sets/src/mage/cards/k/KagemarosClutch.java
+++ b/Mage.Sets/src/mage/cards/k/KagemarosClutch.java
@@ -40,7 +40,7 @@ public final class KagemarosClutch extends CardImpl {
this.addAbility(ability);
// Enchanted creature gets -X/-X, where X is the number of cards in your hand.
- DynamicValue xMinusValue = new SignInversionDynamicValue(new CardsInControllerHandCount());
+ DynamicValue xMinusValue = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
Effect effect = new BoostEnchantedEffect(xMinusValue, xMinusValue, Duration.WhileOnBattlefield);
effect.setText("Enchanted creature gets -X/-X, where X is the number of cards in your hand");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
diff --git a/Mage.Sets/src/mage/cards/k/KarnLiberated.java b/Mage.Sets/src/mage/cards/k/KarnLiberated.java
index 2cecf73c709..5d969273956 100644
--- a/Mage.Sets/src/mage/cards/k/KarnLiberated.java
+++ b/Mage.Sets/src/mage/cards/k/KarnLiberated.java
@@ -1,9 +1,5 @@
-
package mage.cards.k;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
@@ -11,18 +7,11 @@ import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetForSourceEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
-import mage.constants.CardType;
-import mage.constants.SubType;
-import mage.constants.Outcome;
-import mage.constants.SuperType;
-import mage.constants.Zone;
+import mage.cards.*;
+import mage.constants.*;
import mage.game.ExileZone;
import mage.game.Game;
+import mage.game.GameImpl;
import mage.game.command.Commander;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
@@ -34,8 +23,11 @@ import mage.target.TargetPlayer;
import mage.target.common.TargetCardInHand;
import mage.util.CardUtil;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
/**
- *
* @author bunchOfDevs
*/
public final class KarnLiberated extends CardImpl {
@@ -102,6 +94,9 @@ class KarnLiberatedEffect extends OneShotEffect {
}
}
game.getState().clear();
+ // default watchers init, TODO: remove all restart/init code to game
+ ((GameImpl) game).initGameDefaultWatchers();
+
for (Card card : game.getCards()) {
game.getState().addCard(card);
}
@@ -122,6 +117,7 @@ class KarnLiberatedEffect extends OneShotEffect {
}
}
}
+ ((GameImpl) game).initPlayerDefaultWatchers(player.getId());
player.init(game);
}
}
diff --git a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java
index 45373483844..922fd7146f8 100644
--- a/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java
+++ b/Mage.Sets/src/mage/cards/k/KarplusanMinotaur.java
@@ -15,6 +15,7 @@ import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
+import mage.game.events.CoinFlippedEvent;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.Target;
@@ -56,30 +57,6 @@ public final class KarplusanMinotaur extends CardImpl {
}
}
-enum KarplusanMinotaurAdjuster implements TargetAdjuster {
- instance;
-
- @Override
- public void adjustTargets(Ability ability, Game game) {
- Player controller = game.getPlayer(ability.getControllerId());
- if (controller == null) {
- return;
- }
- UUID opponentId = null;
- if (game.getOpponents(controller.getId()).size() > 1) {
- Target target = new TargetOpponent(true);
- if (controller.chooseTarget(Outcome.Neutral, target, ability, game)) {
- opponentId = target.getFirstTarget();
- }
- } else {
- opponentId = game.getOpponents(controller.getId()).iterator().next();
- }
- if (opponentId != null) {
- ability.getTargets().get(0).setTargetController(opponentId);
- }
- }
-}
-
class KarplusanMinotaurFlipWinTriggeredAbility extends TriggeredAbilityImpl {
public KarplusanMinotaurFlipWinTriggeredAbility() {
@@ -103,7 +80,10 @@ class KarplusanMinotaurFlipWinTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- return this.isControlledBy(event.getPlayerId()) && event.getFlag();
+ CoinFlippedEvent flipEvent = (CoinFlippedEvent) event;
+ return flipEvent.getPlayerId().equals(controllerId)
+ && flipEvent.isWinnable()
+ && (flipEvent.getChosen() == flipEvent.getResult());
}
@Override
@@ -136,7 +116,10 @@ class KarplusanMinotaurFlipLoseTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- return this.isControlledBy(event.getPlayerId()) && !event.getFlag();
+ CoinFlippedEvent flipEvent = (CoinFlippedEvent) event;
+ return flipEvent.getPlayerId().equals(controllerId)
+ && flipEvent.isWinnable()
+ && (flipEvent.getChosen() != flipEvent.getResult());
}
@Override
@@ -155,7 +138,7 @@ class KarplusanMinotaurCost extends CostImpl {
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
Player controller = game.getPlayer(controllerId);
if (controller != null) {
- controller.flipCoin(game);
+ controller.flipCoin(ability, game, true);
this.paid = true;
return true;
}
@@ -178,3 +161,27 @@ class KarplusanMinotaurCost extends CostImpl {
return new KarplusanMinotaurCost();
}
}
+
+enum KarplusanMinotaurAdjuster implements TargetAdjuster {
+ instance;
+
+ @Override
+ public void adjustTargets(Ability ability, Game game) {
+ Player controller = game.getPlayer(ability.getControllerId());
+ if (controller == null) {
+ return;
+ }
+ UUID opponentId = null;
+ if (game.getOpponents(controller.getId()).size() > 1) {
+ Target target = new TargetOpponent(true);
+ if (controller.chooseTarget(Outcome.Neutral, target, ability, game)) {
+ opponentId = target.getFirstTarget();
+ }
+ } else {
+ opponentId = game.getOpponents(controller.getId()).iterator().next();
+ }
+ if (opponentId != null) {
+ ability.getTargets().get(0).setTargetController(opponentId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/cards/k/KayaOrzhovUsurper.java b/Mage.Sets/src/mage/cards/k/KayaOrzhovUsurper.java
index edf600b750c..31b447b6e10 100644
--- a/Mage.Sets/src/mage/cards/k/KayaOrzhovUsurper.java
+++ b/Mage.Sets/src/mage/cards/k/KayaOrzhovUsurper.java
@@ -26,7 +26,7 @@ import java.util.UUID;
public final class KayaOrzhovUsurper extends CardImpl {
private static final FilterPermanent filter
- = new FilterNonlandPermanent("permanent with converted mana cost 1 or less");
+ = new FilterNonlandPermanent("nonland permanent with converted mana cost 1 or less");
static {
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 2));
diff --git a/Mage.Sets/src/mage/cards/k/KayasWrath.java b/Mage.Sets/src/mage/cards/k/KayasWrath.java
index e1019f9e0aa..d6e4145e909 100644
--- a/Mage.Sets/src/mage/cards/k/KayasWrath.java
+++ b/Mage.Sets/src/mage/cards/k/KayasWrath.java
@@ -59,9 +59,11 @@ class KayasWrathEffect extends OneShotEffect {
StaticFilters.FILTER_PERMANENT_CREATURE,
source.getControllerId(), source.getSourceId(), game
)) {
- boolean isMine = permanent != null && permanent.isControlledBy(source.getControllerId());
- if (permanent.destroy(source.getSourceId(), game, false) && isMine) {
- counter++;
+ if (permanent != null) {
+ boolean isMine = permanent.isControlledBy(source.getControllerId());
+ if (permanent.destroy(source.getSourceId(), game, false) && isMine) {
+ counter++;
+ }
}
}
return new GainLifeEffect(counter).apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/k/KessigWolfRun.java b/Mage.Sets/src/mage/cards/k/KessigWolfRun.java
index 87a7e9e7ddb..3dfb9a59d9f 100644
--- a/Mage.Sets/src/mage/cards/k/KessigWolfRun.java
+++ b/Mage.Sets/src/mage/cards/k/KessigWolfRun.java
@@ -33,7 +33,7 @@ public final class KessigWolfRun extends CardImpl {
// {X}{R}{G}, {T}: Target creature gets +X/+0 and gains trample until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{X}{R}{G}"));
ability.addCost(new TapSourceCost());
- ability.addEffect(new BoostTargetEffect(new ManacostVariableValue(), new StaticValue(0), Duration.EndOfTurn));
+ ability.addEffect(new BoostTargetEffect(ManacostVariableValue.instance, new StaticValue(0), Duration.EndOfTurn));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/k/KhabalGhoul.java b/Mage.Sets/src/mage/cards/k/KhabalGhoul.java
index 28fc3288234..06a0fe4e253 100644
--- a/Mage.Sets/src/mage/cards/k/KhabalGhoul.java
+++ b/Mage.Sets/src/mage/cards/k/KhabalGhoul.java
@@ -28,7 +28,7 @@ public final class KhabalGhoul extends CardImpl {
// At the beginning of each end step, put a +1/+1 counter on Khabal Ghoul for each creature that died this turn.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(),
- new CreaturesDiedThisTurnCount(), true), TargetController.ANY, false), new CreaturesDiedWatcher());
+ CreaturesDiedThisTurnCount.instance, true), TargetController.ANY, false), new CreaturesDiedWatcher());
}
public KhabalGhoul(final KhabalGhoul card) {
diff --git a/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java b/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java
index 270eaeacf41..2c5328e31ac 100644
--- a/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java
+++ b/Mage.Sets/src/mage/cards/k/KheruDreadmaw.java
@@ -37,7 +37,7 @@ public final class KheruDreadmaw extends CardImpl {
this.addAbility(DefenderAbility.getInstance());
// {1}{G}, Sacrifice another creature: You gain life equal to the sacrificed creature's toughness.
- Effect effect = new GainLifeEffect(new SacrificeCostCreaturesToughness());
+ Effect effect = new GainLifeEffect(SacrificeCostCreaturesToughness.instance);
effect.setText("You gain life equal to the sacrificed creature's toughness");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("{1}{G}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE)));
diff --git a/Mage.Sets/src/mage/cards/k/KillingWave.java b/Mage.Sets/src/mage/cards/k/KillingWave.java
index 9027d41357a..0f146aac56d 100644
--- a/Mage.Sets/src/mage/cards/k/KillingWave.java
+++ b/Mage.Sets/src/mage/cards/k/KillingWave.java
@@ -61,7 +61,7 @@ class KillingWaveEffect extends OneShotEffect {
return false;
}
- int amount = (new ManacostVariableValue()).calculate(game, source, this);
+ int amount = (ManacostVariableValue.instance).calculate(game, source, this);
if (amount > 0) {
List sacrifices = new LinkedList<>();
Map lifePaidAmounts = new HashMap<>();
diff --git a/Mage.Sets/src/mage/cards/k/KitsuneLoreweaver.java b/Mage.Sets/src/mage/cards/k/KitsuneLoreweaver.java
index 8724a8582e7..0b71aea401f 100644
--- a/Mage.Sets/src/mage/cards/k/KitsuneLoreweaver.java
+++ b/Mage.Sets/src/mage/cards/k/KitsuneLoreweaver.java
@@ -30,7 +30,7 @@ public final class KitsuneLoreweaver extends CardImpl {
this.toughness = new MageInt(1);
// {1}{W}: Kitsune Loreweaver gets +0/+X until end of turn, where X is the number of cards in your hand.
- Effect effect = new BoostSourceEffect(new StaticValue(0), new CardsInControllerHandCount(), Duration.EndOfTurn, true);
+ Effect effect = new BoostSourceEffect(new StaticValue(0), CardsInControllerHandCount.instance, Duration.EndOfTurn, true);
effect.setText("{this} gets +0/+X until end of turn, where X is the number of cards in your hand");
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}{W}")));
}
diff --git a/Mage.Sets/src/mage/cards/k/KiyomaroFirstToStand.java b/Mage.Sets/src/mage/cards/k/KiyomaroFirstToStand.java
index f352b996234..0349e3bd190 100644
--- a/Mage.Sets/src/mage/cards/k/KiyomaroFirstToStand.java
+++ b/Mage.Sets/src/mage/cards/k/KiyomaroFirstToStand.java
@@ -43,7 +43,7 @@ public final class KiyomaroFirstToStand extends CardImpl {
this.toughness = new MageInt(0);
// Kiyomaro, First to Stand's power and toughness are each equal to the number of cards in your hand.
- DynamicValue xValue= new CardsInControllerHandCount();
+ DynamicValue xValue= CardsInControllerHandCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame)));
// As long as you have four or more cards in hand, Kiyomaro has vigilance.
diff --git a/Mage.Sets/src/mage/cards/k/KnollspineInvocation.java b/Mage.Sets/src/mage/cards/k/KnollspineInvocation.java
index 7da7179e698..8b2a45c4c39 100644
--- a/Mage.Sets/src/mage/cards/k/KnollspineInvocation.java
+++ b/Mage.Sets/src/mage/cards/k/KnollspineInvocation.java
@@ -32,7 +32,7 @@ public final class KnollspineInvocation extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}{R}");
// {X}, Discard a card with converted mana cost X: Knollspine Invocation deals X damage to any target.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue(), true), new ManaCostsImpl<>("{X}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance, true), new ManaCostsImpl<>("{X}"));
ability.addCost(new DiscardTargetCost(new TargetCardInHand(filter)));
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java b/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java
index 726ead90abc..872488a84d0 100644
--- a/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java
+++ b/Mage.Sets/src/mage/cards/k/KorozdaGuildmage.java
@@ -53,7 +53,7 @@ public final class KorozdaGuildmage extends CardImpl {
this.addAbility(ability);
// {2}{B}{G}, Sacrifice a nontoken creature: create X 1/1 green Saproling creature tokens, where X is the sacrificed creature's toughness.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken(),new SacrificeCostCreaturesToughness()),new ManaCostsImpl("{2}{B}{G}"));
+ ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new SaprolingToken(),SacrificeCostCreaturesToughness.instance),new ManaCostsImpl("{2}{B}{G}"));
ability.addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(1,1,filter, true)));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/k/KrarksThumb.java b/Mage.Sets/src/mage/cards/k/KrarksThumb.java
index 3acb3bde5aa..09f0427eb2b 100644
--- a/Mage.Sets/src/mage/cards/k/KrarksThumb.java
+++ b/Mage.Sets/src/mage/cards/k/KrarksThumb.java
@@ -1,33 +1,35 @@
package mage.cards.k;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
-import mage.constants.*;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.SuperType;
import mage.game.Game;
+import mage.game.events.FlipCoinEvent;
import mage.game.events.GameEvent;
-import mage.players.Player;
-import mage.util.RandomUtil;
+
+import java.util.UUID;
/**
- *
* @author LevelX2
*/
public final class KrarksThumb extends CardImpl {
public KrarksThumb(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
addSuperType(SuperType.LEGENDARY);
// If you would flip a coin, instead flip two coins and ignore one.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new KrarksThumbEffect()));
+ this.addAbility(new SimpleStaticAbility(new KrarksThumbEffect()));
}
- public KrarksThumb(final KrarksThumb card) {
+ private KrarksThumb(final KrarksThumb card) {
super(card);
}
@@ -41,29 +43,22 @@ class KrarksThumbEffect extends ReplacementEffectImpl {
KrarksThumbEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
- staticText = "If you would flip a coin, instead flip two coins and ignore one";
+ staticText = "If you would flip a coin, instead flip two coins and ignore one.";
}
- KrarksThumbEffect(final KrarksThumbEffect effect) {
+ private KrarksThumbEffect(final KrarksThumbEffect effect) {
super(effect);
}
+ @Override
+ public KrarksThumbEffect copy() {
+ return new KrarksThumbEffect(this);
+ }
+
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
- Player player = game.getPlayer(event.getPlayerId());
- if (player != null) {
- // because second flip is ignored it may not be done by the player method
- boolean secondCoinFlip = RandomUtil.nextBoolean();
- if (!game.isSimulation()) {
- game.informPlayers("[Flip a coin] " + player.getLogName() + (secondCoinFlip ? " won (head)." : " lost (tail)."));
- }
- if (player.chooseUse(outcome, "Ignore the first coin flip?", source, game)) {
- event.setFlag(secondCoinFlip);
- game.informPlayers(player.getLogName() + " ignores the first coin flip.");
- } else {
- game.informPlayers(player.getLogName() + " ignores the second coin flip.");
- }
- }
+ FlipCoinEvent flipCoinEvent = (FlipCoinEvent) event;
+ flipCoinEvent.setFlipCount(2 * flipCoinEvent.getFlipCount());
return false;
}
@@ -81,9 +76,4 @@ class KrarksThumbEffect extends ReplacementEffectImpl {
public boolean apply(Game game, Ability source) {
return false;
}
-
- @Override
- public KrarksThumbEffect copy() {
- return new KrarksThumbEffect(this);
- }
}
diff --git a/Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java b/Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java
index 8a08d9630de..136033ed407 100644
--- a/Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java
+++ b/Mage.Sets/src/mage/cards/k/KravTheUnredeemed.java
@@ -76,7 +76,7 @@ class KravTheUnredeemedEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- int xValue = new GetXValue().calculate(game, source, this);
+ int xValue = GetXValue.instance.calculate(game, source, this);
new DrawCardTargetEffect(xValue).apply(game, source);
new GainLifeTargetEffect(xValue).apply(game, source);
new AddCountersSourceEffect(CounterType.P1P1.createInstance(xValue)).apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/k/KryShield.java b/Mage.Sets/src/mage/cards/k/KryShield.java
index 8fc55fc5dc4..eb321f215e2 100644
--- a/Mage.Sets/src/mage/cards/k/KryShield.java
+++ b/Mage.Sets/src/mage/cards/k/KryShield.java
@@ -31,7 +31,7 @@ public final class KryShield extends CardImpl {
Effect effect = new PreventDamageByTargetEffect(Duration.EndOfTurn);
effect.setText("Prevent all damage that would be dealt this turn by target creature you control");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
- ability.addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true)
+ ability.addEffect(new BoostTargetEffect(new StaticValue(0), TargetConvertedManaCost.instance, Duration.EndOfTurn, true)
.setText("That creature gets +0/+X until end of turn, where X is its converted mana cost"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetControlledCreaturePermanent());
diff --git a/Mage.Sets/src/mage/cards/l/LatullaKeldonOverseer.java b/Mage.Sets/src/mage/cards/l/LatullaKeldonOverseer.java
index 7c86ccbe4fd..30171595ff4 100644
--- a/Mage.Sets/src/mage/cards/l/LatullaKeldonOverseer.java
+++ b/Mage.Sets/src/mage/cards/l/LatullaKeldonOverseer.java
@@ -35,7 +35,7 @@ public final class LatullaKeldonOverseer extends CardImpl {
this.toughness = new MageInt(3);
// {X}{R}, {tap}, Discard two cards: Latulla, Keldon Overseer deals X damage to any target.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}{R}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{R}"));
ability.addCost(new TapSourceCost());
ability.addCost(new DiscardTargetCost(new TargetCardInHand(2, 2, new FilterCard("two cards"))));
ability.addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/l/LavaclawReaches.java b/Mage.Sets/src/mage/cards/l/LavaclawReaches.java
index e1c3f7b6fd1..9988c05f7d4 100644
--- a/Mage.Sets/src/mage/cards/l/LavaclawReaches.java
+++ b/Mage.Sets/src/mage/cards/l/LavaclawReaches.java
@@ -60,7 +60,7 @@ class LavaclawReachesToken extends TokenImpl {
color.setBlack(true);
power = new MageInt(2);
toughness = new MageInt(2);
- addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(new ManacostVariableValue(), new StaticValue(0), Duration.EndOfTurn), new ManaCostsImpl("{X}")));
+ addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(ManacostVariableValue.instance, new StaticValue(0), Duration.EndOfTurn), new ManaCostsImpl("{X}")));
}
public LavaclawReachesToken(final LavaclawReachesToken token) {
super(token);
diff --git a/Mage.Sets/src/mage/cards/l/Lavalanche.java b/Mage.Sets/src/mage/cards/l/Lavalanche.java
index bbb74ff71da..231134ea215 100644
--- a/Mage.Sets/src/mage/cards/l/Lavalanche.java
+++ b/Mage.Sets/src/mage/cards/l/Lavalanche.java
@@ -29,7 +29,7 @@ public final class Lavalanche extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{R}{G}");
// Lavalanche deals X damage to target player and each creature he or she controls.
- this.getSpellAbility().addEffect(new LavalancheEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new LavalancheEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
}
diff --git a/Mage.Sets/src/mage/cards/l/LesserWerewolf.java b/Mage.Sets/src/mage/cards/l/LesserWerewolf.java
new file mode 100644
index 00000000000..84d836b950c
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/l/LesserWerewolf.java
@@ -0,0 +1,93 @@
+
+package mage.cards.l;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.condition.common.IsStepCondition;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.decorator.ConditionalActivatedAbility;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.BoostSourceEffect;
+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.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import mage.counters.BoostCounter;
+import mage.filter.common.FilterCreaturePermanent;
+import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.BlockedByIdPredicate;
+import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public final class LesserWerewolf extends CardImpl {
+
+ public LesserWerewolf(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
+ this.subtype.add(SubType.WEREWOLF);
+ this.power = new MageInt(2);
+ this.toughness = new MageInt(4);
+
+ // {B}: If Lesser Werewolf’s power is 1 or more, it gets -1/-0 until end of turn and put a -0/-1 counter on target creature blocking or blocked by Lesser Werewolf. Activate this ability only during the declare blockers step.
+ Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD, new LesserWerewolfEffect(), new ManaCostsImpl("{B}"), new IsStepCondition(PhaseStep.DECLARE_BLOCKERS, false));
+ FilterCreaturePermanent filter = new FilterCreaturePermanent("creature blocking or blocked by Lesser Werewolf");
+ filter.add(Predicates.or(new BlockedByIdPredicate(this.getId()),
+ new BlockingAttackerIdPredicate(this.getId())));
+ ability.addTarget(new TargetCreaturePermanent(filter));
+ this.addAbility(ability);
+
+ }
+
+ public LesserWerewolf(final LesserWerewolf card) {
+ super(card);
+ }
+
+ @Override
+ public LesserWerewolf copy() {
+ return new LesserWerewolf(this);
+ }
+}
+
+class LesserWerewolfEffect extends OneShotEffect {
+
+ public LesserWerewolfEffect() {
+ super(Outcome.Detriment);
+ this.staticText = "If {this}’s power is 1 or more, it gets -1/-0 until end of turn and put a -0/-1 counter on target creature blocking or blocked by {this}";
+ }
+
+ public LesserWerewolfEffect(final LesserWerewolfEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public LesserWerewolfEffect copy() {
+ return new LesserWerewolfEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ Permanent targetPermanent = game.getPermanentOrLKIBattlefield(targetPointer.getFirst(game, source));
+ if (controller != null && sourcePermanent != null && targetPermanent != null) {
+ if (sourcePermanent.getPower().getValue() >= 1) {
+ game.addEffect(new BoostSourceEffect(-1, 0, Duration.EndOfTurn), source);
+ new AddCountersTargetEffect(new BoostCounter(0, -1), outcome).apply(game, source);
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/l/Lich.java b/Mage.Sets/src/mage/cards/l/Lich.java
index a04b2c81a1a..e77d1031f57 100644
--- a/Mage.Sets/src/mage/cards/l/Lich.java
+++ b/Mage.Sets/src/mage/cards/l/Lich.java
@@ -41,7 +41,7 @@ public final class Lich extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{B}{B}{B}{B}");
// As Lich enters the battlefield, you lose life equal to your life total.
- this.addAbility(new EntersBattlefieldAbility(new LoseLifeSourceControllerEffect(new ControllerLifeCount()), null, "As Lich enters the battlefield, you lose life equal to your life total.", null));
+ this.addAbility(new EntersBattlefieldAbility(new LoseLifeSourceControllerEffect(ControllerLifeCount.instance), null, "As Lich enters the battlefield, you lose life equal to your life total.", null));
// You don't lose the game for having 0 or less life.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DontLoseByZeroOrLessLifeEffect(Duration.WhileOnBattlefield)));
diff --git a/Mage.Sets/src/mage/cards/l/LifecraftAwakening.java b/Mage.Sets/src/mage/cards/l/LifecraftAwakening.java
index 7aabdf3f900..a6ff60b5017 100644
--- a/Mage.Sets/src/mage/cards/l/LifecraftAwakening.java
+++ b/Mage.Sets/src/mage/cards/l/LifecraftAwakening.java
@@ -39,7 +39,7 @@ public final class LifecraftAwakening extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{G}");
// Put X +1/+1 counters on target artifact you control. If it isn't a creature or Vehicle, it becomes a 0/0 Construct artifact creature.
- ManacostVariableValue manaX = new ManacostVariableValue();
+ ManacostVariableValue manaX = ManacostVariableValue.instance;
getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.P1P1.createInstance(), manaX));
getSpellAbility().addTarget(new TargetArtifactPermanent(filter));
getSpellAbility().addEffect(new LifecraftAwakeningEffect());
diff --git a/Mage.Sets/src/mage/cards/l/LightkeeperOfEmeria.java b/Mage.Sets/src/mage/cards/l/LightkeeperOfEmeria.java
index 05cad39bf7e..2b3be08030a 100644
--- a/Mage.Sets/src/mage/cards/l/LightkeeperOfEmeria.java
+++ b/Mage.Sets/src/mage/cards/l/LightkeeperOfEmeria.java
@@ -35,7 +35,7 @@ public final class LightkeeperOfEmeria extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// When Lightkeeper of Emeria enters the battlefield, you gain 2 life for each time it was kicked.
- Effect effect = new GainLifeEffect(new MultipliedValue(new MultikickerCount(), 2));
+ Effect effect = new GainLifeEffect(new MultipliedValue(MultikickerCount.instance, 2));
effect.setText("you gain 2 life for each time it was kicked");
this.addAbility(new EntersBattlefieldTriggeredAbility(effect, false));
}
diff --git a/Mage.Sets/src/mage/cards/l/LiquidFire.java b/Mage.Sets/src/mage/cards/l/LiquidFire.java
index 04b40d14139..32737ce082b 100644
--- a/Mage.Sets/src/mage/cards/l/LiquidFire.java
+++ b/Mage.Sets/src/mage/cards/l/LiquidFire.java
@@ -30,7 +30,7 @@ public final class LiquidFire extends CardImpl {
// As an additional cost to cast Liquid Fire, choose a number between 0 and 5.
this.getSpellAbility().addCost(new LiquidFireCost());
// Liquid Fire deals X damage to target creature and 5 minus X damage to that creature's controller, where X is the chosen number.
- DynamicValue choiceValue = new GetXValue();
+ DynamicValue choiceValue = GetXValue.instance;
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new LiquidFireEffect(choiceValue));
diff --git a/Mage.Sets/src/mage/cards/l/LogicKnot.java b/Mage.Sets/src/mage/cards/l/LogicKnot.java
index 49b6eaff913..daa6d03ee13 100644
--- a/Mage.Sets/src/mage/cards/l/LogicKnot.java
+++ b/Mage.Sets/src/mage/cards/l/LogicKnot.java
@@ -24,7 +24,7 @@ public final class LogicKnot extends CardImpl {
this.addAbility(new DelveAbility());
// Counter target spell unless its controller pays {X}.
- this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetSpell());
}
diff --git a/Mage.Sets/src/mage/cards/l/LumberingBattlement.java b/Mage.Sets/src/mage/cards/l/LumberingBattlement.java
index 4b08d51a6d6..38f3c1022c5 100644
--- a/Mage.Sets/src/mage/cards/l/LumberingBattlement.java
+++ b/Mage.Sets/src/mage/cards/l/LumberingBattlement.java
@@ -11,7 +11,9 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
-import mage.cards.*;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
@@ -19,7 +21,9 @@ import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
+import mage.filter.predicate.permanent.AnotherPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
+import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@@ -27,6 +31,8 @@ import mage.target.Target;
import mage.target.TargetPermanent;
import mage.util.CardUtil;
+import java.util.HashSet;
+import java.util.Set;
import java.util.UUID;
import static mage.constants.Outcome.Benefit;
@@ -53,8 +59,8 @@ public final class LumberingBattlement extends CardImpl {
// Lumbering Battlement gets +2/+2 for each card exiled with it.
this.addAbility(new SimpleStaticAbility(new BoostSourceEffect(
- LumberinBattlementValue.instance,
- LumberinBattlementValue.instance,
+ LumberingBattlementValue.instance,
+ LumberingBattlementValue.instance,
Duration.WhileOnBattlefield
).setText("{this} gets +2/+2 for each card exiled with it.")));
}
@@ -72,10 +78,11 @@ public final class LumberingBattlement extends CardImpl {
class LumberingBattlementEffect extends OneShotEffect {
private static final FilterPermanent filter
- = new FilterControlledCreaturePermanent("nontoken creatures");
+ = new FilterControlledCreaturePermanent("other nontoken creatures");
static {
filter.add(Predicates.not(TokenPredicate.instance));
+ filter.add(AnotherPredicate.instance);
}
LumberingBattlementEffect() {
@@ -103,7 +110,7 @@ class LumberingBattlementEffect extends OneShotEffect {
if (!player.choose(Outcome.Neutral, target, source.getSourceId(), game)) {
return false;
}
- Cards cards = new CardsImpl();
+ Set cards = new HashSet();
for (UUID targetId : target.getTargets()) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
@@ -111,23 +118,32 @@ class LumberingBattlementEffect extends OneShotEffect {
}
}
return player.moveCardsToExile(
- cards.getCards(game), source, game, true,
- CardUtil.getExileZoneId(
- game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()
- ), sourcePerm.getIdName()
+ cards, source, game, true,
+ CardUtil.getCardExileZoneId(game, source), sourcePerm.getIdName()
);
}
}
-enum LumberinBattlementValue implements DynamicValue {
+enum LumberingBattlementValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
+ if (sourceAbility == null) {
+ return 0;
+ }
+ ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(
+ game, sourceAbility.getSourceId(),
+ sourceAbility.getSourceObjectZoneChangeCounter()
+ ));
+ if (exileZone == null) {
+ exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, sourceAbility));
+ }
+ if (exileZone == null) {
+ return 0;
+ }
int counter = 0;
- for (UUID cardId : game.getExile().getExileZone(CardUtil.getExileZoneId(
- game, sourceAbility.getSourceId(), sourceAbility.getSourceObjectZoneChangeCounter()
- ))) {
+ for (UUID cardId : exileZone) {
Card card = game.getCard(cardId);
if (card != null) {
counter++;
diff --git a/Mage.Sets/src/mage/cards/m/MageRingNetwork.java b/Mage.Sets/src/mage/cards/m/MageRingNetwork.java
index 3edaf7279c8..21506a8beca 100644
--- a/Mage.Sets/src/mage/cards/m/MageRingNetwork.java
+++ b/Mage.Sets/src/mage/cards/m/MageRingNetwork.java
@@ -39,7 +39,7 @@ public final class MageRingNetwork extends CardImpl {
// {T}, Remove any number of storage counters from Mage-Ring Network: Add {C} for each storage counter removed this way.
ability = new DynamicManaAbility(
Mana.ColorlessMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {C} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/m/Magmaquake.java b/Mage.Sets/src/mage/cards/m/Magmaquake.java
index 98e00ba168f..4522a2d70b7 100644
--- a/Mage.Sets/src/mage/cards/m/Magmaquake.java
+++ b/Mage.Sets/src/mage/cards/m/Magmaquake.java
@@ -34,7 +34,7 @@ public final class Magmaquake extends CardImpl {
// Magmaquake deals X damage to each creature without flying and each planeswalker.
- this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), filter));
+ this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, filter));
}
public Magmaquake(final Magmaquake card) {
diff --git a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java
index 9f05a441e61..b75bb70a686 100644
--- a/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java
+++ b/Mage.Sets/src/mage/cards/m/MaliciousAdvice.java
@@ -30,7 +30,7 @@ public final class MaliciousAdvice extends CardImpl {
Effect effect = new TapTargetEffect();
effect.setText("X target artifacts, creatures, and/or lands.");
this.getSpellAbility().addEffect(effect);
- this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(ManacostVariableValue.instance));
this.getSpellAbility().setTargetAdjuster(MaliciousAdviceAdjuster.instance);
}
diff --git a/Mage.Sets/src/mage/cards/m/Malignus.java b/Mage.Sets/src/mage/cards/m/Malignus.java
index 7db53127549..156ede533cf 100644
--- a/Mage.Sets/src/mage/cards/m/Malignus.java
+++ b/Mage.Sets/src/mage/cards/m/Malignus.java
@@ -74,7 +74,7 @@ class HighestLifeTotalAmongOpponentsCount implements DynamicValue {
@Override
public DynamicValue copy() {
- return new CardsInControllerHandCount();
+ return CardsInControllerHandCount.instance;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/m/ManaClash.java b/Mage.Sets/src/mage/cards/m/ManaClash.java
index 4c8fe0ee5c4..af3dba45bca 100644
--- a/Mage.Sets/src/mage/cards/m/ManaClash.java
+++ b/Mage.Sets/src/mage/cards/m/ManaClash.java
@@ -62,8 +62,8 @@ class ManaClashEffect extends OneShotEffect {
if (!targetOpponent.canRespond() || !controller.canRespond()) {
return false;
}
- boolean controllerFlip = controller.flipCoin(game);
- boolean opponentFlip = targetOpponent.flipCoin(game);
+ boolean controllerFlip = controller.flipCoin(source, game, false);
+ boolean opponentFlip = targetOpponent.flipCoin(source, game, false);
if (controllerFlip && opponentFlip) {
bothHeads = true;
}
diff --git a/Mage.Sets/src/mage/cards/m/ManaCrypt.java b/Mage.Sets/src/mage/cards/m/ManaCrypt.java
index 90535e37a6c..51c09adc938 100644
--- a/Mage.Sets/src/mage/cards/m/ManaCrypt.java
+++ b/Mage.Sets/src/mage/cards/m/ManaCrypt.java
@@ -58,7 +58,7 @@ class ManaCryptEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- if (!player.flipCoin(game)) {
+ if (!player.flipCoin(source, game, true)) {
player.damage(3, source.getSourceId(), game, false, true);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/m/ManaScrew.java b/Mage.Sets/src/mage/cards/m/ManaScrew.java
index f2228b428bc..24b3514c9ee 100644
--- a/Mage.Sets/src/mage/cards/m/ManaScrew.java
+++ b/Mage.Sets/src/mage/cards/m/ManaScrew.java
@@ -88,7 +88,7 @@ class ManaScrewEffect extends BasicManaEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
- if (player != null && player.flipCoin(game)) {
+ if (player != null && player.flipCoin(source, game, true)) {
player.getManaPool().addMana(getMana(game, source), game, source);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/m/MarathWillOfTheWild.java b/Mage.Sets/src/mage/cards/m/MarathWillOfTheWild.java
index 7d5a219f10c..866ab25de72 100644
--- a/Mage.Sets/src/mage/cards/m/MarathWillOfTheWild.java
+++ b/Mage.Sets/src/mage/cards/m/MarathWillOfTheWild.java
@@ -52,12 +52,12 @@ public final class MarathWillOfTheWild extends CardImpl {
this.toughness = new MageInt(0);
// Marath, Will of the Wild enters the battlefield with a number of +1/+1 counters on it equal to the amount of mana spent to cast it.
- Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new ManaSpentToCastCount(), true);
+ Effect effect = new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), ManaSpentToCastCount.instance, true);
effect.setText("with a number of +1/+1 counters on it equal to the amount of mana spent to cast it");
this.addAbility(new EntersBattlefieldAbility(effect));
// {X}, Remove X +1/+1 counters from Marath: Choose one - Put X +1/+1 counters on target creature;
- effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), new ManacostVariableValue());
+ effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(0), ManacostVariableValue.instance);
effect.setText("Put X +1/+1 counters on target creature");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new MarathWillOfTheWildRemoveCountersCost());
@@ -65,7 +65,7 @@ public final class MarathWillOfTheWild extends CardImpl {
// or Marath deals X damage to any target;
Mode mode = new Mode();
- mode.addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ mode.addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
mode.addTarget(new TargetAnyTarget());
ability.addMode(mode);
@@ -132,7 +132,7 @@ class MarathWillOfTheWildCreateTokenEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- int amount = new ManacostVariableValue().calculate(game, source, this);
+ int amount = ManacostVariableValue.instance.calculate(game, source, this);
Token token = new MarathWillOfTheWildElementalToken();
token.getPower().modifyBaseValue(amount);
token.getToughness().modifyBaseValue(amount);
@@ -165,7 +165,7 @@ class MarathWillOfTheWildRemoveCountersCost extends CostImpl {
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
- int amount = new ManacostVariableValue().calculate(game, ability, null);
+ int amount = ManacostVariableValue.instance.calculate(game, ability, null);
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.getCounters(game).getCount(CounterType.P1P1) >= amount) {
permanent.removeCounters(CounterType.P1P1.getName(), amount, game);
diff --git a/Mage.Sets/src/mage/cards/m/MarchOfTheMultitudes.java b/Mage.Sets/src/mage/cards/m/MarchOfTheMultitudes.java
index b15c38640f8..1f6f9fe5a4d 100644
--- a/Mage.Sets/src/mage/cards/m/MarchOfTheMultitudes.java
+++ b/Mage.Sets/src/mage/cards/m/MarchOfTheMultitudes.java
@@ -24,7 +24,7 @@ public final class MarchOfTheMultitudes extends CardImpl {
// Create X 1/1 white Soldier creature tokens with lifelink.
this.getSpellAbility().addEffect(new CreateTokenEffect(
new SoldierLifelinkToken(),
- new ManacostVariableValue()
+ ManacostVariableValue.instance
));
}
diff --git a/Mage.Sets/src/mage/cards/m/Maro.java b/Mage.Sets/src/mage/cards/m/Maro.java
index e611397388c..68bd5c1faf2 100644
--- a/Mage.Sets/src/mage/cards/m/Maro.java
+++ b/Mage.Sets/src/mage/cards/m/Maro.java
@@ -27,7 +27,7 @@ public final class Maro extends CardImpl {
this.toughness = new MageInt(0);
// Maro's power and toughness are each equal to the number of cards in your hand.
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInControllerHandCount(), Duration.EndOfGame)));
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(CardsInControllerHandCount.instance, Duration.EndOfGame)));
}
public Maro(final Maro card) {
diff --git a/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java b/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java
index 7ed4417d513..9fc03f6d555 100644
--- a/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java
+++ b/Mage.Sets/src/mage/cards/m/MarshalsAnthem.java
@@ -65,7 +65,7 @@ enum MarshalsAnthemAdjuster implements TargetAdjuster {
@Override
public void adjustTargets(Ability ability, Game game) {
ability.getTargets().clear();
- int numbTargets = new MultikickerCount().calculate(game, ability, null);
+ int numbTargets = MultikickerCount.instance.calculate(game, ability, null);
if (numbTargets > 0) {
ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, filter));
}
diff --git a/Mage.Sets/src/mage/cards/m/MartyrOfAshes.java b/Mage.Sets/src/mage/cards/m/MartyrOfAshes.java
index 9a99586b08a..c43c8a45e2d 100644
--- a/Mage.Sets/src/mage/cards/m/MartyrOfAshes.java
+++ b/Mage.Sets/src/mage/cards/m/MartyrOfAshes.java
@@ -48,7 +48,7 @@ public final class MartyrOfAshes extends CardImpl {
this.toughness = new MageInt(1);
// {2}, Reveal X red cards from your hand, Sacrifice Martyr of Ashes: Martyr of Ashes deals X damage to each creature without flying.
- Effect effect = new DamageAllEffect(new RevealTargetFromHandCostCount(), filterCreature);
+ Effect effect = new DamageAllEffect(RevealTargetFromHandCostCount.instance, filterCreature);
effect.setText("Martyr of Ashes deals X damage to each creature without flying.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, Integer.MAX_VALUE, filterHand)));
diff --git a/Mage.Sets/src/mage/cards/m/MartyrOfFrost.java b/Mage.Sets/src/mage/cards/m/MartyrOfFrost.java
index 44e48efe62c..5ec56acb5ae 100644
--- a/Mage.Sets/src/mage/cards/m/MartyrOfFrost.java
+++ b/Mage.Sets/src/mage/cards/m/MartyrOfFrost.java
@@ -42,7 +42,7 @@ public final class MartyrOfFrost extends CardImpl {
this.toughness = new MageInt(1);
// {2}, Reveal X blue cards from your hand, Sacrifice Martyr of Frost: Counter target spell unless its controller pays {X}.
- Effect effect = new CounterUnlessPaysEffect(new RevealTargetFromHandCostCount());
+ Effect effect = new CounterUnlessPaysEffect(RevealTargetFromHandCostCount.instance);
effect.setText("Counter target spell unless its controller pays {X}.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, Integer.MAX_VALUE, filter)));
diff --git a/Mage.Sets/src/mage/cards/m/MartyrOfSands.java b/Mage.Sets/src/mage/cards/m/MartyrOfSands.java
index 5076f87b2fb..d6c7baa4635 100644
--- a/Mage.Sets/src/mage/cards/m/MartyrOfSands.java
+++ b/Mage.Sets/src/mage/cards/m/MartyrOfSands.java
@@ -43,7 +43,7 @@ public final class MartyrOfSands extends CardImpl {
this.toughness = new MageInt(1);
// {1}, Reveal X white cards from your hand, Sacrifice Martyr of Sands: You gain three times X life.
- Effect effect = new GainLifeEffect(new MultipliedValue(new RevealTargetFromHandCostCount(), 3));
+ Effect effect = new GainLifeEffect(new MultipliedValue(RevealTargetFromHandCostCount.instance, 3));
effect.setText("You gain three times X life.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}"));
ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, Integer.MAX_VALUE, filter)));
diff --git a/Mage.Sets/src/mage/cards/m/MartyrOfSpores.java b/Mage.Sets/src/mage/cards/m/MartyrOfSpores.java
index 160441a376f..4bb1335d443 100644
--- a/Mage.Sets/src/mage/cards/m/MartyrOfSpores.java
+++ b/Mage.Sets/src/mage/cards/m/MartyrOfSpores.java
@@ -43,7 +43,7 @@ public final class MartyrOfSpores extends CardImpl {
this.toughness = new MageInt(1);
// {1}, Reveal X green cards from your hand, Sacrifice Martyr of Spores: Target creature gets +X/+X until end of turn.
- Effect effect = new BoostTargetEffect(new RevealTargetFromHandCostCount(), new RevealTargetFromHandCostCount(), Duration.EndOfTurn, true);
+ Effect effect = new BoostTargetEffect(RevealTargetFromHandCostCount.instance, RevealTargetFromHandCostCount.instance, Duration.EndOfTurn, true);
effect.setText("Target creature gets +X/+X until end of turn.");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(1));
ability.addCost(new RevealTargetFromHandCost(new TargetCardInHand(0, Integer.MAX_VALUE, filter)));
diff --git a/Mage.Sets/src/mage/cards/m/MasterTheWay.java b/Mage.Sets/src/mage/cards/m/MasterTheWay.java
index 9325793aa83..e3fc9243cf4 100644
--- a/Mage.Sets/src/mage/cards/m/MasterTheWay.java
+++ b/Mage.Sets/src/mage/cards/m/MasterTheWay.java
@@ -23,7 +23,7 @@ public final class MasterTheWay extends CardImpl {
// Draw a card. Master the Way deals damage to any target equal to the number of cards in your hand.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
- Effect effect = new DamageTargetEffect(new CardsInControllerHandCount());
+ Effect effect = new DamageTargetEffect(CardsInControllerHandCount.instance);
effect.setText("{this} deals damage to any target equal to the number of cards in your hand");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/m/MasumaroFirstToLive.java b/Mage.Sets/src/mage/cards/m/MasumaroFirstToLive.java
index e7721a06a81..3e67265849d 100644
--- a/Mage.Sets/src/mage/cards/m/MasumaroFirstToLive.java
+++ b/Mage.Sets/src/mage/cards/m/MasumaroFirstToLive.java
@@ -32,7 +32,7 @@ public final class MasumaroFirstToLive extends CardImpl {
this.toughness = new MageInt(0);
// Masumaro, First to Live's power and toughness are each equal to twice the number of cards in your hand.
- DynamicValue xValue= new MultipliedValue(new CardsInControllerHandCount(), 2);
+ DynamicValue xValue= new MultipliedValue(CardsInControllerHandCount.instance, 2);
Effect effect = new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame);
effect.setText("{this}'s power and toughness are each equal to twice the number of cards in your hand");
this.addAbility(new SimpleStaticAbility(Zone.ALL, effect));
diff --git a/Mage.Sets/src/mage/cards/m/MeishinTheMindCage.java b/Mage.Sets/src/mage/cards/m/MeishinTheMindCage.java
index 2d29f4215a1..a88e657705d 100644
--- a/Mage.Sets/src/mage/cards/m/MeishinTheMindCage.java
+++ b/Mage.Sets/src/mage/cards/m/MeishinTheMindCage.java
@@ -26,7 +26,7 @@ public final class MeishinTheMindCage extends CardImpl {
addSuperType(SuperType.LEGENDARY);
// All creatures get -X/-0, where X is the number of cards in your hand.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(new SignInversionDynamicValue(new CardsInControllerHandCount()), new StaticValue(0), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, false, "All creatures get -X/-0, where X is the number of cards in your hand")));
+ this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(new SignInversionDynamicValue(CardsInControllerHandCount.instance), new StaticValue(0), Duration.WhileOnBattlefield, StaticFilters.FILTER_PERMANENT_CREATURE, false, "All creatures get -X/-0, where X is the number of cards in your hand")));
}
public MeishinTheMindCage(final MeishinTheMindCage card) {
diff --git a/Mage.Sets/src/mage/cards/m/MercadianBazaar.java b/Mage.Sets/src/mage/cards/m/MercadianBazaar.java
index dc03c83a538..aadd3bbe450 100644
--- a/Mage.Sets/src/mage/cards/m/MercadianBazaar.java
+++ b/Mage.Sets/src/mage/cards/m/MercadianBazaar.java
@@ -34,7 +34,7 @@ public final class MercadianBazaar extends CardImpl {
// {tap}, Remove any number of storage counters from Mercadian Bazaar: Add {R} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.RedMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {R} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/m/MercurialChemister.java b/Mage.Sets/src/mage/cards/m/MercurialChemister.java
index 9365da620db..b3390f455ec 100644
--- a/Mage.Sets/src/mage/cards/m/MercurialChemister.java
+++ b/Mage.Sets/src/mage/cards/m/MercurialChemister.java
@@ -39,7 +39,7 @@ public final class MercurialChemister extends CardImpl {
this.addAbility(ability);
// {R}, {T}, Discard a card: Mercurial Chemister deals damage to target creature equal to the discarded card's converted mana cost.
- ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new DiscardCostCardConvertedMana()), new ManaCostsImpl("{R}"));
+ ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(DiscardCostCardConvertedMana.instance), new ManaCostsImpl("{R}"));
ability.addTarget(new TargetCreaturePermanent());
ability.addCost(new TapSourceCost());
ability.addCost(new DiscardCardCost());
diff --git a/Mage.Sets/src/mage/cards/m/MeteorShower.java b/Mage.Sets/src/mage/cards/m/MeteorShower.java
index 9c8031c50df..2fa2390c042 100644
--- a/Mage.Sets/src/mage/cards/m/MeteorShower.java
+++ b/Mage.Sets/src/mage/cards/m/MeteorShower.java
@@ -21,7 +21,7 @@ public final class MeteorShower extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{R}");
// Meteor Shower deals X plus 1 damage divided as you choose among any number of target creatures and/or players.
- DynamicValue xValue = new IntPlusDynamicValue(1, new ManacostVariableValue());
+ DynamicValue xValue = new IntPlusDynamicValue(1, ManacostVariableValue.instance);
this.getSpellAbility().addEffect(new DamageMultiEffect(xValue));
this.getSpellAbility().addTarget(new TargetAnyTargetAmount(xValue));
}
diff --git a/Mage.Sets/src/mage/cards/m/MijaeDjinn.java b/Mage.Sets/src/mage/cards/m/MijaeDjinn.java
index 7407d86d66e..6ec0f9b8d1d 100644
--- a/Mage.Sets/src/mage/cards/m/MijaeDjinn.java
+++ b/Mage.Sets/src/mage/cards/m/MijaeDjinn.java
@@ -57,7 +57,7 @@ class MijaeDjinnEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent creature = game.getPermanent(source.getSourceId());
if (controller != null && creature != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
return true;
} else {
creature.removeFromCombat(game);
diff --git a/Mage.Sets/src/mage/cards/m/MilitantAngel.java b/Mage.Sets/src/mage/cards/m/MilitantAngel.java
index 790f1e62c17..c1ff666a0dd 100644
--- a/Mage.Sets/src/mage/cards/m/MilitantAngel.java
+++ b/Mage.Sets/src/mage/cards/m/MilitantAngel.java
@@ -33,7 +33,7 @@ public final class MilitantAngel extends CardImpl {
this.addAbility(LifelinkAbility.getInstance());
// When Militant Angel enters the battlefield, create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn.
- Effect effect = new CreateTokenEffect(new KnightToken(), new AttackedThisTurnOpponentsCount());
+ Effect effect = new CreateTokenEffect(new KnightToken(), AttackedThisTurnOpponentsCount.instance);
effect.setText("create a number of 2/2 white Knight creature tokens with vigilance equal to the number of opponents you attacked this turn");
this.addAbility(new EntersBattlefieldTriggeredAbility(effect));
}
diff --git a/Mage.Sets/src/mage/cards/m/MindShatter.java b/Mage.Sets/src/mage/cards/m/MindShatter.java
index 244b241f933..8e048a27ab7 100644
--- a/Mage.Sets/src/mage/cards/m/MindShatter.java
+++ b/Mage.Sets/src/mage/cards/m/MindShatter.java
@@ -19,7 +19,7 @@ public final class MindShatter extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B}{B}");
// Target player discards X cards at random.
- this.getSpellAbility().addEffect(new DiscardTargetEffect(new ManacostVariableValue(), true));
+ this.getSpellAbility().addEffect(new DiscardTargetEffect(ManacostVariableValue.instance, true));
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/m/MindSpring.java b/Mage.Sets/src/mage/cards/m/MindSpring.java
index f327dde9c9e..58b59946328 100644
--- a/Mage.Sets/src/mage/cards/m/MindSpring.java
+++ b/Mage.Sets/src/mage/cards/m/MindSpring.java
@@ -18,7 +18,7 @@ public final class MindSpring extends CardImpl {
public MindSpring(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}{U}");
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(ManacostVariableValue.instance));
}
public MindSpring(final MindSpring card) {
diff --git a/Mage.Sets/src/mage/cards/m/MindTwist.java b/Mage.Sets/src/mage/cards/m/MindTwist.java
index 1b1b377ffcd..bddc25745ab 100644
--- a/Mage.Sets/src/mage/cards/m/MindTwist.java
+++ b/Mage.Sets/src/mage/cards/m/MindTwist.java
@@ -20,7 +20,7 @@ public final class MindTwist extends CardImpl {
// Target player discards X cards at random.
- this.getSpellAbility().addEffect(new DiscardTargetEffect(new ManacostVariableValue(), true));
+ this.getSpellAbility().addEffect(new DiscardTargetEffect(ManacostVariableValue.instance, true));
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/m/MindWarp.java b/Mage.Sets/src/mage/cards/m/MindWarp.java
index c82cf55fb61..3db8935245e 100644
--- a/Mage.Sets/src/mage/cards/m/MindWarp.java
+++ b/Mage.Sets/src/mage/cards/m/MindWarp.java
@@ -28,7 +28,7 @@ public final class MindWarp extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{3}{B}");
// Look at target player's hand and choose X cards from it. That player discards those cards.
- this.getSpellAbility().addEffect(new MindWarpEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new MindWarpEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/m/Mindswipe.java b/Mage.Sets/src/mage/cards/m/Mindswipe.java
index fbfa217fd31..1650b14967c 100644
--- a/Mage.Sets/src/mage/cards/m/Mindswipe.java
+++ b/Mage.Sets/src/mage/cards/m/Mindswipe.java
@@ -29,7 +29,7 @@ public final class Mindswipe extends CardImpl {
// Counter target spell unless its controller pays {X}. Mindswipe deals X damage to that spell's controller.
- Effect effect = new CounterUnlessPaysEffect(new ManacostVariableValue());
+ Effect effect = new CounterUnlessPaysEffect(ManacostVariableValue.instance);
effect.setText("Counter target spell unless its controller pays {X}.");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetSpell());
@@ -74,7 +74,7 @@ class MindswipeEffect extends OneShotEffect {
Spell spell = (Spell) object;
Player spellController = game.getPlayer(spell.getControllerId());
if (spellController != null) {
- int damage = new ManacostVariableValue().calculate(game, source, this);
+ int damage = ManacostVariableValue.instance.calculate(game, source, this);
spellController.damage(damage, source.getSourceId(), game, false, true);
}
return true;
diff --git a/Mage.Sets/src/mage/cards/m/MineMineMine.java b/Mage.Sets/src/mage/cards/m/MineMineMine.java
index b5c54f0dad2..4d227ec47f8 100644
--- a/Mage.Sets/src/mage/cards/m/MineMineMine.java
+++ b/Mage.Sets/src/mage/cards/m/MineMineMine.java
@@ -33,7 +33,7 @@ public final class MineMineMine extends CardImpl {
public MineMineMine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{4}{G}{G}");
- // When Mine, Mine, Mine enters the battlefield, each player puts his or her library into his or her hand.
+ // When Mine, Mine, Mine enters the battlefield, each player puts their library into their hand.
this.addAbility(new EntersBattlefieldTriggeredAbility(new MineMineMineDrawEffect()));
// Players have no maximum hand size and don't lose the game for drawing from an empty library.
@@ -45,7 +45,7 @@ public final class MineMineMine extends CardImpl {
// Each player can't cast more than one spell each turn.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantCastMoreThanOneSpellEffect(TargetController.ANY)));
- // When Mine, Mine, Mine leaves the battlefield, each player shuffles his or her hand and graveyard into his or her library.
+ // When Mine, Mine, Mine leaves the battlefield, each player shuffles their hand and graveyard into their library.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ShuffleHandGraveyardAllEffect(), false));
}
diff --git a/Mage.Sets/src/mage/cards/m/MirrorEntity.java b/Mage.Sets/src/mage/cards/m/MirrorEntity.java
index b5246cc7e3b..9174db87c9e 100644
--- a/Mage.Sets/src/mage/cards/m/MirrorEntity.java
+++ b/Mage.Sets/src/mage/cards/m/MirrorEntity.java
@@ -40,7 +40,7 @@ public final class MirrorEntity extends CardImpl {
// Changeling
this.addAbility(ChangelingAbility.getInstance());
// {X}: Until end of turn, creatures you control have base power and toughness X/X and gain all creature types.
- DynamicValue variableMana = new ManacostVariableValue();
+ DynamicValue variableMana = ManacostVariableValue.instance;
Effect effect = new SetPowerToughnessAllEffect(variableMana, variableMana, Duration.EndOfTurn, filter, true);
effect.setText("Until end of turn, creatures you control have base power and toughness X/X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new VariableManaCost());
diff --git a/Mage.Sets/src/mage/cards/m/MirrorMarch.java b/Mage.Sets/src/mage/cards/m/MirrorMarch.java
index 9d242c439d7..c68bf6b03ad 100644
--- a/Mage.Sets/src/mage/cards/m/MirrorMarch.java
+++ b/Mage.Sets/src/mage/cards/m/MirrorMarch.java
@@ -8,6 +8,8 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
+import mage.constants.SetTargetPointer;
+import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
@@ -32,7 +34,13 @@ public final class MirrorMarch extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{5}{R}");
// Whenever a nontoken creature enters the battlefield under your control, flip a coin until you lose a flip. For each flip you won, create a token that's a copy of that creature. Those tokens gain haste. Exile them at the beginning of the next end step.
- this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new MirrorMarchEffect(), filter));
+ this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
+ Zone.BATTLEFIELD, new MirrorMarchEffect(), filter, false, SetTargetPointer.PERMANENT,
+ "Whenever a nontoken creature enters the battlefield under your control, " +
+ "flip a coin until you lose a flip. For each flip you won, " +
+ "create a token that's a copy of that creature. Those tokens gain haste. " +
+ "Exile them at the beginning of the next end step."
+ ));
}
private MirrorMarch(final MirrorMarch card) {
@@ -49,9 +57,6 @@ class MirrorMarchEffect extends OneShotEffect {
MirrorMarchEffect() {
super(Outcome.Benefit);
- staticText = "flip a coin until you lose a flip. For each flip you won, " +
- "create a token that's a copy of that creature. " +
- "Those tokens gain haste. Exile them at the beginning of the next end step.";
}
private MirrorMarchEffect(final MirrorMarchEffect effect) {
@@ -72,7 +77,7 @@ class MirrorMarchEffect extends OneShotEffect {
int counter = 0;
boolean wonFlip = false;
do {
- wonFlip = player.flipCoin(game);
+ wonFlip = player.flipCoin(source, game, true);
if (wonFlip) {
counter++;
}
@@ -80,6 +85,8 @@ class MirrorMarchEffect extends OneShotEffect {
if (counter > 0) {
CreateTokenCopyTargetEffect effect
= new CreateTokenCopyTargetEffect(player.getId(), null, true, counter);
+ effect.setUseLKI(true);
+ effect.setTargetPointer(targetPointer);
effect.apply(game, source);
effect.exileTokensCreatedAtNextEndStep(game, source);
}
diff --git a/Mage.Sets/src/mage/cards/m/MoggAssassin.java b/Mage.Sets/src/mage/cards/m/MoggAssassin.java
index 938bdbb799a..8f8f2a93526 100644
--- a/Mage.Sets/src/mage/cards/m/MoggAssassin.java
+++ b/Mage.Sets/src/mage/cards/m/MoggAssassin.java
@@ -110,7 +110,7 @@ class MoggAssassinEffect extends OneShotEffect {
}
Permanent chosenPermanent = game.getPermanent(source.getTargets().get(0).getFirstTarget());
Permanent opponentsPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
if (chosenPermanent != null) {
chosenPermanent.destroy(source.getSourceId(), game, false);
return true;
diff --git a/Mage.Sets/src/mage/cards/m/Molder.java b/Mage.Sets/src/mage/cards/m/Molder.java
index ca23233ac7c..cffc75b81a1 100644
--- a/Mage.Sets/src/mage/cards/m/Molder.java
+++ b/Mage.Sets/src/mage/cards/m/Molder.java
@@ -28,7 +28,7 @@ public final class Molder extends CardImpl {
// Destroy target artifact or enchantment with converted mana cost X. It can't be regenerated. You gain X life.
this.getSpellAbility().addEffect(new DestroyTargetEffect("Destroy target artifact or enchantment with converted mana cost X.", true));
- this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new GainLifeEffect(ManacostVariableValue.instance));
this.getSpellAbility().setTargetAdjuster(MolderAdjuster.instance);
}
diff --git a/Mage.Sets/src/mage/cards/m/MoltenBirth.java b/Mage.Sets/src/mage/cards/m/MoltenBirth.java
index 8ca1c620ba7..6fbee1801cb 100644
--- a/Mage.Sets/src/mage/cards/m/MoltenBirth.java
+++ b/Mage.Sets/src/mage/cards/m/MoltenBirth.java
@@ -59,7 +59,7 @@ class MoltenBirthEffect extends OneShotEffect {
if (controller != null) {
MoltenBirthElementalToken token = new MoltenBirthElementalToken();
token.putOntoBattlefield(2, game, source.getSourceId(), source.getControllerId());
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
Card molten = game.getCard(source.getSourceId());
if (molten != null) {
molten.moveToZone(Zone.HAND, source.getSourceId(), game, true);
diff --git a/Mage.Sets/src/mage/cards/m/MoltenSentry.java b/Mage.Sets/src/mage/cards/m/MoltenSentry.java
index c4640f09dce..d39b4c15517 100644
--- a/Mage.Sets/src/mage/cards/m/MoltenSentry.java
+++ b/Mage.Sets/src/mage/cards/m/MoltenSentry.java
@@ -64,7 +64,7 @@ class MoltenSentryEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanentEntering(source.getSourceId());
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, false)) {
game.informPlayers("Heads: " + permanent.getLogName() + " enters the battlefield as a 5/2 creature with haste");
permanent.getPower().modifyBaseValue(5);
permanent.getToughness().modifyBaseValue(2);
diff --git a/Mage.Sets/src/mage/cards/m/MoltenSlagheap.java b/Mage.Sets/src/mage/cards/m/MoltenSlagheap.java
index a6e3ef4dea9..5d339c274aa 100644
--- a/Mage.Sets/src/mage/cards/m/MoltenSlagheap.java
+++ b/Mage.Sets/src/mage/cards/m/MoltenSlagheap.java
@@ -36,7 +36,7 @@ public final class MoltenSlagheap extends CardImpl {
this.addAbility(ability);
// {1}, Remove X storage counters from Molten Slagheap: Add X mana in any combination of {B} and/or {R}.
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
- new AddManaInAnyCombinationEffect(new RemovedCountersForCostValue(), ColoredManaSymbol.B, ColoredManaSymbol.R),
+ new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.B, ColoredManaSymbol.R),
new GenericManaCost(1));
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/m/MonstrousOnslaught.java b/Mage.Sets/src/mage/cards/m/MonstrousOnslaught.java
index 77087fd6242..28f7226af55 100644
--- a/Mage.Sets/src/mage/cards/m/MonstrousOnslaught.java
+++ b/Mage.Sets/src/mage/cards/m/MonstrousOnslaught.java
@@ -21,7 +21,7 @@ public final class MonstrousOnslaught extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{G}{G}");
// Monstrous Onslaught deals X damage divided as you choose among any number of target creatures, where X is the greatest power among creatures you control as you cast Monstrous Onslaught.
- DynamicValue xValue = new GreatestPowerAmongControlledCreaturesValue();
+ DynamicValue xValue = GreatestPowerAmongControlledCreaturesValue.instance;
Effect effect = new DamageMultiEffect(xValue);
effect.setText("{this} deals X damage divided as you choose among any number of target creatures, where X is the greatest power among creatures you control as you cast {this}");
this.getSpellAbility().addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/m/MultaniMaroSorcerer.java b/Mage.Sets/src/mage/cards/m/MultaniMaroSorcerer.java
index 63949d9ba94..d2e45d955e9 100644
--- a/Mage.Sets/src/mage/cards/m/MultaniMaroSorcerer.java
+++ b/Mage.Sets/src/mage/cards/m/MultaniMaroSorcerer.java
@@ -33,7 +33,7 @@ public final class MultaniMaroSorcerer extends CardImpl {
this.addAbility(ShroudAbility.getInstance());
// Multani, Maro-Sorcerer's power and toughness are each equal to the total number of cards in all players' hands.
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInAllHandsCount(), Duration.EndOfGame)));
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(CardsInAllHandsCount.instance, Duration.EndOfGame)));
}
public MultaniMaroSorcerer(final MultaniMaroSorcerer card) {
diff --git a/Mage.Sets/src/mage/cards/m/MycosynthFiend.java b/Mage.Sets/src/mage/cards/m/MycosynthFiend.java
index ddeaa5a4785..99d1ecdfb52 100644
--- a/Mage.Sets/src/mage/cards/m/MycosynthFiend.java
+++ b/Mage.Sets/src/mage/cards/m/MycosynthFiend.java
@@ -27,7 +27,7 @@ public final class MycosynthFiend extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- DynamicValue value = new OpponentsPoisonCountersCount();
+ DynamicValue value = OpponentsPoisonCountersCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostSourceEffect(value, value, Duration.WhileOnBattlefield)));
}
diff --git a/Mage.Sets/src/mage/cards/n/NahirisWrath.java b/Mage.Sets/src/mage/cards/n/NahirisWrath.java
index 0d4a764c73c..3777758cfe7 100644
--- a/Mage.Sets/src/mage/cards/n/NahirisWrath.java
+++ b/Mage.Sets/src/mage/cards/n/NahirisWrath.java
@@ -34,7 +34,7 @@ public final class NahirisWrath extends CardImpl {
this.getSpellAbility().addCost(new NahirisWrathAdditionalCost());
// Nahiri's Wrath deals damage equal to the total converted mana cost of the discarded cards to each of up to X target creatures and/or planeswalkers.
- Effect effect = new DamageTargetEffect(new DiscardCostCardConvertedMana());
+ Effect effect = new DamageTargetEffect(DiscardCostCardConvertedMana.instance);
effect.setText("{this} deals damage equal to the total converted mana cost of the discarded cards to each of up to X target creatures and/or planeswalkers");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().setTargetAdjuster(NahirisWrathAdjuster.instance);
diff --git a/Mage.Sets/src/mage/cards/n/Necrologia.java b/Mage.Sets/src/mage/cards/n/Necrologia.java
index 1d35c3bebab..d1c3dc8a265 100644
--- a/Mage.Sets/src/mage/cards/n/Necrologia.java
+++ b/Mage.Sets/src/mage/cards/n/Necrologia.java
@@ -29,7 +29,7 @@ public final class Necrologia extends CardImpl {
this.getSpellAbility().addCost(new PayVariableLifeCost(true));
// Draw X cards.
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new GetXValue()));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(GetXValue.instance));
}
public Necrologia(final Necrologia card) {
diff --git a/Mage.Sets/src/mage/cards/n/NecropolisFiend.java b/Mage.Sets/src/mage/cards/n/NecropolisFiend.java
index db6e9c26c82..e1b5a829d9b 100644
--- a/Mage.Sets/src/mage/cards/n/NecropolisFiend.java
+++ b/Mage.Sets/src/mage/cards/n/NecropolisFiend.java
@@ -53,7 +53,7 @@ public final class NecropolisFiend extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// {X}, {T}, Exile X cards from your graveyard: Target creature gets -X/-X until end of turn.
- DynamicValue xValue = new SignInversionDynamicValue(new ManacostVariableValue());
+ DynamicValue xValue = new SignInversionDynamicValue(ManacostVariableValue.instance);
Effect effect = new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn);
effect.setText("Target creature gets -X/-X until end of turn");
Ability ability = new SimpleActivatedAbility(
diff --git a/Mage.Sets/src/mage/cards/n/NightmarishEnd.java b/Mage.Sets/src/mage/cards/n/NightmarishEnd.java
index ccf1c13d351..c597bc8f7a2 100644
--- a/Mage.Sets/src/mage/cards/n/NightmarishEnd.java
+++ b/Mage.Sets/src/mage/cards/n/NightmarishEnd.java
@@ -24,7 +24,7 @@ public final class NightmarishEnd extends CardImpl {
// Target creature gets -X/-X until end of turn, where X is the number of cards in your hand.
- DynamicValue xValue = new SignInversionDynamicValue(new CardsInControllerHandCount());
+ DynamicValue xValue = new SignInversionDynamicValue(CardsInControllerHandCount.instance);
Effect effect = new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn, true);
effect.setText("Target creature gets -X/-X until end of turn, where X is the number of cards in your hand");
this.getSpellAbility().addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/n/NostalgicDreams.java b/Mage.Sets/src/mage/cards/n/NostalgicDreams.java
index 5570440c6d3..a9d8eec1aef 100644
--- a/Mage.Sets/src/mage/cards/n/NostalgicDreams.java
+++ b/Mage.Sets/src/mage/cards/n/NostalgicDreams.java
@@ -55,7 +55,7 @@ enum NostalgicDreamsAdjuster implements TargetAdjuster {
public void adjustTargets(Ability ability, Game game) {
ability.getTargets().clear();
ability.addTarget(new TargetCardInYourGraveyard(
- new GetXValue().calculate(game, ability, null),
+ GetXValue.instance.calculate(game, ability, null),
StaticFilters.FILTER_CARD_FROM_YOUR_GRAVEYARD
));
}
diff --git a/Mage.Sets/src/mage/cards/n/NourishingShoal.java b/Mage.Sets/src/mage/cards/n/NourishingShoal.java
index f6459c10858..aa39d1d90fa 100644
--- a/Mage.Sets/src/mage/cards/n/NourishingShoal.java
+++ b/Mage.Sets/src/mage/cards/n/NourishingShoal.java
@@ -36,7 +36,7 @@ public final class NourishingShoal extends CardImpl {
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter), true)));
// You gain X life.
- this.getSpellAbility().addEffect(new GainLifeEffect(new ExileFromHandCostCardConvertedMana()));
+ this.getSpellAbility().addEffect(new GainLifeEffect(ExileFromHandCostCardConvertedMana.instance));
}
diff --git a/Mage.Sets/src/mage/cards/o/OboroEnvoy.java b/Mage.Sets/src/mage/cards/o/OboroEnvoy.java
index c4990fe881e..fa6d5891b0c 100644
--- a/Mage.Sets/src/mage/cards/o/OboroEnvoy.java
+++ b/Mage.Sets/src/mage/cards/o/OboroEnvoy.java
@@ -39,7 +39,7 @@ public final class OboroEnvoy extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// {2}, Return a land you control to its owner's hand: Target creature gets -X/-0 until end of turn, where X is the number of cards in your hand.
- Effect effect = new BoostTargetEffect(new SignInversionDynamicValue(new CardsInControllerHandCount()), new StaticValue(-0), Duration.EndOfTurn, true);
+ Effect effect = new BoostTargetEffect(new SignInversionDynamicValue(CardsInControllerHandCount.instance), new StaticValue(-0), Duration.EndOfTurn, true);
effect.setText("Target creature gets -X/-0 until end of turn, where X is the number of cards in your hand");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new GenericManaCost(2));
ability.addCost(new ReturnToHandChosenControlledPermanentCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))));
diff --git a/Mage.Sets/src/mage/cards/o/OddsEnds.java b/Mage.Sets/src/mage/cards/o/OddsEnds.java
index e83b5f5258e..efdd05d6e13 100644
--- a/Mage.Sets/src/mage/cards/o/OddsEnds.java
+++ b/Mage.Sets/src/mage/cards/o/OddsEnds.java
@@ -65,7 +65,7 @@ class OddsEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, false)) {
game.informPlayers("Odds: Spell countered");
return game.getStack().counter(getTargetPointer().getFirst(game, source), source.getSourceId(), game);
diff --git a/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java b/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java
index f22d1ea5c57..884c23d1254 100644
--- a/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java
+++ b/Mage.Sets/src/mage/cards/o/OkaunEyeOfChaos.java
@@ -1,7 +1,6 @@
package mage.cards.o;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.WinsCoinFlipTriggeredAbility;
@@ -13,18 +12,18 @@ import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.PartnerWithAbility;
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.constants.TargetController;
+import mage.constants.*;
+
+import java.util.UUID;
/**
- *
* @author TheElk801
*/
public final class OkaunEyeOfChaos extends CardImpl {
+ private static final DynamicValue sourcePower = new SourcePermanentPowerCount();
+ private static final DynamicValue sourceToughness = new SourcePermanentToughnessValue();
+
public OkaunEyeOfChaos(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}");
@@ -41,8 +40,6 @@ public final class OkaunEyeOfChaos extends CardImpl {
this.addAbility(new BeginningOfCombatTriggeredAbility(new FlipUntilLoseEffect(), TargetController.YOU, false));
// Whenever a player wins a coin flip, double Okaun's power and toughness until end of turn.
- DynamicValue sourcePower = new SourcePermanentPowerCount();
- DynamicValue sourceToughness = new SourcePermanentToughnessValue();
this.addAbility(new WinsCoinFlipTriggeredAbility(
new BoostSourceEffect(
sourcePower,
diff --git a/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java b/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java
index a5e986680f4..797552378e2 100644
--- a/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java
+++ b/Mage.Sets/src/mage/cards/o/OnceMoreWithFeeling.java
@@ -28,7 +28,7 @@ public final class OnceMoreWithFeeling extends CardImpl {
public OnceMoreWithFeeling(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{W}{W}{W}{W}");
- // Exile all permanents and all cards from all graveyards. Each player shuffles his or her hand into his or her library, then draws seven cards. Each player's life total becomes 10. Exile Once More with Feeling.
+ // Exile all permanents and all cards from all graveyards. Each player shuffles their hand into their library, then draws seven cards. Each player's life total becomes 10. Exile Once More with Feeling.
this.getSpellAbility().addEffect(new OnceMoreWithFeelingEffect());
Effect effect = new DrawCardAllEffect(7);
effect.setText(", then draws seven cards");
diff --git a/Mage.Sets/src/mage/cards/o/OnwardVictory.java b/Mage.Sets/src/mage/cards/o/OnwardVictory.java
index 5d04b761f92..e5d5aa698d1 100644
--- a/Mage.Sets/src/mage/cards/o/OnwardVictory.java
+++ b/Mage.Sets/src/mage/cards/o/OnwardVictory.java
@@ -25,7 +25,7 @@ public final class OnwardVictory extends SplitCard {
// Onward
// Target creature gets +X/+0 until end of turn where X is its power.
getLeftHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
- getLeftHalfCard().getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true));
+ getLeftHalfCard().getSpellAbility().addEffect(new BoostTargetEffect(TargetPermanentPowerCount.instance, new StaticValue(0), Duration.EndOfTurn, true));
// to
// Victory
diff --git a/Mage.Sets/src/mage/cards/o/OracleOfNectars.java b/Mage.Sets/src/mage/cards/o/OracleOfNectars.java
index 0c8bd66cd1b..94f72f3ee72 100644
--- a/Mage.Sets/src/mage/cards/o/OracleOfNectars.java
+++ b/Mage.Sets/src/mage/cards/o/OracleOfNectars.java
@@ -30,7 +30,7 @@ public final class OracleOfNectars extends CardImpl {
this.toughness = new MageInt(2);
// {X}, {tap}: You gain X life.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/o/OrcishCaptain.java b/Mage.Sets/src/mage/cards/o/OrcishCaptain.java
index 998fe8e7e8d..adb37723559 100644
--- a/Mage.Sets/src/mage/cards/o/OrcishCaptain.java
+++ b/Mage.Sets/src/mage/cards/o/OrcishCaptain.java
@@ -69,7 +69,7 @@ class OrcishCaptainEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
game.informPlayers("Orcish Captain: Won flip. Target Orc creature gets +2/+0 until end of turn.");
game.addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn), source);
return true;
diff --git a/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java b/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java
index c2b78462c69..6484e923032 100644
--- a/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java
+++ b/Mage.Sets/src/mage/cards/o/OverbeingOfMyth.java
@@ -33,7 +33,7 @@ public final class OverbeingOfMyth extends CardImpl {
this.toughness = new MageInt(0);
// Overbeing of Myth's power and toughness are each equal to the number of cards in your hand.
- DynamicValue number = new CardsInControllerHandCount();
+ DynamicValue number = CardsInControllerHandCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(number, Duration.EndOfGame)));
// At the beginning of your draw step, draw an additional card.
diff --git a/Mage.Sets/src/mage/cards/o/Overrule.java b/Mage.Sets/src/mage/cards/o/Overrule.java
index 19b922b8467..5f92d8fd352 100644
--- a/Mage.Sets/src/mage/cards/o/Overrule.java
+++ b/Mage.Sets/src/mage/cards/o/Overrule.java
@@ -20,11 +20,11 @@ public final class Overrule extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{W}{U}");
// Counter target spell unless its controller pays {X}.
- this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetSpell());
// You gain X life.
- this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new GainLifeEffect(ManacostVariableValue.instance));
}
public Overrule(final Overrule card) {
diff --git a/Mage.Sets/src/mage/cards/p/PainKami.java b/Mage.Sets/src/mage/cards/p/PainKami.java
index f682910a9b7..68c11d11539 100644
--- a/Mage.Sets/src/mage/cards/p/PainKami.java
+++ b/Mage.Sets/src/mage/cards/p/PainKami.java
@@ -28,7 +28,7 @@ public final class PainKami extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}{R}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}{R}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/p/Painbringer.java b/Mage.Sets/src/mage/cards/p/Painbringer.java
index 02af94d9bc2..bc415a2ba1a 100644
--- a/Mage.Sets/src/mage/cards/p/Painbringer.java
+++ b/Mage.Sets/src/mage/cards/p/Painbringer.java
@@ -35,7 +35,7 @@ public final class Painbringer extends CardImpl {
this.toughness = new MageInt(1);
// {tap}, Exile any number of cards from your graveyard: Target creature gets -X/-X until end of turn, where X is the number of cards exiled this way.
- DynamicValue X = new SignInversionDynamicValue(new GetXValue());
+ DynamicValue X = new SignInversionDynamicValue(GetXValue.instance);
Effect effect = new BoostTargetEffect(X, X, Duration.EndOfTurn);
effect.setText("Target creature gets -X/-X until end of turn, where X is the number of cards exiled this way");
Ability ability = new SimpleActivatedAbility(effect, new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/p/Panacea.java b/Mage.Sets/src/mage/cards/p/Panacea.java
index 70de0178e61..099c2d61c00 100644
--- a/Mage.Sets/src/mage/cards/p/Panacea.java
+++ b/Mage.Sets/src/mage/cards/p/Panacea.java
@@ -25,7 +25,7 @@ public final class Panacea extends CardImpl {
// {X}{X}, {tap}: Prevent the next X damage that would be dealt to any target this turn.
Ability ability = new SimpleActivatedAbility(
- new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, new ManacostVariableValue()),
+ new PreventDamageToTargetEffect(Duration.EndOfTurn, false, true, ManacostVariableValue.instance),
new ManaCostsImpl("{X}{X}")
);
ability.addCost(new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/p/Paroxysm.java b/Mage.Sets/src/mage/cards/p/Paroxysm.java
index 753951b5c18..d24b2e9b276 100644
--- a/Mage.Sets/src/mage/cards/p/Paroxysm.java
+++ b/Mage.Sets/src/mage/cards/p/Paroxysm.java
@@ -1,111 +1,111 @@
-package mage.cards.p;
-
-import java.util.UUID;
-import mage.constants.SubType;
-import mage.target.common.TargetCreaturePermanent;
-import mage.abilities.Ability;
-import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
-import mage.abilities.effects.ContinuousEffect;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.AttachEffect;
-import mage.abilities.effects.common.continuous.BoostTargetEffect;
-import mage.constants.Outcome;
-import mage.target.TargetPermanent;
-import mage.abilities.keyword.EnchantAbility;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
-import mage.constants.CardType;
-import mage.constants.Duration;
-import mage.constants.TargetController;
-import mage.constants.Zone;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
-import mage.target.targetpointer.FixedTarget;
-
-/**
- *
- * @author jeffwadsworth
- */
-public final class Paroxysm extends CardImpl {
-
- public Paroxysm(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
-
- this.subtype.add(SubType.AURA);
-
- // Enchant creature
- TargetPermanent auraTarget = new TargetCreaturePermanent();
- this.getSpellAbility().addTarget(auraTarget);
- this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
- Ability ability = new EnchantAbility(auraTarget.getTargetName());
- this.addAbility(ability);
-
- // At the beginning of the upkeep of enchanted creature's controller, that player reveals the top card of his or her library.
- // If that card is a land card, destroy that creature. Otherwise, it gets +3/+3 until end of turn.
- this.addAbility(new BeginningOfUpkeepTriggeredAbility(
- Zone.BATTLEFIELD,
- new ParoxysmEffect(),
- TargetController.CONTROLLER_ATTACHED_TO,
- false, false, "At the beginning of the upkeep of enchanted creature's controller, "));
- }
-
- public Paroxysm(final Paroxysm card) {
- super(card);
- }
-
- @Override
- public Paroxysm copy() {
- return new Paroxysm(this);
- }
-}
-
-class ParoxysmEffect extends OneShotEffect {
-
- ParoxysmEffect() {
- super(Outcome.BoostCreature);
- this.staticText = "that player reveals the top card of his or her library. \n"
- + "If that card is a land card, destroy that creature. \n"
- + "Otherwise, it gets +3/+3 until end of turn.";
- }
-
- ParoxysmEffect(final ParoxysmEffect effect) {
- super(effect);
- }
-
- @Override
- public ParoxysmEffect copy() {
- return new ParoxysmEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Permanent aura = game.getPermanent(source.getSourceId());
- if (aura != null) {
- Permanent creatureAttachedTo = game.getPermanent(aura.getAttachedTo());
- if (creatureAttachedTo != null) {
- Player controllerOfCreature = game.getPlayer(creatureAttachedTo.getControllerId());
- if (controllerOfCreature != null) {
- Card revealCardFromTop = controllerOfCreature.getLibrary().getFromTop(game);
- if (revealCardFromTop != null) {
- Cards cards = new CardsImpl();
- cards.add(revealCardFromTop);
- controllerOfCreature.revealCards(source, cards, game);
- if (revealCardFromTop.isLand()) {
- creatureAttachedTo.destroy(source.getSourceId(), game, false);
- } else {
- ContinuousEffect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn);
- effect.setTargetPointer(new FixedTarget(creatureAttachedTo.getId()));
- game.addEffect(effect, source);
- }
- return true;
- }
- }
- }
- }
- return false;
- }
-}
+package mage.cards.p;
+
+import java.util.UUID;
+import mage.constants.SubType;
+import mage.target.common.TargetCreaturePermanent;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.effects.common.continuous.BoostTargetEffect;
+import mage.constants.Outcome;
+import mage.target.TargetPermanent;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public final class Paroxysm extends CardImpl {
+
+ public Paroxysm(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
+
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // At the beginning of the upkeep of enchanted creature's controller, that player reveals the top card of their library.
+ // If that card is a land card, destroy that creature. Otherwise, it gets +3/+3 until end of turn.
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ Zone.BATTLEFIELD,
+ new ParoxysmEffect(),
+ TargetController.CONTROLLER_ATTACHED_TO,
+ false, false, "At the beginning of the upkeep of enchanted creature's controller, "));
+ }
+
+ public Paroxysm(final Paroxysm card) {
+ super(card);
+ }
+
+ @Override
+ public Paroxysm copy() {
+ return new Paroxysm(this);
+ }
+}
+
+class ParoxysmEffect extends OneShotEffect {
+
+ ParoxysmEffect() {
+ super(Outcome.BoostCreature);
+ this.staticText = "that player reveals the top card of their library. \n"
+ + "If that card is a land card, destroy that creature. \n"
+ + "Otherwise, it gets +3/+3 until end of turn.";
+ }
+
+ ParoxysmEffect(final ParoxysmEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public ParoxysmEffect copy() {
+ return new ParoxysmEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent aura = game.getPermanent(source.getSourceId());
+ if (aura != null) {
+ Permanent creatureAttachedTo = game.getPermanent(aura.getAttachedTo());
+ if (creatureAttachedTo != null) {
+ Player controllerOfCreature = game.getPlayer(creatureAttachedTo.getControllerId());
+ if (controllerOfCreature != null) {
+ Card revealCardFromTop = controllerOfCreature.getLibrary().getFromTop(game);
+ if (revealCardFromTop != null) {
+ Cards cards = new CardsImpl();
+ cards.add(revealCardFromTop);
+ controllerOfCreature.revealCards(source, cards, game);
+ if (revealCardFromTop.isLand()) {
+ creatureAttachedTo.destroy(source.getSourceId(), game, false);
+ } else {
+ ContinuousEffect effect = new BoostTargetEffect(3, 3, Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(creatureAttachedTo.getId()));
+ game.addEffect(effect, source);
+ }
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/p/PeemaAetherSeer.java b/Mage.Sets/src/mage/cards/p/PeemaAetherSeer.java
index 4d87ffe9848..84b1f2598e8 100644
--- a/Mage.Sets/src/mage/cards/p/PeemaAetherSeer.java
+++ b/Mage.Sets/src/mage/cards/p/PeemaAetherSeer.java
@@ -34,7 +34,7 @@ public final class PeemaAetherSeer extends CardImpl {
this.toughness = new MageInt(2);
// When Peema Aether-Seer enters the battlefield, you get an amount of {E} equal to the greatest power among creatures you control.
- Effect effect = new GetEnergyCountersControllerEffect(new GreatestPowerAmongControlledCreaturesValue());
+ Effect effect = new GetEnergyCountersControllerEffect(GreatestPowerAmongControlledCreaturesValue.instance);
effect.setText("you get an amount of {E} equal to the greatest power among creatures you control");
this.addAbility(new EntersBattlefieldTriggeredAbility(effect));
diff --git a/Mage.Sets/src/mage/cards/p/PetalmaneBaku.java b/Mage.Sets/src/mage/cards/p/PetalmaneBaku.java
index 85812a645e7..167b6d2ba11 100644
--- a/Mage.Sets/src/mage/cards/p/PetalmaneBaku.java
+++ b/Mage.Sets/src/mage/cards/p/PetalmaneBaku.java
@@ -37,7 +37,7 @@ public final class PetalmaneBaku extends CardImpl {
// {1}, Remove X ki counters from Petalmane Baku: Add X mana of any one color.
Ability ability = new DynamicManaAbility(
new Mana(0, 0, 0, 0, 0, 0, 1, 0),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new ManaCostsImpl<>("{1}"),
"Add X mana of any one color",
true, new CountersSourceCount(CounterType.KI));
diff --git a/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java b/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java
index 4f2f1f4e2dc..3dd4288d02e 100644
--- a/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java
+++ b/Mage.Sets/src/mage/cards/p/PhyrexianSwarmlord.java
@@ -30,7 +30,7 @@ public final class PhyrexianSwarmlord extends CardImpl {
this.addAbility(InfectAbility.getInstance());
this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep",
- new CreateTokenEffect(new InsectInfectToken(), new OpponentsPoisonCountersCount())));
+ new CreateTokenEffect(new InsectInfectToken(), OpponentsPoisonCountersCount.instance)));
}
public PhyrexianSwarmlord(final PhyrexianSwarmlord card) {
diff --git a/Mage.Sets/src/mage/cards/p/Plaguecrafter.java b/Mage.Sets/src/mage/cards/p/Plaguecrafter.java
index 39eaf6eb382..19830b5503a 100644
--- a/Mage.Sets/src/mage/cards/p/Plaguecrafter.java
+++ b/Mage.Sets/src/mage/cards/p/Plaguecrafter.java
@@ -1,8 +1,5 @@
package mage.cards.p;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@@ -23,8 +20,11 @@ import mage.players.Player;
import mage.target.common.TargetControlledPermanent;
import mage.target.targetpointer.FixedTarget;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
/**
- *
* @author themogwi
*/
public final class Plaguecrafter extends CardImpl {
@@ -43,7 +43,7 @@ public final class Plaguecrafter extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new PlaguecrafterEffect()));
}
- public Plaguecrafter(final Plaguecrafter card) {
+ private Plaguecrafter(final Plaguecrafter card) {
super(card);
}
@@ -55,13 +55,13 @@ public final class Plaguecrafter extends CardImpl {
class PlaguecrafterEffect extends OneShotEffect {
- public PlaguecrafterEffect() {
+ PlaguecrafterEffect() {
super(Outcome.Benefit);
this.staticText = "each player sacrifices a creature or planeswalker. "
+ "Each player who can't discards a card.";
}
- public PlaguecrafterEffect(final PlaguecrafterEffect effect) {
+ private PlaguecrafterEffect(final PlaguecrafterEffect effect) {
super(effect);
}
@@ -82,20 +82,22 @@ class PlaguecrafterEffect extends OneShotEffect {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
- if (player != null) {
- FilterControlledPermanent filter = new FilterControlledPermanent();
- filter.add(Predicates.or(
- new CardTypePredicate(CardType.CREATURE),
- new CardTypePredicate(CardType.PLANESWALKER)));
- TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
- if (target.canChoose(player.getId(), game)) {
- while (!target.isChosen() && player.canRespond()) {
- player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
- }
- perms.addAll(target.getTargets());
- } else {
- cantSac.add(playerId);
+ if (player == null) {
+ continue;
+ }
+ FilterControlledPermanent filter = new FilterControlledPermanent("creature or planeswalker");
+ filter.add(Predicates.or(
+ new CardTypePredicate(CardType.CREATURE),
+ new CardTypePredicate(CardType.PLANESWALKER)
+ ));
+ TargetControlledPermanent target = new TargetControlledPermanent(1, 1, filter, true);
+ if (target.canChoose(player.getId(), game)) {
+ while (!target.isChosen() && player.canRespond()) {
+ player.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
}
+ perms.addAll(target.getTargets());
+ } else {
+ cantSac.add(playerId);
}
}
diff --git a/Mage.Sets/src/mage/cards/p/PlanarChaos.java b/Mage.Sets/src/mage/cards/p/PlanarChaos.java
index 4f4dc4c6a7a..863a0d0d4a0 100644
--- a/Mage.Sets/src/mage/cards/p/PlanarChaos.java
+++ b/Mage.Sets/src/mage/cards/p/PlanarChaos.java
@@ -61,7 +61,7 @@ class PlanarChaosUpkeepEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- if (!player.flipCoin(game)) {
+ if (!player.flipCoin(source, game, true)) {
Permanent perm = game.getPermanent(source.getSourceId());
if (perm != null) {
perm.sacrifice(source.getSourceId(), game);
@@ -104,7 +104,7 @@ class PlanarChaosCastAllEffect extends OneShotEffect {
if (sourceObject != null && spell != null) {
Player caster = game.getPlayer(spell.getControllerId());
if (caster != null) {
- if (!caster.flipCoin(game)) {
+ if (!caster.flipCoin(source, game, true)) {
game.informPlayers(sourceObject.getLogName() + ": " + spell.getLogName() + " countered");
game.getStack().counter(getTargetPointer().getFirst(game, source), source.getSourceId(), game);
}
diff --git a/Mage.Sets/src/mage/cards/p/PresenceOfTheWise.java b/Mage.Sets/src/mage/cards/p/PresenceOfTheWise.java
index 0129a82eb5f..7c7037e939f 100644
--- a/Mage.Sets/src/mage/cards/p/PresenceOfTheWise.java
+++ b/Mage.Sets/src/mage/cards/p/PresenceOfTheWise.java
@@ -20,7 +20,7 @@ public final class PresenceOfTheWise extends CardImpl {
// You gain 2 life for each card in your hand.
this.getSpellAbility().addEffect(new GainLifeEffect(
- new MultipliedValue(new CardsInControllerHandCount(), 2),"You gain 2 life for each card in your hand"));
+ new MultipliedValue(CardsInControllerHandCount.instance, 2),"You gain 2 life for each card in your hand"));
}
public PresenceOfTheWise(final PresenceOfTheWise card) {
diff --git a/Mage.Sets/src/mage/cards/p/PriceOfFame.java b/Mage.Sets/src/mage/cards/p/PriceOfFame.java
index 194d35fe996..0aefe57301c 100644
--- a/Mage.Sets/src/mage/cards/p/PriceOfFame.java
+++ b/Mage.Sets/src/mage/cards/p/PriceOfFame.java
@@ -12,7 +12,7 @@ import mage.constants.CardType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
-import mage.filter.common.FilterControlledCreaturePermanent;
+import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.target.common.TargetCreaturePermanent;
@@ -24,7 +24,7 @@ import java.util.UUID;
public final class PriceOfFame extends CardImpl {
private static final FilterPermanent filter
- = new FilterControlledCreaturePermanent("a legendary creature");
+ = new FilterCreaturePermanent("a legendary creature");
static {
filter.add(new SupertypePredicate(SuperType.LEGENDARY));
diff --git a/Mage.Sets/src/mage/cards/p/ProfaneCommand.java b/Mage.Sets/src/mage/cards/p/ProfaneCommand.java
index 769dbf2bbfb..9e9b5172f90 100644
--- a/Mage.Sets/src/mage/cards/p/ProfaneCommand.java
+++ b/Mage.Sets/src/mage/cards/p/ProfaneCommand.java
@@ -38,7 +38,7 @@ public final class ProfaneCommand extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{B}");
- DynamicValue xValue = new ManacostVariableValue();
+ DynamicValue xValue = ManacostVariableValue.instance;
// Choose two -
this.getSpellAbility().getModes().setMinModes(2);
this.getSpellAbility().getModes().setMaxModes(2);
diff --git a/Mage.Sets/src/mage/cards/p/Prosperity.java b/Mage.Sets/src/mage/cards/p/Prosperity.java
index edb928d7bc5..17d84d0b325 100644
--- a/Mage.Sets/src/mage/cards/p/Prosperity.java
+++ b/Mage.Sets/src/mage/cards/p/Prosperity.java
@@ -19,7 +19,7 @@ public final class Prosperity extends CardImpl {
// Each player draws X cards.
- this.getSpellAbility().addEffect(new DrawCardAllEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardAllEffect(ManacostVariableValue.instance));
}
public Prosperity(final Prosperity card) {
diff --git a/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java b/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java
index 3b3e48838b3..bc9badb09fe 100644
--- a/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java
+++ b/Mage.Sets/src/mage/cards/p/ProsshSkyraiderOfKher.java
@@ -38,7 +38,7 @@ public final class ProsshSkyraiderOfKher extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When you cast Prossh, Skyraider of Kher, create X 0/1 red Kobold creature tokens named Kobolds of Kher Keep, where X is the amount of mana spent to cast Prossh.
- this.addAbility(new CastSourceTriggeredAbility(new CreateTokenEffect(new ProsshKoboldToken(), new ManaSpentToCastCount()), false));
+ this.addAbility(new CastSourceTriggeredAbility(new CreateTokenEffect(new ProsshKoboldToken(), ManaSpentToCastCount.instance), false));
// Sacrifice another creature: Prossh gets +1/+0 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 0, Duration.EndOfTurn),
new SacrificeTargetCost(new TargetControlledCreaturePermanent(1, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_CREATURE, true))));
diff --git a/Mage.Sets/src/mage/cards/p/PsychicBattle.java b/Mage.Sets/src/mage/cards/p/PsychicBattle.java
index f4f3eb91b9a..6c77281e1a5 100644
--- a/Mage.Sets/src/mage/cards/p/PsychicBattle.java
+++ b/Mage.Sets/src/mage/cards/p/PsychicBattle.java
@@ -31,7 +31,7 @@ public final class PsychicBattle extends CardImpl {
public PsychicBattle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}{U}");
- // Whenever a player chooses one or more targets, each player reveals the top card of his or her library. The player who reveals the card with the highest converted mana cost may change the target or targets. If two or more cards are tied for highest cost, the target or targets remain unchanged. Changing targets this way doesn't trigger abilities of permanents named Psychic Battle.
+ // Whenever a player chooses one or more targets, each player reveals the top card of their library. The player who reveals the card with the highest converted mana cost may change the target or targets. If two or more cards are tied for highest cost, the target or targets remain unchanged. Changing targets this way doesn't trigger abilities of permanents named Psychic Battle.
this.addAbility(new PsychicBattleTriggeredAbility());
}
diff --git a/Mage.Sets/src/mage/cards/p/PsychicDrain.java b/Mage.Sets/src/mage/cards/p/PsychicDrain.java
index 6deb03654bf..8008a2e7fb3 100644
--- a/Mage.Sets/src/mage/cards/p/PsychicDrain.java
+++ b/Mage.Sets/src/mage/cards/p/PsychicDrain.java
@@ -21,9 +21,9 @@ public final class PsychicDrain extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}{B}");
// Target player puts the top X cards of their library into their graveyard and you gain X life.
- this.getSpellAbility().addEffect(new PutLibraryIntoGraveTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new PutLibraryIntoGraveTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayer());
- Effect effect = new GainLifeEffect(new ManacostVariableValue());
+ Effect effect = new GainLifeEffect(ManacostVariableValue.instance);
effect.setText("and you gain X life");
this.getSpellAbility().addEffect(effect);
}
diff --git a/Mage.Sets/src/mage/cards/p/PsychicSurgery.java b/Mage.Sets/src/mage/cards/p/PsychicSurgery.java
index a3c04aa3268..b50c23af476 100644
--- a/Mage.Sets/src/mage/cards/p/PsychicSurgery.java
+++ b/Mage.Sets/src/mage/cards/p/PsychicSurgery.java
@@ -29,7 +29,7 @@ public final class PsychicSurgery extends CardImpl {
public PsychicSurgery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
- // Whenever an opponent shuffles his or her library, you may look at the top two cards of that library.
+ // Whenever an opponent shuffles their library, you may look at the top two cards of that library.
// You may exile one of those cards. Then put the rest on top of that library in any order.
this.addAbility(new PsychicSurgeryTriggeredAbility());
}
diff --git a/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java b/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java
index 9df5371fa95..74128f25f30 100644
--- a/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java
+++ b/Mage.Sets/src/mage/cards/p/PsychosisCrawler.java
@@ -28,7 +28,7 @@ public final class PsychosisCrawler extends CardImpl {
this.power = new MageInt(0);
this.toughness = new MageInt(0);
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInControllerHandCount(), Duration.EndOfGame)));
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(CardsInControllerHandCount.instance, Duration.EndOfGame)));
this.addAbility(new DrawCardControllerTriggeredAbility(new LoseLifeOpponentsEffect(1), false));
}
diff --git a/Mage.Sets/src/mage/cards/p/PullFromTomorrow.java b/Mage.Sets/src/mage/cards/p/PullFromTomorrow.java
index 2a2760fdebb..bc190746707 100644
--- a/Mage.Sets/src/mage/cards/p/PullFromTomorrow.java
+++ b/Mage.Sets/src/mage/cards/p/PullFromTomorrow.java
@@ -20,7 +20,7 @@ public final class PullFromTomorrow extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{U}{U}");
// Draw X cards, then discard a card.
- getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new ManacostVariableValue()));
+ getSpellAbility().addEffect(new DrawCardSourceControllerEffect(ManacostVariableValue.instance));
Effect effect = new DiscardControllerEffect(1);
effect.setText(", then discard a card");
getSpellAbility().addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/p/PuppetMaster.java b/Mage.Sets/src/mage/cards/p/PuppetMaster.java
new file mode 100644
index 00000000000..7b4a6f874bc
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/p/PuppetMaster.java
@@ -0,0 +1,95 @@
+
+package mage.cards.p;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.DiesAttachedTriggeredAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.AttachEffect;
+import mage.abilities.keyword.EnchantAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.SubType;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.TargetPermanent;
+import mage.target.common.TargetCreaturePermanent;
+
+/**
+ *
+ * @author L_J
+ */
+public final class PuppetMaster extends CardImpl {
+
+ public PuppetMaster(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{U}{U}{U}");
+ this.subtype.add(SubType.AURA);
+
+ // Enchant creature
+ TargetPermanent auraTarget = new TargetCreaturePermanent();
+ this.getSpellAbility().addTarget(auraTarget);
+ this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
+ Ability ability = new EnchantAbility(auraTarget.getTargetName());
+ this.addAbility(ability);
+
+ // When enchanted creature dies, return that card to its owner's hand. If that card is returned to its owner’s hand this way, you may pay {U}{U}{U}. If you do, return Puppet Master to its owner’s hand.
+ this.addAbility(new DiesAttachedTriggeredAbility(new PuppetMasterEffect(), "enchanted creature"));
+ }
+
+ public PuppetMaster(final PuppetMaster card) {
+ super(card);
+ }
+
+ @Override
+ public PuppetMaster copy() {
+ return new PuppetMaster(this);
+ }
+}
+
+class PuppetMasterEffect extends OneShotEffect {
+
+ public PuppetMasterEffect() {
+ super(Outcome.ReturnToHand);
+ staticText = "return that card to its owner's hand. If that card is returned to its owner’s hand this way, you may pay {U}{U}{U}. If you do, return {this} to its owner’s hand";
+ }
+
+ public PuppetMasterEffect(final PuppetMasterEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public PuppetMasterEffect copy() {
+ return new PuppetMasterEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Object object = getValue("attachedTo");
+ if (object instanceof Permanent) {
+ Card card = game.getCard(((Permanent)object).getId());
+ if (card != null) {
+ if (card.moveToZone(Zone.HAND, source.getSourceId(), game, false)) {
+ Cost cost = new ManaCostsImpl("{U}{U}{U}");
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
+ if (controller != null && sourcePermanent != null) {
+ if (controller.chooseUse(Outcome.Neutral, "Pay " + cost.getText() + " to return " + sourcePermanent.getLogName() + " to its owner's hand?", source, game)
+ && cost.pay(source, game, source.getSourceId(), controller.getId(), false, null)) {
+ sourcePermanent.moveToZone(Zone.HAND, source.getSourceId(), game, false);
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/Mage.Sets/src/mage/cards/p/PuppetsVerdict.java b/Mage.Sets/src/mage/cards/p/PuppetsVerdict.java
index ab3f3183fbb..080d25a75cf 100644
--- a/Mage.Sets/src/mage/cards/p/PuppetsVerdict.java
+++ b/Mage.Sets/src/mage/cards/p/PuppetsVerdict.java
@@ -54,7 +54,7 @@ class PuppetsVerdictEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
FilterCreaturePermanent filterPower2OrLess = new FilterCreaturePermanent("all creatures power 2 or less");
filterPower2OrLess.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3));
diff --git a/Mage.Sets/src/mage/cards/p/Pyromancy.java b/Mage.Sets/src/mage/cards/p/Pyromancy.java
index b1d4d0a3cfb..4cc770be5a9 100644
--- a/Mage.Sets/src/mage/cards/p/Pyromancy.java
+++ b/Mage.Sets/src/mage/cards/p/Pyromancy.java
@@ -25,7 +25,7 @@ public final class Pyromancy extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}{R}");
// {3}, Discard a card at random: Pyromancy deals damage to any target equal to the converted mana cost of the discarded card.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new DiscardCostCardConvertedMana()), new ManaCostsImpl("{3}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(DiscardCostCardConvertedMana.instance), new ManaCostsImpl("{3}"));
ability.addTarget(new TargetAnyTarget());
ability.addCost(new DiscardCardCost(true));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/q/QuagVampires.java b/Mage.Sets/src/mage/cards/q/QuagVampires.java
index 4cd03cf178e..ebea1544997 100644
--- a/Mage.Sets/src/mage/cards/q/QuagVampires.java
+++ b/Mage.Sets/src/mage/cards/q/QuagVampires.java
@@ -36,7 +36,7 @@ public final class QuagVampires extends CardImpl {
// Quag Vampires enters the battlefield with a +1/+1 counter on it for each time it was kicked.
this.addAbility(new EntersBattlefieldAbility(
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new MultikickerCount(), true),
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), MultikickerCount.instance, true),
"with a +1/+1 counter on it for each time it was kicked"));
}
diff --git a/Mage.Sets/src/mage/cards/r/RakdosRoustabout.java b/Mage.Sets/src/mage/cards/r/RakdosRoustabout.java
index fab2cfd1bda..301aed4e1dd 100644
--- a/Mage.Sets/src/mage/cards/r/RakdosRoustabout.java
+++ b/Mage.Sets/src/mage/cards/r/RakdosRoustabout.java
@@ -58,13 +58,15 @@ class RakdosRoustaboutAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
- return event.getType() == GameEvent.EventType.ATTACKER_DECLARED;
+ return event.getType() == GameEvent.EventType.CREATURE_BLOCKED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- if (sourceId.equals(event.getSourceId())) {
- this.getEffects().get(0).setTargetPointer(new FixedTarget(game.getCombat().getDefenderId(event.getSourceId())));
+ if (sourceId.equals(event.getTargetId())) {
+ this.getEffects().get(0).setTargetPointer(
+ new FixedTarget(game.getCombat().getDefenderId(event.getTargetId()), game)
+ );
return true;
}
return false;
diff --git a/Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java b/Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java
index 327883a2d94..be9118e141c 100644
--- a/Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java
+++ b/Mage.Sets/src/mage/cards/r/RakdosTheShowstopper.java
@@ -80,7 +80,7 @@ class RakdosTheShowstopperEffect extends OneShotEffect {
&& !permanent.hasSubtype(SubType.DEMON, game)
&& !permanent.hasSubtype(SubType.DEVIL, game)
&& !permanent.hasSubtype(SubType.IMP, game)
- && !player.flipCoin(game)) {
+ && !player.flipCoin(source, game, false)) {
permanent.destroy(source.getSourceId(), game, false);
}
}
diff --git a/Mage.Sets/src/mage/cards/r/RakdossReturn.java b/Mage.Sets/src/mage/cards/r/RakdossReturn.java
index 5d9276caf36..a24d77837ed 100644
--- a/Mage.Sets/src/mage/cards/r/RakdossReturn.java
+++ b/Mage.Sets/src/mage/cards/r/RakdossReturn.java
@@ -28,7 +28,7 @@ public final class RakdossReturn extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{R}");
// Rakdos's Return deals X damage to target opponent or planeswalker. That player or that planeswalker’s controller discards X cards.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addEffect(new RakdossReturnEffect());
this.getSpellAbility().addTarget(new TargetOpponentOrPlaneswalker());
}
@@ -65,7 +65,7 @@ class RakdossReturnEffect extends OneShotEffect {
if (player == null) {
return false;
}
- Effect effect = new DiscardTargetEffect(new ManacostVariableValue());
+ Effect effect = new DiscardTargetEffect(ManacostVariableValue.instance);
effect.setTargetPointer(new FixedTarget(player.getId(), game));
return effect.apply(game, source);
}
diff --git a/Mage.Sets/src/mage/cards/r/RalZarek.java b/Mage.Sets/src/mage/cards/r/RalZarek.java
index 2dfe8cf9b6d..23073717b20 100644
--- a/Mage.Sets/src/mage/cards/r/RalZarek.java
+++ b/Mage.Sets/src/mage/cards/r/RalZarek.java
@@ -99,7 +99,7 @@ class RalZarekExtraTurnsEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (int i = 0; i < 5; i++) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, false)) {
game.getState().getTurnMods().add(new TurnMod(source.getControllerId(), false));
}
}
diff --git a/Mage.Sets/src/mage/cards/r/RalsStaticaster.java b/Mage.Sets/src/mage/cards/r/RalsStaticaster.java
index d5b83f25404..87de152208a 100644
--- a/Mage.Sets/src/mage/cards/r/RalsStaticaster.java
+++ b/Mage.Sets/src/mage/cards/r/RalsStaticaster.java
@@ -48,7 +48,7 @@ public final class RalsStaticaster extends CardImpl {
// Whenever Ral's Staticaster attacks, if you control a Ral planeswalker, Ral's Staticaster gets +1/+0 for each card in your hand until end of turn.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new AttacksTriggeredAbility(new BoostSourceEffect(
- new CardsInControllerHandCount(), new StaticValue(0),
+ CardsInControllerHandCount.instance, new StaticValue(0),
Duration.EndOfTurn, true), false),
new PermanentsOnTheBattlefieldCondition(filter),
"Whenever {this} attacks, if you control a Ral planeswalker, "
diff --git a/Mage.Sets/src/mage/cards/r/RapidFire.java b/Mage.Sets/src/mage/cards/r/RapidFire.java
new file mode 100644
index 00000000000..a57b9181edb
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/r/RapidFire.java
@@ -0,0 +1,82 @@
+
+package mage.cards.r;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.CastOnlyDuringPhaseStepSourceAbility;
+import mage.abilities.condition.common.BeforeBlockersAreDeclaredCondition;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
+import mage.abilities.keyword.FirstStrikeAbility;
+import mage.abilities.keyword.RampageAbility;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.*;
+import mage.game.Game;
+import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.common.TargetCreaturePermanent;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author L_J
+ */
+public final class RapidFire extends CardImpl {
+
+ public RapidFire(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{W}");
+
+ // Cast this spell only before blockers are declared.
+ this.addAbility(new CastOnlyDuringPhaseStepSourceAbility(null, null, BeforeBlockersAreDeclaredCondition.instance, "Cast this spell only before blockers are declared"));
+
+ // Target creature gains first strike until end of turn. If it doesn’t have rampage, that creature gains rampage 2 until end of turn.
+ this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new RapidFireEffect());
+ this.getSpellAbility().addTarget(new TargetCreaturePermanent());
+
+ }
+
+ public RapidFire(final RapidFire card) {
+ super(card);
+ }
+
+ @Override
+ public RapidFire copy() {
+ return new RapidFire(this);
+ }
+
+}
+
+class RapidFireEffect extends OneShotEffect {
+
+ public RapidFireEffect() {
+ super(Outcome.AddAbility);
+ this.staticText = "If it doesn’t have rampage, that creature gains rampage 2 until end of turn";
+ }
+
+ public RapidFireEffect(final RapidFireEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public RapidFireEffect copy() {
+ return new RapidFireEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
+ if (controller != null && permanent != null) {
+ if (!permanent.getAbilities().containsClass(RampageAbility.class)) {
+ ContinuousEffect effect = new GainAbilityTargetEffect(new RampageAbility(2), Duration.EndOfTurn);
+ effect.setTargetPointer(new FixedTarget(permanent, game));
+ game.addEffect(effect, source);
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/r/RashidaScalebane.java b/Mage.Sets/src/mage/cards/r/RashidaScalebane.java
index 2e690465339..af3c5daf3d0 100644
--- a/Mage.Sets/src/mage/cards/r/RashidaScalebane.java
+++ b/Mage.Sets/src/mage/cards/r/RashidaScalebane.java
@@ -46,7 +46,7 @@ public final class RashidaScalebane extends CardImpl {
// {tap}: Destroy target attacking or blocking Dragon. It can't be regenerated. You gain life equal to its power.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(true), new TapSourceCost());
- Effect effect = new GainLifeEffect(new TargetPermanentPowerCount());
+ Effect effect = new GainLifeEffect(TargetPermanentPowerCount.instance);
effect.setText("You gain life equal to its power");
ability.addEffect(effect);
ability.addTarget(new TargetCreaturePermanent(filter));
diff --git a/Mage.Sets/src/mage/cards/r/RavagingBlaze.java b/Mage.Sets/src/mage/cards/r/RavagingBlaze.java
index 6a85da01800..4b8f4e7f45d 100644
--- a/Mage.Sets/src/mage/cards/r/RavagingBlaze.java
+++ b/Mage.Sets/src/mage/cards/r/RavagingBlaze.java
@@ -22,10 +22,10 @@ public final class RavagingBlaze extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{R}{R}");
// Ravaging Blaze deals X damage to target creature.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, Ravaging Blaze also deals X damage to that creature's controller.
- this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DamageTargetControllerEffect(new ManacostVariableValue()),
+ this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new DamageTargetControllerEffect(ManacostVariableValue.instance),
SpellMasteryCondition.instance, "
Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, Ravaging Blaze also deals X damage to that creature's controller."));
}
diff --git a/Mage.Sets/src/mage/cards/r/RealmSeekers.java b/Mage.Sets/src/mage/cards/r/RealmSeekers.java
index 283fff9287d..5ac43f2142f 100644
--- a/Mage.Sets/src/mage/cards/r/RealmSeekers.java
+++ b/Mage.Sets/src/mage/cards/r/RealmSeekers.java
@@ -37,7 +37,7 @@ public final class RealmSeekers extends CardImpl {
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(
CounterType.P1P1.createInstance(),
- new CardsInAllHandsCount(),
+ CardsInAllHandsCount.instance,
false),
"with X +1/+1 counters on it, where X is the total number of cards in all players' hands"));
diff --git a/Mage.Sets/src/mage/cards/r/Reanimate.java b/Mage.Sets/src/mage/cards/r/Reanimate.java
index 3a70eaa36e0..d91e2ad3e44 100644
--- a/Mage.Sets/src/mage/cards/r/Reanimate.java
+++ b/Mage.Sets/src/mage/cards/r/Reanimate.java
@@ -25,7 +25,7 @@ public final class Reanimate extends CardImpl {
// Put target creature card from a graveyard onto the battlefield under your control. You lose life equal to its converted mana cost.
getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card from a graveyard")));
getSpellAbility().addEffect(new ReturnFromGraveyardToBattlefieldTargetEffect());
- Effect effect = new LoseLifeSourceControllerEffect(new TargetConvertedManaCost());
+ Effect effect = new LoseLifeSourceControllerEffect(TargetConvertedManaCost.instance);
effect.setText("You lose life equal to its converted mana cost");
getSpellAbility().addEffect(effect);
}
diff --git a/Mage.Sets/src/mage/cards/r/RedManaBattery.java b/Mage.Sets/src/mage/cards/r/RedManaBattery.java
index 461a4664e3e..1281c0d257b 100644
--- a/Mage.Sets/src/mage/cards/r/RedManaBattery.java
+++ b/Mage.Sets/src/mage/cards/r/RedManaBattery.java
@@ -36,7 +36,7 @@ public final class RedManaBattery extends CardImpl {
// {tap}, Remove any number of charge counters from Red Mana Battery: Add {R}, then add an additional {R} for each charge counter removed this way.
ability = new DynamicManaAbility(
Mana.RedMana(1),
- new IntPlusDynamicValue(1, new RemovedCountersForCostValue()),
+ new IntPlusDynamicValue(1, RemovedCountersForCostValue.instance),
new TapSourceCost(),
"Add {R}, then add {R} for each charge counter removed this way",
true, new CountersSourceCount(CounterType.CHARGE));
diff --git a/Mage.Sets/src/mage/cards/r/RedSunsZenith.java b/Mage.Sets/src/mage/cards/r/RedSunsZenith.java
index a95deffc582..9d39917e0ce 100644
--- a/Mage.Sets/src/mage/cards/r/RedSunsZenith.java
+++ b/Mage.Sets/src/mage/cards/r/RedSunsZenith.java
@@ -26,7 +26,7 @@ public final class RedSunsZenith extends CardImpl {
// If a creature dealt damage this way would die this turn, exile it instead.
// Shuffle Red Sun's Zenith into its owner's library.
this.getSpellAbility().addTarget(new TargetAnyTarget());
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addEffect(new DealtDamageToCreatureBySourceDies(this, Duration.EndOfTurn));
this.getSpellAbility().addEffect(ShuffleSpellEffect.getInstance());
this.getSpellAbility().addWatcher(new DamagedByWatcher());
diff --git a/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java b/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java
index a176fbb338e..eee1db14278 100644
--- a/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java
+++ b/Mage.Sets/src/mage/cards/r/ReleaseTheGremlins.java
@@ -28,7 +28,7 @@ public final class ReleaseTheGremlins extends CardImpl {
this.getSpellAbility().addTarget(new TargetArtifactPermanent());
// Create X 2/2 red Gremlin creature tokens.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new GremlinToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new GremlinToken(), ManacostVariableValue.instance));
this.getSpellAbility().setTargetAdjuster(ReleaseTheGremlinsAdjuster.instance);
}
diff --git a/Mage.Sets/src/mage/cards/r/RetributionOfTheAncients.java b/Mage.Sets/src/mage/cards/r/RetributionOfTheAncients.java
index ce921ada409..42aab39e6f4 100644
--- a/Mage.Sets/src/mage/cards/r/RetributionOfTheAncients.java
+++ b/Mage.Sets/src/mage/cards/r/RetributionOfTheAncients.java
@@ -36,7 +36,7 @@ public final class RetributionOfTheAncients extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{B}");
- DynamicValue xValue = new SignInversionDynamicValue(new GetXValue());
+ DynamicValue xValue = new SignInversionDynamicValue(GetXValue.instance);
// {B}, Remove X +1/+1 counters from among creatures you control: Target creature gets -X/-X until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(xValue,xValue,Duration.EndOfTurn, true), new ManaCostsImpl("{B}"));
ability.addCost(new RemoveVariableCountersTargetCost(filter, CounterType.P1P1, "X", 0));
diff --git a/Mage.Sets/src/mage/cards/r/RighteousAuthority.java b/Mage.Sets/src/mage/cards/r/RighteousAuthority.java
index 8e066aae9a4..399c1a17cfe 100644
--- a/Mage.Sets/src/mage/cards/r/RighteousAuthority.java
+++ b/Mage.Sets/src/mage/cards/r/RighteousAuthority.java
@@ -2,7 +2,6 @@
package mage.cards.r;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfDrawTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@@ -21,18 +20,18 @@ import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class RighteousAuthority extends CardImpl {
- public RighteousAuthority (UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}{U}");
+ public RighteousAuthority(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{U}");
this.subtype.add(SubType.AURA);
-
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
@@ -48,7 +47,7 @@ public final class RighteousAuthority extends CardImpl {
this.addAbility(new BeginningOfDrawTriggeredAbility(new DrawCardTargetEffect(1), TargetController.CONTROLLER_ATTACHED_TO, false));
}
- public RighteousAuthority (final RighteousAuthority card) {
+ public RighteousAuthority(final RighteousAuthority card) {
super(card);
}
@@ -79,7 +78,7 @@ class CardsInEnchantedControllerHandCount implements DynamicValue {
@Override
public DynamicValue copy() {
- return new mage.abilities.dynamicvalue.common.CardsInControllerHandCount();
+ return new CardsInEnchantedControllerHandCount();
}
@Override
diff --git a/Mage.Sets/src/mage/cards/r/RishkarsExpertise.java b/Mage.Sets/src/mage/cards/r/RishkarsExpertise.java
index 35ff9c2d529..4dd55e8cdc5 100644
--- a/Mage.Sets/src/mage/cards/r/RishkarsExpertise.java
+++ b/Mage.Sets/src/mage/cards/r/RishkarsExpertise.java
@@ -19,7 +19,7 @@ public final class RishkarsExpertise extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{G}{G}");
// Draw cards equal to the greatest power among creatures you control.
- Effect effect = new DrawCardSourceControllerEffect(new GreatestPowerAmongControlledCreaturesValue());
+ Effect effect = new DrawCardSourceControllerEffect(GreatestPowerAmongControlledCreaturesValue.instance);
effect.setText("Draw cards equal to the greatest power among creatures you control");
this.getSpellAbility().addEffect(effect);
diff --git a/Mage.Sets/src/mage/cards/r/RiskyMove.java b/Mage.Sets/src/mage/cards/r/RiskyMove.java
index a855fca0834..b72f91ad8dc 100644
--- a/Mage.Sets/src/mage/cards/r/RiskyMove.java
+++ b/Mage.Sets/src/mage/cards/r/RiskyMove.java
@@ -162,7 +162,7 @@ class RiskyMoveFlipCoinEffect extends OneShotEffect {
}
Permanent permanent = game.getPermanent(target1.getFirstTarget());
Player chosenOpponent = game.getPlayer(target2.getFirstTarget());
- if (!controller.flipCoin(game)) {
+ if (!controller.flipCoin(source, game, true)) {
if (permanent != null && chosenOpponent != null) {
ContinuousEffect effect = new RiskyMoveCreatureGainControlEffect(Duration.Custom, chosenOpponent.getId());
effect.setTargetPointer(new FixedTarget(permanent.getId()));
diff --git a/Mage.Sets/src/mage/cards/r/RockSlide.java b/Mage.Sets/src/mage/cards/r/RockSlide.java
index c0ab5600718..fe4a7869d98 100644
--- a/Mage.Sets/src/mage/cards/r/RockSlide.java
+++ b/Mage.Sets/src/mage/cards/r/RockSlide.java
@@ -36,7 +36,7 @@ public final class RockSlide extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{R}");
// Rock Slide deals X damage divided as you choose among any number of target attacking or blocking creatures without flying.
- DynamicValue xValue = new ManacostVariableValue();
+ DynamicValue xValue = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new DamageMultiEffect(xValue));
this.getSpellAbility().addTarget(new TargetCreaturePermanentAmount(xValue, filter));
}
diff --git a/Mage.Sets/src/mage/cards/r/RollingEarthquake.java b/Mage.Sets/src/mage/cards/r/RollingEarthquake.java
index 005778c3c55..5e201d51401 100644
--- a/Mage.Sets/src/mage/cards/r/RollingEarthquake.java
+++ b/Mage.Sets/src/mage/cards/r/RollingEarthquake.java
@@ -29,7 +29,7 @@ public final class RollingEarthquake extends CardImpl {
// Rolling Earthquake deals X damage to each creature without horsemanship and each player.
- this.getSpellAbility().addEffect(new DamageEverythingEffect(new ManacostVariableValue(), filter));
+ this.getSpellAbility().addEffect(new DamageEverythingEffect(ManacostVariableValue.instance, filter));
}
public RollingEarthquake(final RollingEarthquake card) {
diff --git a/Mage.Sets/src/mage/cards/r/RollingThunder.java b/Mage.Sets/src/mage/cards/r/RollingThunder.java
index b4b7e696ffb..696e3ed0f68 100644
--- a/Mage.Sets/src/mage/cards/r/RollingThunder.java
+++ b/Mage.Sets/src/mage/cards/r/RollingThunder.java
@@ -20,7 +20,7 @@ public final class RollingThunder extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}{R}");
// Rolling Thunder deals X damage divided as you choose among any number of target creatures and/or players.
- DynamicValue xValue = new ManacostVariableValue();
+ DynamicValue xValue = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new DamageMultiEffect(xValue));
this.getSpellAbility().addTarget(new TargetAnyTargetAmount(xValue));
}
diff --git a/Mage.Sets/src/mage/cards/r/RotHulk.java b/Mage.Sets/src/mage/cards/r/RotHulk.java
index 152f27ddcac..81b82e55263 100644
--- a/Mage.Sets/src/mage/cards/r/RotHulk.java
+++ b/Mage.Sets/src/mage/cards/r/RotHulk.java
@@ -55,7 +55,7 @@ public final class RotHulk extends CardImpl {
// up to X target Zombie cards from your graveyard
// X is the number of opponents you have.
ability.getTargets().clear();
- int numbTargets = new OpponentsCount().calculate(game, ability, null);
+ int numbTargets = OpponentsCount.instance.calculate(game, ability, null);
ability.addTarget(new TargetCardInYourGraveyard(0, numbTargets, filterZombie));
}
}
diff --git a/Mage.Sets/src/mage/cards/r/RushOfBlood.java b/Mage.Sets/src/mage/cards/r/RushOfBlood.java
index 3a1b06858ce..09daee68f03 100644
--- a/Mage.Sets/src/mage/cards/r/RushOfBlood.java
+++ b/Mage.Sets/src/mage/cards/r/RushOfBlood.java
@@ -22,7 +22,7 @@ public final class RushOfBlood extends CardImpl {
// Target creature gets +X/+0 until end of turn, where X is its power.
- this.getSpellAbility().addEffect(new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(TargetPermanentPowerCount.instance, new StaticValue(0), Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/r/RushwoodGrove.java b/Mage.Sets/src/mage/cards/r/RushwoodGrove.java
index 670f8b8f6b1..604f7383f53 100644
--- a/Mage.Sets/src/mage/cards/r/RushwoodGrove.java
+++ b/Mage.Sets/src/mage/cards/r/RushwoodGrove.java
@@ -34,7 +34,7 @@ public final class RushwoodGrove extends CardImpl {
// {T}, Remove any number of storage counters from Rushwood Grove: Add {G} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.GreenMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {G} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/s/SabaccGame.java b/Mage.Sets/src/mage/cards/s/SabaccGame.java
index 3d42eaf52fe..4cfd1b6b467 100644
--- a/Mage.Sets/src/mage/cards/s/SabaccGame.java
+++ b/Mage.Sets/src/mage/cards/s/SabaccGame.java
@@ -88,7 +88,7 @@ class SabaccGameEffect extends OneShotEffect {
if (target.chooseTarget(outcome, opponent.getId(), source, game)) {
chosenPermanent = game.getPermanent(target.getFirstTarget());
}
- boolean flipWin = controller.flipCoin(game);
+ boolean flipWin = controller.flipCoin(source, game, true);
if (flipWin) {
ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, true, controller.getId());
effect.setTargetPointer(new FixedTarget(targetPermanent, game));
diff --git a/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java b/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java
index dcecae03c61..159e756f99b 100644
--- a/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java
+++ b/Mage.Sets/src/mage/cards/s/SageOfAncientLore.java
@@ -43,7 +43,7 @@ public final class SageOfAncientLore extends CardImpl {
this.secondSideCardClazz = mage.cards.w.WerewolfOfAncientHunger.class;
// Sage of Ancient Lore's power and toughness are each equal to the number of cards in your hand.
- DynamicValue xValue = new CardsInControllerHandCount();
+ DynamicValue xValue = CardsInControllerHandCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.ALL,
new ConditionalContinuousEffect(new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame),
new TransformedCondition(true), "{this}'s power and toughness are each equal to the total number of cards in your hand")));
diff --git a/Mage.Sets/src/mage/cards/s/SaltcrustedSteppe.java b/Mage.Sets/src/mage/cards/s/SaltcrustedSteppe.java
index 8bc8e64d083..9b20de817dc 100644
--- a/Mage.Sets/src/mage/cards/s/SaltcrustedSteppe.java
+++ b/Mage.Sets/src/mage/cards/s/SaltcrustedSteppe.java
@@ -36,7 +36,7 @@ public final class SaltcrustedSteppe extends CardImpl {
this.addAbility(ability);
// {1}, Remove X storage counters from Saltcrusted Steppe: Add X mana in any combination of {G} and/or {W}.
ability = new SimpleManaAbility(Zone.BATTLEFIELD,
- new AddManaInAnyCombinationEffect(new RemovedCountersForCostValue(), ColoredManaSymbol.G, ColoredManaSymbol.W),
+ new AddManaInAnyCombinationEffect(RemovedCountersForCostValue.instance, ColoredManaSymbol.G, ColoredManaSymbol.W),
new GenericManaCost(1));
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance()));
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/s/SanctumOfTheSun.java b/Mage.Sets/src/mage/cards/s/SanctumOfTheSun.java
index 46269e831e2..0a8238c866c 100644
--- a/Mage.Sets/src/mage/cards/s/SanctumOfTheSun.java
+++ b/Mage.Sets/src/mage/cards/s/SanctumOfTheSun.java
@@ -32,7 +32,7 @@ public final class SanctumOfTheSun extends CardImpl {
new InfoEffect("(Transforms from Azor's Gateway.)")).setRuleAtTheTop(true));
// {T}: Add X mana of any one color, where X is your life total.
- this.addAbility(new DynamicManaAbility(new Mana(0, 0, 0, 0, 0, 0, 1, 0), new ControllerLifeCount(), new TapSourceCost(),
+ this.addAbility(new DynamicManaAbility(new Mana(0, 0, 0, 0, 0, 0, 1, 0), ControllerLifeCount.instance, new TapSourceCost(),
"Add X mana of any one color, where X is is your life total", true));
}
diff --git a/Mage.Sets/src/mage/cards/s/SandSilos.java b/Mage.Sets/src/mage/cards/s/SandSilos.java
index 360ca7ffc87..61b800e3bd9 100644
--- a/Mage.Sets/src/mage/cards/s/SandSilos.java
+++ b/Mage.Sets/src/mage/cards/s/SandSilos.java
@@ -44,7 +44,7 @@ public final class SandSilos extends CardImpl {
// {tap}, Remove any number of storage counters from Sand Silos: Add {U} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.BlueMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {U} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/s/SandsOfDelirium.java b/Mage.Sets/src/mage/cards/s/SandsOfDelirium.java
index cbbb1c6011b..f10c51c2bff 100644
--- a/Mage.Sets/src/mage/cards/s/SandsOfDelirium.java
+++ b/Mage.Sets/src/mage/cards/s/SandsOfDelirium.java
@@ -25,7 +25,7 @@ public final class SandsOfDelirium extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
// {X}, {tap}: Target player puts the top X cards of their library into their graveyard.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLibraryIntoGraveTargetEffect(new ManacostVariableValue()), new VariableManaCost());
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLibraryIntoGraveTargetEffect(ManacostVariableValue.instance), new VariableManaCost());
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/s/SanguineSacrament.java b/Mage.Sets/src/mage/cards/s/SanguineSacrament.java
index f80c3580cac..bbccf8ba5c8 100644
--- a/Mage.Sets/src/mage/cards/s/SanguineSacrament.java
+++ b/Mage.Sets/src/mage/cards/s/SanguineSacrament.java
@@ -1,9 +1,8 @@
package mage.cards.s;
-import java.util.UUID;
import mage.abilities.Ability;
-import mage.abilities.dynamicvalue.common.ManacostVariableValue;
+import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.ReturnToLibrarySpellEffect;
@@ -12,8 +11,9 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.Game;
+import java.util.UUID;
+
/**
- *
* @author spjspj
*/
public final class SanguineSacrament extends CardImpl {
@@ -22,11 +22,11 @@ public final class SanguineSacrament extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{W}{W}");
// You gain twice X life. Put Sanguine Sacrament on the bottom of its owner's library.
- this.getSpellAbility().addEffect(new GainLifeEffect(new SanguineSacramentValue()));
+ this.getSpellAbility().addEffect(new GainLifeEffect(SanguineSacramentValue.instance));
this.getSpellAbility().addEffect(new ReturnToLibrarySpellEffect(false));
}
- public SanguineSacrament(final SanguineSacrament card) {
+ private SanguineSacrament(final SanguineSacrament card) {
super(card);
}
@@ -36,16 +36,22 @@ public final class SanguineSacrament extends CardImpl {
}
}
-class SanguineSacramentValue extends ManacostVariableValue {
+enum SanguineSacramentValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
- return super.calculate(game, sourceAbility, effect) * 2;
+ return sourceAbility.getManaCostsToPay().getX() * 2;
}
@Override
public SanguineSacramentValue copy() {
- return new SanguineSacramentValue();
+ return instance;
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/s/SaplingOfColfenor.java b/Mage.Sets/src/mage/cards/s/SaplingOfColfenor.java
index 3297faa9a2c..4bfeb3924cc 100644
--- a/Mage.Sets/src/mage/cards/s/SaplingOfColfenor.java
+++ b/Mage.Sets/src/mage/cards/s/SaplingOfColfenor.java
@@ -74,12 +74,14 @@ class SaplingOfColfenorEffect extends OneShotEffect {
if (controller != null && sourceObject != null) {
if (controller.getLibrary().hasCards()) {
Card card = controller.getLibrary().getFromTop(game);
- Cards cards = new CardsImpl(card);
- controller.revealCards(sourceObject.getIdName(), cards, game);
- if (card.isCreature()) {
- controller.gainLife(card.getToughness().getValue(), game, source);
- controller.loseLife(card.getPower().getValue(), game, false);
- return controller.moveCards(cards.getCards(game), Zone.HAND, source, game);
+ if(card != null) {
+ Cards cards = new CardsImpl(card);
+ controller.revealCards(sourceObject.getIdName(), cards, game);
+ if (card.isCreature()) {
+ controller.gainLife(card.getToughness().getValue(), game, source);
+ controller.loseLife(card.getPower().getValue(), game, false);
+ return controller.moveCards(cards.getCards(game), Zone.HAND, source, game);
+ }
}
}
return true;
diff --git a/Mage.Sets/src/mage/cards/s/SaprazzanCove.java b/Mage.Sets/src/mage/cards/s/SaprazzanCove.java
index 9f1c510d2a7..5806b041e15 100644
--- a/Mage.Sets/src/mage/cards/s/SaprazzanCove.java
+++ b/Mage.Sets/src/mage/cards/s/SaprazzanCove.java
@@ -34,7 +34,7 @@ public final class SaprazzanCove extends CardImpl {
// {tap}, Remove any number of storage counters from Saprazzan Cove: Add {U} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.BlueMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {U} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/s/SavageTwister.java b/Mage.Sets/src/mage/cards/s/SavageTwister.java
index 26acebbd855..0b9090439b0 100644
--- a/Mage.Sets/src/mage/cards/s/SavageTwister.java
+++ b/Mage.Sets/src/mage/cards/s/SavageTwister.java
@@ -20,7 +20,7 @@ public final class SavageTwister extends CardImpl {
// Savage Twister deals X damage to each creature.
- this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), new FilterCreaturePermanent()));
+ this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, new FilterCreaturePermanent()));
}
public SavageTwister(final SavageTwister card) {
diff --git a/Mage.Sets/src/mage/cards/s/ScavengingGhoul.java b/Mage.Sets/src/mage/cards/s/ScavengingGhoul.java
index 103d57b3604..d71e11b07bf 100644
--- a/Mage.Sets/src/mage/cards/s/ScavengingGhoul.java
+++ b/Mage.Sets/src/mage/cards/s/ScavengingGhoul.java
@@ -32,7 +32,7 @@ public final class ScavengingGhoul extends CardImpl {
// At the beginning of each end step, put a corpse counter on Scavenging Ghoul for each creature that died this turn.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new AddCountersSourceEffect(CounterType.CORPSE.createInstance(),
- new CreaturesDiedThisTurnCount(), true), TargetController.ANY, false), new CreaturesDiedWatcher());
+ CreaturesDiedThisTurnCount.instance, true), TargetController.ANY, false), new CreaturesDiedWatcher());
// Remove a corpse counter from Scavenging Ghoul: Regenerate Scavenging Ghoul.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(),
new RemoveCountersSourceCost(CounterType.CORPSE.createInstance())));
diff --git a/Mage.Sets/src/mage/cards/s/ScholarOfAthreos.java b/Mage.Sets/src/mage/cards/s/ScholarOfAthreos.java
index cc9c89b986f..aebf8005de6 100644
--- a/Mage.Sets/src/mage/cards/s/ScholarOfAthreos.java
+++ b/Mage.Sets/src/mage/cards/s/ScholarOfAthreos.java
@@ -1,4 +1,3 @@
-
package mage.cards.s;
import java.util.UUID;
@@ -10,10 +9,11 @@ import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.SubType;
import mage.constants.Outcome;
+import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
+import mage.players.Player;
/**
*
@@ -22,7 +22,7 @@ import mage.game.Game;
public final class ScholarOfAthreos extends CardImpl {
public ScholarOfAthreos(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.CLERIC);
@@ -33,7 +33,7 @@ public final class ScholarOfAthreos extends CardImpl {
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScholarOfAthreosEffect(), new ManaCostsImpl("{2}{B}")));
}
- public ScholarOfAthreos(final ScholarOfAthreos card) {
+ private ScholarOfAthreos(final ScholarOfAthreos card) {
super(card);
}
@@ -50,17 +50,20 @@ class ScholarOfAthreosEffect extends OneShotEffect {
staticText = "Each opponent loses 1 life. You gain life equal to the life lost this way";
}
- public ScholarOfAthreosEffect(final ScholarOfAthreosEffect effect) {
+ private ScholarOfAthreosEffect(final ScholarOfAthreosEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
- int damage = 0;
- for (UUID opponentId: game.getOpponents(source.getControllerId())) {
- damage += game.getPlayer(opponentId).damage(1, source.getSourceId(), game, false, true);
+ int lifeLost = 0;
+ for (UUID opponentId : game.getOpponents(source.getControllerId())) {
+ Player opponent = game.getPlayer(opponentId);
+ if(opponent != null) {
+ lifeLost += opponent.loseLife(1, game, false);
+ }
}
- game.getPlayer(source.getControllerId()).gainLife(damage, game, source);
+ game.getPlayer(source.getControllerId()).gainLife(lifeLost, game, source);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/s/ScoriaWurm.java b/Mage.Sets/src/mage/cards/s/ScoriaWurm.java
index 4c05f8d3502..5f02aba6f93 100644
--- a/Mage.Sets/src/mage/cards/s/ScoriaWurm.java
+++ b/Mage.Sets/src/mage/cards/s/ScoriaWurm.java
@@ -60,7 +60,7 @@ class ScoriaWurmEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
return true;
} else {
new ReturnToHandSourceEffect().apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/s/ScryingGlass.java b/Mage.Sets/src/mage/cards/s/ScryingGlass.java
index 8f53b6f0333..bb535f3a52a 100644
--- a/Mage.Sets/src/mage/cards/s/ScryingGlass.java
+++ b/Mage.Sets/src/mage/cards/s/ScryingGlass.java
@@ -1,87 +1,87 @@
-package mage.cards.s;
-
-import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.common.TapSourceCost;
-import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.OneShotEffect;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.choices.ChoiceColor;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
-import mage.filter.predicate.mageobject.ColorPredicate;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.common.TargetOpponent;
-
-/**
- *
- * @author jeffwadsworth
- */
-public final class ScryingGlass extends CardImpl {
-
- public ScryingGlass(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
-
- // {3}, {tap}: Choose a number greater than 0 and a color. Target opponent reveals his or her hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScryingGlassEffect(), new ManaCostsImpl("{3}"));
- ability.addCost(new TapSourceCost());
- ability.addTarget(new TargetOpponent());
- this.addAbility(ability);
-
- }
-
- public ScryingGlass(final ScryingGlass card) {
- super(card);
- }
-
- @Override
- public ScryingGlass copy() {
- return new ScryingGlass(this);
- }
-}
-
-class ScryingGlassEffect extends OneShotEffect {
-
- public ScryingGlassEffect() {
- super(Outcome.Neutral);
- staticText = "Choose a number greater than 0 and a color. Target opponent reveals his or her hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card";
- }
-
- public ScryingGlassEffect(final ScryingGlassEffect effect) {
- super(effect);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- Player targetOpponent = game.getPlayer(source.getFirstTarget());
- ChoiceColor color = new ChoiceColor();
- int amount = 0;
- if (controller != null
- && targetOpponent != null) {
- amount = controller.getAmount(1, Integer.MAX_VALUE, "Choose a number", game);
- controller.choose(Outcome.Discard, color, game);
- FilterCard filter = new FilterCard();
- filter.add(new ColorPredicate(color.getColor()));
- targetOpponent.revealCards(source, targetOpponent.getHand(), game);
- if (targetOpponent.getHand().count(filter, game) == amount) {
- game.informPlayers(controller.getName() + " has chosen the exact number and color of the revealed cards from " + targetOpponent.getName() + "'s hand. They draw a card.");
- controller.drawCards(1, game);
- return true;
- } else {
- game.informPlayers(controller.getName() + " has chosen incorrectly and will not draw a card.");
- }
- }
- return false;
- }
-
- @Override
- public ScryingGlassEffect copy() {
- return new ScryingGlassEffect(this);
- }
-}
+package mage.cards.s;
+
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.common.TapSourceCost;
+import mage.abilities.costs.mana.ManaCostsImpl;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.choices.ChoiceColor;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.filter.predicate.mageobject.ColorPredicate;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.common.TargetOpponent;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public final class ScryingGlass extends CardImpl {
+
+ public ScryingGlass(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
+
+ // {3}, {tap}: Choose a number greater than 0 and a color. Target opponent reveals their hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card.
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ScryingGlassEffect(), new ManaCostsImpl("{3}"));
+ ability.addCost(new TapSourceCost());
+ ability.addTarget(new TargetOpponent());
+ this.addAbility(ability);
+
+ }
+
+ public ScryingGlass(final ScryingGlass card) {
+ super(card);
+ }
+
+ @Override
+ public ScryingGlass copy() {
+ return new ScryingGlass(this);
+ }
+}
+
+class ScryingGlassEffect extends OneShotEffect {
+
+ public ScryingGlassEffect() {
+ super(Outcome.Neutral);
+ staticText = "Choose a number greater than 0 and a color. Target opponent reveals their hand. If that opponent reveals exactly the chosen number of cards of the chosen color, you draw a card";
+ }
+
+ public ScryingGlassEffect(final ScryingGlassEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Player targetOpponent = game.getPlayer(source.getFirstTarget());
+ ChoiceColor color = new ChoiceColor();
+ int amount = 0;
+ if (controller != null
+ && targetOpponent != null) {
+ amount = controller.getAmount(1, Integer.MAX_VALUE, "Choose a number", game);
+ controller.choose(Outcome.Discard, color, game);
+ FilterCard filter = new FilterCard();
+ filter.add(new ColorPredicate(color.getColor()));
+ targetOpponent.revealCards(source, targetOpponent.getHand(), game);
+ if (targetOpponent.getHand().count(filter, game) == amount) {
+ game.informPlayers(controller.getName() + " has chosen the exact number and color of the revealed cards from " + targetOpponent.getName() + "'s hand. They draw a card.");
+ controller.drawCards(1, game);
+ return true;
+ } else {
+ game.informPlayers(controller.getName() + " has chosen incorrectly and will not draw a card.");
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public ScryingGlassEffect copy() {
+ return new ScryingGlassEffect(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SearchForSurvivors.java b/Mage.Sets/src/mage/cards/s/SearchForSurvivors.java
index 278beadcfac..d961db7e4a9 100644
--- a/Mage.Sets/src/mage/cards/s/SearchForSurvivors.java
+++ b/Mage.Sets/src/mage/cards/s/SearchForSurvivors.java
@@ -1,104 +1,104 @@
-package mage.cards.s;
-
-import java.util.Arrays;
-import java.util.UUID;
-import mage.abilities.Ability;
-import mage.abilities.effects.OneShotEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.cards.Cards;
-import mage.cards.CardsImpl;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.Zone;
-import mage.game.Game;
-import mage.players.Player;
-import mage.util.RandomUtil;
-
-/**
- *
- * @author jeffwadsworth
- */
-
-/*
- The card is chosen at random, so the computer just picks a card at random from
- the controller's graveyard. Devs, feel free to set up something else...
- */
-public final class SearchForSurvivors extends CardImpl {
-
- public SearchForSurvivors(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
-
- // Reorder your graveyard at random. An opponent chooses a card at random in your graveyard. If it's a creature card, put it onto the battlefield. Otherwise, exile it.
- this.getSpellAbility().addEffect(new SearchForSurvivorsEffect());
-
- }
-
- public SearchForSurvivors(final SearchForSurvivors card) {
- super(card);
- }
-
- @Override
- public SearchForSurvivors copy() {
- return new SearchForSurvivors(this);
- }
-}
-
-class SearchForSurvivorsEffect extends OneShotEffect {
-
- public SearchForSurvivorsEffect() {
- super(Outcome.PutCardInPlay);
- this.staticText = "Reorder your graveyard at random. "
- + "An opponent chooses a card at random in your graveyard. "
- + "If it's a creature card, put it onto the battlefield. "
- + "Otherwise, exile it";
- }
-
- public SearchForSurvivorsEffect(final SearchForSurvivorsEffect effect) {
- super(effect);
- }
-
- @Override
- public SearchForSurvivorsEffect copy() {
- return new SearchForSurvivorsEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player controller = game.getPlayer(source.getControllerId());
- if (controller != null) {
- game.informPlayers("The controller of Search for Survivors will have his or her graveyard randomized. "
- + " A card will be chosen at random from the controller's graveyard. "
- + " The result is essentially the same as the card rule");
- // randomly arrange the graveyard
- UUID[] shuffled = controller.getGraveyard().toArray(new UUID[0]);
- for (int n = shuffled.length - 1; n > 0; n--) {
- int r = RandomUtil.nextInt(n + 1);
- UUID temp = shuffled[r];
- shuffled[r] = shuffled[n];
- shuffled[n] = temp;
- }
- controller.getGraveyard().clear();
- controller.getGraveyard().addAll(Arrays.asList(shuffled));
- // end of randomize
- Cards cards = new CardsImpl();
- controller.getGraveyard().getCards(game).forEach((card) -> {
- cards.add(card);
- });
- if (!cards.isEmpty()) {
- Card card = cards.getRandom(game);
- cards.clear();
- cards.add(card);
- controller.revealCards(source, cards, game); // reveal the card randomly chosen.
- if (card.isCreature()) {
- controller.moveCards(card, Zone.BATTLEFIELD, source, game);
- } else {
- controller.moveCards(card, Zone.EXILED, source, game);
- }
- }
- return true;
- }
- return false;
- }
-}
+package mage.cards.s;
+
+import java.util.Arrays;
+import java.util.UUID;
+import mage.abilities.Ability;
+import mage.abilities.effects.OneShotEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.cards.Cards;
+import mage.cards.CardsImpl;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.players.Player;
+import mage.util.RandomUtil;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+
+/*
+ The card is chosen at random, so the computer just picks a card at random from
+ the controller's graveyard. Devs, feel free to set up something else...
+ */
+public final class SearchForSurvivors extends CardImpl {
+
+ public SearchForSurvivors(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}");
+
+ // Reorder your graveyard at random. An opponent chooses a card at random in your graveyard. If it's a creature card, put it onto the battlefield. Otherwise, exile it.
+ this.getSpellAbility().addEffect(new SearchForSurvivorsEffect());
+
+ }
+
+ public SearchForSurvivors(final SearchForSurvivors card) {
+ super(card);
+ }
+
+ @Override
+ public SearchForSurvivors copy() {
+ return new SearchForSurvivors(this);
+ }
+}
+
+class SearchForSurvivorsEffect extends OneShotEffect {
+
+ public SearchForSurvivorsEffect() {
+ super(Outcome.PutCardInPlay);
+ this.staticText = "Reorder your graveyard at random. "
+ + "An opponent chooses a card at random in your graveyard. "
+ + "If it's a creature card, put it onto the battlefield. "
+ + "Otherwise, exile it";
+ }
+
+ public SearchForSurvivorsEffect(final SearchForSurvivorsEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public SearchForSurvivorsEffect copy() {
+ return new SearchForSurvivorsEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller != null) {
+ game.informPlayers("The controller of Search for Survivors will have their graveyard randomized. "
+ + " A card will be chosen at random from the controller's graveyard. "
+ + " The result is essentially the same as the card rule");
+ // randomly arrange the graveyard
+ UUID[] shuffled = controller.getGraveyard().toArray(new UUID[0]);
+ for (int n = shuffled.length - 1; n > 0; n--) {
+ int r = RandomUtil.nextInt(n + 1);
+ UUID temp = shuffled[r];
+ shuffled[r] = shuffled[n];
+ shuffled[n] = temp;
+ }
+ controller.getGraveyard().clear();
+ controller.getGraveyard().addAll(Arrays.asList(shuffled));
+ // end of randomize
+ Cards cards = new CardsImpl();
+ controller.getGraveyard().getCards(game).forEach((card) -> {
+ cards.add(card);
+ });
+ if (!cards.isEmpty()) {
+ Card card = cards.getRandom(game);
+ cards.clear();
+ cards.add(card);
+ controller.revealCards(source, cards, game); // reveal the card randomly chosen.
+ if (card.isCreature()) {
+ controller.moveCards(card, Zone.BATTLEFIELD, source, game);
+ } else {
+ controller.moveCards(card, Zone.EXILED, source, game);
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SecureTheWastes.java b/Mage.Sets/src/mage/cards/s/SecureTheWastes.java
index 8d8e83e6750..2540f72bbeb 100644
--- a/Mage.Sets/src/mage/cards/s/SecureTheWastes.java
+++ b/Mage.Sets/src/mage/cards/s/SecureTheWastes.java
@@ -19,7 +19,7 @@ public final class SecureTheWastes extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{W}");
// create X 1/1 white Warrior creature tokens.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new WarriorToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new WarriorToken(), ManacostVariableValue.instance));
}
public SecureTheWastes(final SecureTheWastes card) {
diff --git a/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java b/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java
index 7ef32df750e..3516ba3642e 100644
--- a/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java
+++ b/Mage.Sets/src/mage/cards/s/SelvalaHeartOfTheWilds.java
@@ -54,7 +54,7 @@ public final class SelvalaHeartOfTheWilds extends CardImpl {
// {G}, {T}: Add X mana in any combination of colors, where X is the greatest power among creatures you control.
ManaEffect manaEffect = new AddManaInAnyCombinationEffect(
- new GreatestPowerAmongControlledCreaturesValue(), rule2,
+ GreatestPowerAmongControlledCreaturesValue.instance, rule2,
ColoredManaSymbol.B, ColoredManaSymbol.U, ColoredManaSymbol.R, ColoredManaSymbol.W, ColoredManaSymbol.G);
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, manaEffect, new ManaCostsImpl("{G}"));
ability.addCost(new TapSourceCost());
diff --git a/Mage.Sets/src/mage/cards/s/Seraph.java b/Mage.Sets/src/mage/cards/s/Seraph.java
new file mode 100644
index 00000000000..b656237d5dd
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/s/Seraph.java
@@ -0,0 +1,140 @@
+package mage.cards.s;
+
+import java.util.UUID;
+import mage.MageInt;
+import mage.abilities.Ability;
+import mage.abilities.DelayedTriggeredAbility;
+import mage.abilities.common.DealtDamageAndDiedTriggeredAbility;
+import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
+import mage.abilities.effects.Effect;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
+import mage.abilities.effects.common.SacrificeTargetEffect;
+import mage.constants.SubType;
+import mage.abilities.keyword.FlyingAbility;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Duration;
+import mage.constants.Outcome;
+import mage.constants.Zone;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.events.GameEvent.EventType;
+import mage.players.Player;
+import mage.target.targetpointer.FixedTarget;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public final class Seraph extends CardImpl {
+
+ public Seraph(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{W}");
+
+ this.subtype.add(SubType.ANGEL);
+ this.power = new MageInt(4);
+ this.toughness = new MageInt(4);
+
+ // Flying
+ this.addAbility(FlyingAbility.getInstance());
+
+ // Whenever a creature dealt damage by Seraph this turn dies, put that card onto the battlefield under your control at the beginning of the next end step. Sacrifice the creature when you lose control of Seraph.
+ Effect effect = new CreateDelayedTriggeredAbilityEffect(
+ new AtTheBeginOfNextEndStepDelayedTriggeredAbility(
+ new SeraphEffect()));
+ effect.setText("put that card onto the battlefield under your control at the beginning of the next end step. Sacrifice the creature when you lose control of {this}");
+ this.addAbility(new DealtDamageAndDiedTriggeredAbility(effect));
+
+ }
+
+ private Seraph(final Seraph card) {
+ super(card);
+ }
+
+ @Override
+ public Seraph copy() {
+ return new Seraph(this);
+ }
+}
+
+class SeraphEffect extends OneShotEffect {
+
+ SeraphEffect() {
+ super(Outcome.Neutral);
+ staticText = "put that card onto the battlefield under your control. Sacrifice it when you lose control of {this}";
+ }
+
+ SeraphEffect(SeraphEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player controller = game.getPlayer(source.getControllerId());
+ Card creatureCard = game.getCard(targetPointer.getFirst(game, source));
+ if (controller != null
+ && creatureCard != null
+ && game.getState().getZone(creatureCard.getId()) == Zone.GRAVEYARD) { // must be still in the graveyard
+ controller.moveCards(creatureCard, Zone.BATTLEFIELD, source, game, false, false, false, null);
+ OneShotEffect effect = new SacrificeTargetEffect();
+ effect.setText("Sacrifice this if Seraph leaves the battlefield or its current controller loses control of it.");
+ effect.setTargetPointer(new FixedTarget(creatureCard.getId()));
+ SeraphDelayedTriggeredAbility dTA = new SeraphDelayedTriggeredAbility(effect, source.getSourceId());
+ game.addDelayedTriggeredAbility(dTA, source);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public SeraphEffect copy() {
+ return new SeraphEffect(this);
+ }
+}
+
+class SeraphDelayedTriggeredAbility extends DelayedTriggeredAbility {
+
+ UUID seraph;
+
+ SeraphDelayedTriggeredAbility(Effect effect, UUID seraph) {
+ super(effect, Duration.EndOfGame, true);
+ this.seraph = seraph;
+ }
+
+ SeraphDelayedTriggeredAbility(SeraphDelayedTriggeredAbility ability) {
+ super(ability);
+ this.seraph = ability.seraph;
+ }
+
+ @Override
+ public boolean checkEventType(GameEvent event, Game game) {
+ return event.getType() == EventType.LOST_CONTROL
+ || event.getType() == EventType.ZONE_CHANGE;
+ }
+
+ @Override
+ public boolean checkTrigger(GameEvent event, Game game) {
+ if (event.getType() == EventType.LOST_CONTROL
+ && event.getSourceId().equals(seraph)) {
+ return true;
+ }
+ if (event.getType() == EventType.ZONE_CHANGE
+ && event.getTargetId().equals(seraph)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public SeraphDelayedTriggeredAbility copy() {
+ return new SeraphDelayedTriggeredAbility(this);
+ }
+
+ @Override
+ public String getRule() {
+ return "Control of Seraph was lost, sacrifice this.";
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/s/SereneOffering.java b/Mage.Sets/src/mage/cards/s/SereneOffering.java
index b8a0060a5aa..09a48a3deb8 100644
--- a/Mage.Sets/src/mage/cards/s/SereneOffering.java
+++ b/Mage.Sets/src/mage/cards/s/SereneOffering.java
@@ -22,7 +22,7 @@ public final class SereneOffering extends CardImpl {
// Destroy target enchantment. You gain life equal to its converted mana cost.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
- Effect effect = new GainLifeEffect(new TargetConvertedManaCost());
+ Effect effect = new GainLifeEffect(TargetConvertedManaCost.instance);
effect.setText("You gain life equal to its converted mana cost");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetEnchantmentPermanent());
diff --git a/Mage.Sets/src/mage/cards/s/SerraAvatar.java b/Mage.Sets/src/mage/cards/s/SerraAvatar.java
index 49680a7cc62..9fb4458a34c 100644
--- a/Mage.Sets/src/mage/cards/s/SerraAvatar.java
+++ b/Mage.Sets/src/mage/cards/s/SerraAvatar.java
@@ -29,7 +29,7 @@ public final class SerraAvatar extends CardImpl {
this.toughness = new MageInt(0);
// Serra Avatar's power and toughness are each equal to your life total.
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new ControllerLifeCount(), Duration.EndOfGame)));
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(ControllerLifeCount.instance, Duration.EndOfGame)));
// When Serra Avatar is put into a graveyard from anywhere, shuffle it into its owner's library.
this.addAbility(new PutIntoGraveFromAnywhereSourceTriggeredAbility(new ShuffleIntoLibrarySourceEffect()));
diff --git a/Mage.Sets/src/mage/cards/s/SeveredStrands.java b/Mage.Sets/src/mage/cards/s/SeveredStrands.java
index a0e7278361b..523aedf125e 100644
--- a/Mage.Sets/src/mage/cards/s/SeveredStrands.java
+++ b/Mage.Sets/src/mage/cards/s/SeveredStrands.java
@@ -26,7 +26,7 @@ public final class SeveredStrands extends CardImpl {
// You gain life equal to the sacrificed creature's toughness. Destroy target creature an opponent controls.
this.getSpellAbility().addEffect(new GainLifeEffect(
- new SacrificeCostCreaturesToughness(),
+ SacrificeCostCreaturesToughness.instance,
"You gain life equal to the "
+ "sacrificed creature's toughness."
));
diff --git a/Mage.Sets/src/mage/cards/s/ShapeAnew.java b/Mage.Sets/src/mage/cards/s/ShapeAnew.java
index 63a7595fadd..feaef70514d 100644
--- a/Mage.Sets/src/mage/cards/s/ShapeAnew.java
+++ b/Mage.Sets/src/mage/cards/s/ShapeAnew.java
@@ -74,7 +74,7 @@ public final class ShapeAnew extends CardImpl {
if (artifactCard != null) {
targetController.moveCards(artifactCard, Zone.BATTLEFIELD, source, game);
}
- // 1/1/2011: If the first card the player reveals is an artifact card, he or she will still have to shuffle his or her library even though no other cards were revealed this way.
+ // 1/1/2011: If the first card the player reveals is an artifact card, he or she will still have to shuffle their library even though no other cards were revealed this way.
targetController.shuffleLibrary(source, game);
return true;
}
diff --git a/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java b/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java
index 90425abc247..7ce9d8e1525 100644
--- a/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java
+++ b/Mage.Sets/src/mage/cards/s/ShatteredCrypt.java
@@ -29,7 +29,7 @@ public final class ShatteredCrypt extends CardImpl {
Effect effect = new ReturnFromGraveyardToHandTargetEffect();
effect.setText("Return X target creature cards from your graveyard to your hand");
this.getSpellAbility().addEffect(effect);
- this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new LoseLifeSourceControllerEffect(ManacostVariableValue.instance));
this.getSpellAbility().setTargetAdjuster(ShatteredCryptAdjuster.instance);
}
diff --git a/Mage.Sets/src/mage/cards/s/ShiningShoal.java b/Mage.Sets/src/mage/cards/s/ShiningShoal.java
index 79ad6ea8bfb..f4d8b7a9082 100644
--- a/Mage.Sets/src/mage/cards/s/ShiningShoal.java
+++ b/Mage.Sets/src/mage/cards/s/ShiningShoal.java
@@ -44,7 +44,7 @@ public final class ShiningShoal extends CardImpl {
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter), true)));
// The next X damage that a source of your choice would deal to you and/or creatures you control this turn is dealt to any target instead.
- this.getSpellAbility().addEffect(new ShiningShoalRedirectDamageTargetEffect(Duration.EndOfTurn, new ExileFromHandCostCardConvertedMana()));
+ this.getSpellAbility().addEffect(new ShiningShoalRedirectDamageTargetEffect(Duration.EndOfTurn, ExileFromHandCostCardConvertedMana.instance));
this.getSpellAbility().addTarget(new TargetSource());
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/s/SickeningDreams.java b/Mage.Sets/src/mage/cards/s/SickeningDreams.java
index ba51c255802..3a74c9e7eec 100644
--- a/Mage.Sets/src/mage/cards/s/SickeningDreams.java
+++ b/Mage.Sets/src/mage/cards/s/SickeningDreams.java
@@ -30,7 +30,7 @@ public final class SickeningDreams extends CardImpl {
this.getSpellAbility().addCost(new SickeningDreamsAdditionalCost());
// Sickening Dreams deals X damage to each creature and each player.
- this.getSpellAbility().addEffect(new DamageEverythingEffect(new GetXValue(), new FilterCreaturePermanent()));
+ this.getSpellAbility().addEffect(new DamageEverythingEffect(GetXValue.instance, new FilterCreaturePermanent()));
}
public SickeningDreams(final SickeningDreams card) {
diff --git a/Mage.Sets/src/mage/cards/s/SickeningShoal.java b/Mage.Sets/src/mage/cards/s/SickeningShoal.java
index 32b4fb3587f..5bec8f2fe76 100644
--- a/Mage.Sets/src/mage/cards/s/SickeningShoal.java
+++ b/Mage.Sets/src/mage/cards/s/SickeningShoal.java
@@ -40,7 +40,7 @@ public final class SickeningShoal extends CardImpl {
this.addAbility(new AlternativeCostSourceAbility(new ExileFromHandCost(new TargetCardInHand(filter), true)));
// Target creature gets -X/-X until end of turn.
- DynamicValue x = new SignInversionDynamicValue(new ExileFromHandCostCardConvertedMana());
+ DynamicValue x = new SignInversionDynamicValue(ExileFromHandCostCardConvertedMana.instance);
this.getSpellAbility().addEffect(new BoostTargetEffect(x, x, Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/s/SilhanaWayfinder.java b/Mage.Sets/src/mage/cards/s/SilhanaWayfinder.java
index b8ee5abb202..c6aa18b579f 100644
--- a/Mage.Sets/src/mage/cards/s/SilhanaWayfinder.java
+++ b/Mage.Sets/src/mage/cards/s/SilhanaWayfinder.java
@@ -41,7 +41,7 @@ public final class SilhanaWayfinder extends CardImpl {
// When Silhana Wayfinder enters the battlefield, look at the top four cards of your library. You may reveal a creature or land card from among them and put it on top of your library. Put the rest on the bottom of your library in a random order.
this.addAbility(new EntersBattlefieldTriggeredAbility(new LookLibraryAndPickControllerEffect(
new StaticValue(4), false, new StaticValue(1), filter, Zone.LIBRARY, false,
- true, false, Zone.LIBRARY, false, true, false
+ true, true, Zone.LIBRARY, false, true, false
).setText("look at the top four cards of your library. " +
"You may reveal a creature or land card from among them " +
"and put it on top of your library. Put the rest " +
diff --git a/Mage.Sets/src/mage/cards/s/SilklashSpider.java b/Mage.Sets/src/mage/cards/s/SilklashSpider.java
index 0cd6ebd1353..05b44bcf58a 100644
--- a/Mage.Sets/src/mage/cards/s/SilklashSpider.java
+++ b/Mage.Sets/src/mage/cards/s/SilklashSpider.java
@@ -40,7 +40,7 @@ public final class SilklashSpider extends CardImpl {
this.addAbility(ReachAbility.getInstance());
// {X}{G}{G}: Silklash Spider deals X damage to each creature with flying.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new DamageAllEffect(new ManacostVariableValue(), filter),
+ new DamageAllEffect(ManacostVariableValue.instance, filter),
new ManaCostsImpl("{X}{G}{G}")));
}
diff --git a/Mage.Sets/src/mage/cards/s/SkeletalScrying.java b/Mage.Sets/src/mage/cards/s/SkeletalScrying.java
index 712f565e937..558d6319396 100644
--- a/Mage.Sets/src/mage/cards/s/SkeletalScrying.java
+++ b/Mage.Sets/src/mage/cards/s/SkeletalScrying.java
@@ -34,7 +34,7 @@ public final class SkeletalScrying extends CardImpl {
ability.setRuleAtTheTop(true);
this.addAbility(ability);
// You draw X cards and you lose X life.
- this.getSpellAbility().addEffect(new SkeletalScryingEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new SkeletalScryingEffect(ManacostVariableValue.instance));
}
diff --git a/Mage.Sets/src/mage/cards/s/SkitterOfLizards.java b/Mage.Sets/src/mage/cards/s/SkitterOfLizards.java
index 95353e03aa7..b4a9f5a5244 100644
--- a/Mage.Sets/src/mage/cards/s/SkitterOfLizards.java
+++ b/Mage.Sets/src/mage/cards/s/SkitterOfLizards.java
@@ -35,7 +35,7 @@ public final class SkitterOfLizards extends CardImpl {
// Skitter of Lizards enters the battlefield with a +1/+1 counter on it for each time it was kicked.
this.addAbility(new EntersBattlefieldAbility(
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new MultikickerCount(), true),
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), MultikickerCount.instance, true),
"with a +1/+1 counter on it for each time it was kicked"));
}
diff --git a/Mage.Sets/src/mage/cards/s/SkittishValesk.java b/Mage.Sets/src/mage/cards/s/SkittishValesk.java
index 8ba58f3f855..604f9a2e6d0 100644
--- a/Mage.Sets/src/mage/cards/s/SkittishValesk.java
+++ b/Mage.Sets/src/mage/cards/s/SkittishValesk.java
@@ -63,7 +63,7 @@ class SkittishValeskEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
- if (controller != null && permanent != null && !controller.flipCoin(game)) {
+ if (controller != null && permanent != null && !controller.flipCoin(source, game, true)) {
return permanent.turnFaceDown(game, source.getControllerId());
}
return false;
diff --git a/Mage.Sets/src/mage/cards/s/SkyclawThrash.java b/Mage.Sets/src/mage/cards/s/SkyclawThrash.java
index 3e9bf12b52b..b0a9e3f91b4 100644
--- a/Mage.Sets/src/mage/cards/s/SkyclawThrash.java
+++ b/Mage.Sets/src/mage/cards/s/SkyclawThrash.java
@@ -70,7 +70,7 @@ class SkyclawThrashEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
- if (controller.flipCoin(game) && sourcePermanent != null) {
+ if (controller.flipCoin(source, game, true) && sourcePermanent != null) {
ContinuousEffect effect = new BoostTargetEffect(1, 1, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(sourcePermanent, game));
game.addEffect(effect, source);
diff --git a/Mage.Sets/src/mage/cards/s/Skyscribing.java b/Mage.Sets/src/mage/cards/s/Skyscribing.java
index eba3cb37bf5..cf37f0c5c6d 100644
--- a/Mage.Sets/src/mage/cards/s/Skyscribing.java
+++ b/Mage.Sets/src/mage/cards/s/Skyscribing.java
@@ -20,7 +20,7 @@ public final class Skyscribing extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}{U}");
// Each player draws X cards.
- this.getSpellAbility().addEffect(new DrawCardAllEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardAllEffect(ManacostVariableValue.instance));
// Forecast - {2}{U}, Reveal Skyscribing from your hand: Each player draws a card.
this.addAbility(new ForecastAbility(new DrawCardAllEffect(1), new ManaCostsImpl("{2}{U}")));
}
diff --git a/Mage.Sets/src/mage/cards/s/SmotheringTithe.java b/Mage.Sets/src/mage/cards/s/SmotheringTithe.java
index 4e7023ea4f5..e5da0997464 100644
--- a/Mage.Sets/src/mage/cards/s/SmotheringTithe.java
+++ b/Mage.Sets/src/mage/cards/s/SmotheringTithe.java
@@ -60,7 +60,7 @@ class SmotheringTitheEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
- Player player = game.getPlayer(source.getFirstTarget());
+ Player player = game.getPlayer(targetPointer.getFirst(game, source));
if (player == null) {
return false;
}
diff --git a/Mage.Sets/src/mage/cards/s/SnakeBasket.java b/Mage.Sets/src/mage/cards/s/SnakeBasket.java
index 66862965c22..6cc0acd59d0 100644
--- a/Mage.Sets/src/mage/cards/s/SnakeBasket.java
+++ b/Mage.Sets/src/mage/cards/s/SnakeBasket.java
@@ -25,7 +25,7 @@ public final class SnakeBasket extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
// {X}, Sacrifice Snake Basket: create X 1/1 green Snake creature tokens. Activate this ability only any time you could cast a sorcery.
- Effect effect = new CreateTokenEffect(new SnakeToken(), new ManacostVariableValue());
+ Effect effect = new CreateTokenEffect(new SnakeToken(), ManacostVariableValue.instance);
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/s/SokenzanSpellblade.java b/Mage.Sets/src/mage/cards/s/SokenzanSpellblade.java
index fda9d9d9987..56e925fe0ce 100644
--- a/Mage.Sets/src/mage/cards/s/SokenzanSpellblade.java
+++ b/Mage.Sets/src/mage/cards/s/SokenzanSpellblade.java
@@ -35,7 +35,7 @@ public final class SokenzanSpellblade extends CardImpl {
// Bushido 1
this.addAbility(new BushidoAbility(1));
// {1}{R}: Sokenzan Spellblade gets +X/+0 until end of turn, where X is the number of cards in your hand.
- Effect effect = new BoostSourceEffect(new CardsInControllerHandCount(), new StaticValue(0), Duration.EndOfTurn, true);
+ Effect effect = new BoostSourceEffect(CardsInControllerHandCount.instance, new StaticValue(0), Duration.EndOfTurn, true);
effect.setText("{this} gets +X/+0 until end of turn, where X is the number of cards in your hand");
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
effect, new ManaCostsImpl("{1}{R}")
diff --git a/Mage.Sets/src/mage/cards/s/Soothsaying.java b/Mage.Sets/src/mage/cards/s/Soothsaying.java
index fe88a0035c8..2f67392f252 100644
--- a/Mage.Sets/src/mage/cards/s/Soothsaying.java
+++ b/Mage.Sets/src/mage/cards/s/Soothsaying.java
@@ -27,7 +27,7 @@ public final class Soothsaying extends CardImpl {
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ShuffleLibrarySourceEffect(), new ManaCostsImpl<>("{3}{U}{U}")));
// {X}: Look at the top X cards of your library, then put them back in any order.
- Effect effect = new LookLibraryControllerEffect(new ManacostVariableValue());
+ Effect effect = new LookLibraryControllerEffect(ManacostVariableValue.instance);
effect.setText("Look at the top X cards of your library, then put them back in any order");
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl<>("X")));
}
diff --git a/Mage.Sets/src/mage/cards/s/SophicCentaur.java b/Mage.Sets/src/mage/cards/s/SophicCentaur.java
index d28ffa11afa..76ed6c4d03f 100644
--- a/Mage.Sets/src/mage/cards/s/SophicCentaur.java
+++ b/Mage.Sets/src/mage/cards/s/SophicCentaur.java
@@ -33,7 +33,7 @@ public final class SophicCentaur extends CardImpl {
this.toughness = new MageInt(1);
// {2}{G}{G}, {tap}, Discard a card: You gain 2 life for each card in your hand.
- DynamicValue lifeToGainAmount = new MultipliedValue(new CardsInControllerHandCount(), 2);
+ DynamicValue lifeToGainAmount = new MultipliedValue(CardsInControllerHandCount.instance, 2);
Effect effect = new GainLifeEffect(lifeToGainAmount);
effect.setText("You gain 2 life for each card in your hand");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{2}{G}{G}"));
diff --git a/Mage.Sets/src/mage/cards/s/SoramaroFirstToDream.java b/Mage.Sets/src/mage/cards/s/SoramaroFirstToDream.java
index d197ae5806d..62a0867b8b0 100644
--- a/Mage.Sets/src/mage/cards/s/SoramaroFirstToDream.java
+++ b/Mage.Sets/src/mage/cards/s/SoramaroFirstToDream.java
@@ -39,7 +39,7 @@ public final class SoramaroFirstToDream extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// Soramaro, First to Dream's power and toughness are each equal to the number of cards in your hand.
- DynamicValue xValue= new CardsInControllerHandCount();
+ DynamicValue xValue= CardsInControllerHandCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame)));
// {4}, Return a land you control to its owner's hand: Draw a card.
diff --git a/Mage.Sets/src/mage/cards/s/SoulStrings.java b/Mage.Sets/src/mage/cards/s/SoulStrings.java
index 4dc5d880609..5ae9b10d29d 100644
--- a/Mage.Sets/src/mage/cards/s/SoulStrings.java
+++ b/Mage.Sets/src/mage/cards/s/SoulStrings.java
@@ -23,7 +23,7 @@ public final class SoulStrings extends CardImpl {
// Return two target creature cards from your graveyard to your hand unless any player pays {X}.
Effect effect = new DoUnlessAnyPlayerPaysEffect(
- new ReturnFromGraveyardToHandTargetEffect(), new ManacostVariableValue());
+ new ReturnFromGraveyardToHandTargetEffect(), ManacostVariableValue.instance);
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(2, new FilterCreatureCard("creature cards from your graveyard")));
}
diff --git a/Mage.Sets/src/mage/cards/s/SpellContortion.java b/Mage.Sets/src/mage/cards/s/SpellContortion.java
index aab49c9ab4f..fd89cb7298f 100644
--- a/Mage.Sets/src/mage/cards/s/SpellContortion.java
+++ b/Mage.Sets/src/mage/cards/s/SpellContortion.java
@@ -29,7 +29,7 @@ public final class SpellContortion extends CardImpl {
// Counter target spell unless its controller pays {2}. Draw a card for each time Spell Contortion was kicked.
this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new GenericManaCost(2)));
- this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(new MultikickerCount()));
+ this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(MultikickerCount.instance));
this.getSpellAbility().addTarget(new TargetSpell());
}
diff --git a/Mage.Sets/src/mage/cards/s/SphinxsRevelation.java b/Mage.Sets/src/mage/cards/s/SphinxsRevelation.java
index 4658f434502..9a982e8c060 100644
--- a/Mage.Sets/src/mage/cards/s/SphinxsRevelation.java
+++ b/Mage.Sets/src/mage/cards/s/SphinxsRevelation.java
@@ -21,7 +21,7 @@ public final class SphinxsRevelation extends CardImpl {
// You gain X life and draw X cards.
- ManacostVariableValue manaX = new ManacostVariableValue();
+ ManacostVariableValue manaX = ManacostVariableValue.instance;
this.getSpellAbility().addEffect(new GainLifeEffect(manaX));
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(manaX));
}
diff --git a/Mage.Sets/src/mage/cards/s/SpiralingEmbers.java b/Mage.Sets/src/mage/cards/s/SpiralingEmbers.java
index 68696268cab..f6b5adc9204 100644
--- a/Mage.Sets/src/mage/cards/s/SpiralingEmbers.java
+++ b/Mage.Sets/src/mage/cards/s/SpiralingEmbers.java
@@ -23,7 +23,7 @@ public final class SpiralingEmbers extends CardImpl {
// Spiraling Embers deals damage to any target equal to the number of cards in your hand.
- Effect effect = new DamageTargetEffect(new CardsInControllerHandCount());
+ Effect effect = new DamageTargetEffect(CardsInControllerHandCount.instance);
effect.setText("{this} deals damage to any target equal to the number of cards in your hand.");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/s/SpiritOfTheSpires.java b/Mage.Sets/src/mage/cards/s/SpiritOfTheSpires.java
index 56fcac28566..796e7540afa 100644
--- a/Mage.Sets/src/mage/cards/s/SpiritOfTheSpires.java
+++ b/Mage.Sets/src/mage/cards/s/SpiritOfTheSpires.java
@@ -13,6 +13,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import java.util.UUID;
+import mage.abilities.effects.Effect;
/**
* @author TheElk801
@@ -20,7 +21,7 @@ import java.util.UUID;
public final class SpiritOfTheSpires extends CardImpl {
private static final FilterCreaturePermanent filter
- = new FilterCreaturePermanent("creatures you control with flying");
+ = new FilterCreaturePermanent();
static {
filter.add(new AbilityPredicate(FlyingAbility.class));
@@ -37,9 +38,11 @@ public final class SpiritOfTheSpires extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Other creatures you control with flying get +0/+1.
- this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
+ Effect effect = new BoostControlledEffect(
0, 1, Duration.WhileOnBattlefield, filter, true
- )));
+ );
+ effect.setText("Other creatures you control with flying get +0/+1");
+ this.addAbility(new SimpleStaticAbility(effect));
}
private SpiritOfTheSpires(final SpiritOfTheSpires card) {
diff --git a/Mage.Sets/src/mage/cards/s/SpontaneousGeneration.java b/Mage.Sets/src/mage/cards/s/SpontaneousGeneration.java
index eab38e464ee..6820a1e7ddb 100644
--- a/Mage.Sets/src/mage/cards/s/SpontaneousGeneration.java
+++ b/Mage.Sets/src/mage/cards/s/SpontaneousGeneration.java
@@ -19,7 +19,7 @@ public final class SpontaneousGeneration extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{G}");
// Create a 1/1 green Saproling creature token for each card in your hand.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), new CardsInControllerHandCount()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), CardsInControllerHandCount.instance));
}
public SpontaneousGeneration(final SpontaneousGeneration card) {
diff --git a/Mage.Sets/src/mage/cards/s/SpringjackPasture.java b/Mage.Sets/src/mage/cards/s/SpringjackPasture.java
index c5f7f6a91ab..d4ba3405d73 100644
--- a/Mage.Sets/src/mage/cards/s/SpringjackPasture.java
+++ b/Mage.Sets/src/mage/cards/s/SpringjackPasture.java
@@ -49,12 +49,12 @@ public final class SpringjackPasture extends CardImpl {
// {tap}, Sacrifice X Goats: Add X mana of any one color. You gain X life.
ability = new DynamicManaAbility(
new Mana(0,0,0,0,0,0,1,0),
- new GetXValue(),
+ GetXValue.instance,
new TapSourceCost(),
"Add X mana of any one color",
true);
ability.addCost(new SacrificeXTargetCost(filter));
- ability.addEffect(new GainLifeEffect(new GetXValue()));
+ ability.addEffect(new GainLifeEffect(GetXValue.instance));
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/s/SquallLine.java b/Mage.Sets/src/mage/cards/s/SquallLine.java
index b2b8c822011..37e98c9e647 100644
--- a/Mage.Sets/src/mage/cards/s/SquallLine.java
+++ b/Mage.Sets/src/mage/cards/s/SquallLine.java
@@ -27,7 +27,7 @@ public final class SquallLine extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{G}{G}");
// Squall Line deals X damage to each creature with flying and each player.
- this.getSpellAbility().addEffect(new DamageEverythingEffect(new ManacostVariableValue(), filter)); }
+ this.getSpellAbility().addEffect(new DamageEverythingEffect(ManacostVariableValue.instance, filter)); }
public SquallLine(final SquallLine card) {
super(card);
diff --git a/Mage.Sets/src/mage/cards/s/SqueesRevenge.java b/Mage.Sets/src/mage/cards/s/SqueesRevenge.java
index b999d689034..f30ec04673e 100644
--- a/Mage.Sets/src/mage/cards/s/SqueesRevenge.java
+++ b/Mage.Sets/src/mage/cards/s/SqueesRevenge.java
@@ -56,7 +56,7 @@ class SqueesRevengeEffect extends OneShotEffect {
int number = player.announceXMana(0, Integer.MAX_VALUE, "Choose how many times to flip a coin", game, source);
game.informPlayers(player.getLogName() + " chooses " + number + '.');
for(int i = 0; i < number; i++) {
- if(!player.flipCoin(game)) {
+ if(!player.flipCoin(source, game, true)) {
return true;
}
}
diff --git a/Mage.Sets/src/mage/cards/s/Starstorm.java b/Mage.Sets/src/mage/cards/s/Starstorm.java
index 1d74ac89d2e..bdf7d1c097b 100644
--- a/Mage.Sets/src/mage/cards/s/Starstorm.java
+++ b/Mage.Sets/src/mage/cards/s/Starstorm.java
@@ -22,7 +22,7 @@ public final class Starstorm extends CardImpl {
// Starstorm deals X damage to each creature.
- this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), new FilterCreaturePermanent()));
+ this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, new FilterCreaturePermanent()));
// Cycling {3}
this.addAbility(new CyclingAbility(new ManaCostsImpl("{3}")));
}
diff --git a/Mage.Sets/src/mage/cards/s/StitchInTime.java b/Mage.Sets/src/mage/cards/s/StitchInTime.java
index 4bafd1b73bc..c1dc506c43c 100644
--- a/Mage.Sets/src/mage/cards/s/StitchInTime.java
+++ b/Mage.Sets/src/mage/cards/s/StitchInTime.java
@@ -52,7 +52,7 @@ class StitchInTimeEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- if (player.flipCoin(game)) {
+ if (player.flipCoin(source, game, true)) {
game.getState().getTurnMods().add(new TurnMod(player.getId(), false));
return true;
}
diff --git a/Mage.Sets/src/mage/cards/s/StormHerd.java b/Mage.Sets/src/mage/cards/s/StormHerd.java
index 9ba7cb1bc33..c2fac4e69c0 100644
--- a/Mage.Sets/src/mage/cards/s/StormHerd.java
+++ b/Mage.Sets/src/mage/cards/s/StormHerd.java
@@ -19,7 +19,7 @@ public final class StormHerd extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{8}{W}{W}");
// create X 1/1 white Pegasus creature tokens with flying, where X is your life total.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new PegasusToken(), new ControllerLifeCount()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new PegasusToken(), ControllerLifeCount.instance));
}
public StormHerd(final StormHerd card) {
diff --git a/Mage.Sets/src/mage/cards/s/StormSeeker.java b/Mage.Sets/src/mage/cards/s/StormSeeker.java
index 63460d878c8..173b24552c7 100644
--- a/Mage.Sets/src/mage/cards/s/StormSeeker.java
+++ b/Mage.Sets/src/mage/cards/s/StormSeeker.java
@@ -20,7 +20,7 @@ public final class StormSeeker extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{3}{G}");
// Storm Seeker deals damage to target player equal to the number of cards in that player's hand.
- Effect effect = new DamageTargetEffect(new CardsInTargetHandCount());
+ Effect effect = new DamageTargetEffect(CardsInTargetHandCount.instance);
effect.setText("{this} deals damage to target player equal to the number of cards in that player's hand.");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayer());
diff --git a/Mage.Sets/src/mage/cards/s/StreamOfLife.java b/Mage.Sets/src/mage/cards/s/StreamOfLife.java
index 97e91d04b33..51924a217bd 100644
--- a/Mage.Sets/src/mage/cards/s/StreamOfLife.java
+++ b/Mage.Sets/src/mage/cards/s/StreamOfLife.java
@@ -20,7 +20,7 @@ public final class StreamOfLife extends CardImpl {
// Target player gains X life.
- this.getSpellAbility().addEffect(new GainLifeTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new GainLifeTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/s/StreetSpasm.java b/Mage.Sets/src/mage/cards/s/StreetSpasm.java
index fa0f2d43e83..e10d340862f 100644
--- a/Mage.Sets/src/mage/cards/s/StreetSpasm.java
+++ b/Mage.Sets/src/mage/cards/s/StreetSpasm.java
@@ -37,10 +37,10 @@ public final class StreetSpasm extends CardImpl {
// Street Spasm deals X damage to target creature without flying you don't control.
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
// Overload {X}{X}{R}{R} (You may cast this spell for its overload cost. If you do, change its text by replacing all instances of "target" with "each.")
- this.addAbility(new OverloadAbility(this, new DamageAllEffect(new ManacostVariableValue(), filter), new ManaCostsImpl("{X}{X}{R}{R}")));
+ this.addAbility(new OverloadAbility(this, new DamageAllEffect(ManacostVariableValue.instance, filter), new ManaCostsImpl("{X}{X}{R}{R}")));
}
public StreetSpasm(final StreetSpasm card) {
diff --git a/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java b/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java
index 48f0586a2bc..73a007d69f0 100644
--- a/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java
+++ b/Mage.Sets/src/mage/cards/s/StrengthOfTheTajuru.java
@@ -49,7 +49,7 @@ enum StrengthOfTheTajuruAdjuster implements TargetAdjuster {
@Override
public void adjustTargets(Ability ability, Game game) {
ability.getTargets().clear();
- int numbTargets = new MultikickerCount().calculate(game, ability, null) + 1;
+ int numbTargets = MultikickerCount.instance.calculate(game, ability, null) + 1;
ability.addTarget(new TargetCreaturePermanent(0, numbTargets));
}
}
diff --git a/Mage.Sets/src/mage/cards/s/StrokeOfGenius.java b/Mage.Sets/src/mage/cards/s/StrokeOfGenius.java
index f9d0145f2cf..8effb656273 100644
--- a/Mage.Sets/src/mage/cards/s/StrokeOfGenius.java
+++ b/Mage.Sets/src/mage/cards/s/StrokeOfGenius.java
@@ -21,7 +21,7 @@ public final class StrokeOfGenius extends CardImpl {
// Target player draws X cards.
- this.getSpellAbility().addEffect(new DrawCardTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DrawCardTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetPlayer());
}
diff --git a/Mage.Sets/src/mage/cards/s/Sturmgeist.java b/Mage.Sets/src/mage/cards/s/Sturmgeist.java
index 6bc161a0d45..f21efdda143 100644
--- a/Mage.Sets/src/mage/cards/s/Sturmgeist.java
+++ b/Mage.Sets/src/mage/cards/s/Sturmgeist.java
@@ -31,7 +31,7 @@ public final class Sturmgeist extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Sturmgeist's power and toughness are each equal to the number of cards in your hand.
- this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(new CardsInControllerHandCount(), Duration.EndOfGame)));
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(CardsInControllerHandCount.instance, Duration.EndOfGame)));
// Whenever Sturmgeist deals combat damage to a player, draw a card.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new DrawCardSourceControllerEffect(1), false));
}
diff --git a/Mage.Sets/src/mage/cards/s/Subdue.java b/Mage.Sets/src/mage/cards/s/Subdue.java
index 63ac77351e7..970e3df7882 100644
--- a/Mage.Sets/src/mage/cards/s/Subdue.java
+++ b/Mage.Sets/src/mage/cards/s/Subdue.java
@@ -24,7 +24,7 @@ public final class Subdue extends CardImpl {
// Prevent all combat damage that would be dealt by target creature this turn. That creature gets +0/+X until end of turn, where X is its converted mana cost.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new PreventDamageByTargetEffect(Duration.EndOfTurn, true));
- this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), new TargetConvertedManaCost(), Duration.EndOfTurn, true)
+ this.getSpellAbility().addEffect(new BoostTargetEffect(new StaticValue(0), TargetConvertedManaCost.instance, Duration.EndOfTurn, true)
.setText("That creature gets +0/+X until end of turn, where X is its converted mana cost"));
}
diff --git a/Mage.Sets/src/mage/cards/s/SubterraneanHangar.java b/Mage.Sets/src/mage/cards/s/SubterraneanHangar.java
index 9676c73977b..9ddc675a34b 100644
--- a/Mage.Sets/src/mage/cards/s/SubterraneanHangar.java
+++ b/Mage.Sets/src/mage/cards/s/SubterraneanHangar.java
@@ -34,7 +34,7 @@ public final class SubterraneanHangar extends CardImpl {
// {tap}, Remove any number of storage counters from Subterranean Hangar: Add {B} for each storage counter removed this way.
Ability ability = new DynamicManaAbility(
Mana.BlackMana(1),
- new RemovedCountersForCostValue(),
+ RemovedCountersForCostValue.instance,
new TapSourceCost(),
"Add {B} for each storage counter removed this way",
true, new CountersSourceCount(CounterType.STORAGE));
diff --git a/Mage.Sets/src/mage/cards/s/SuddenImpact.java b/Mage.Sets/src/mage/cards/s/SuddenImpact.java
index b3affd23630..6f889719a28 100644
--- a/Mage.Sets/src/mage/cards/s/SuddenImpact.java
+++ b/Mage.Sets/src/mage/cards/s/SuddenImpact.java
@@ -21,7 +21,7 @@ public final class SuddenImpact extends CardImpl {
// Sudden Impact deals damage to target player equal to the number of cards in that player's hand.
- Effect effect = new DamageTargetEffect(new CardsInTargetHandCount());
+ Effect effect = new DamageTargetEffect(CardsInTargetHandCount.instance);
effect.setText("{this} deals damage to target player equal to the number of cards in that player's hand.");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPlayer());
diff --git a/Mage.Sets/src/mage/cards/s/SummaryJudgment.java b/Mage.Sets/src/mage/cards/s/SummaryJudgment.java
index 87c6989019e..5e2cc2ee4ba 100644
--- a/Mage.Sets/src/mage/cards/s/SummaryJudgment.java
+++ b/Mage.Sets/src/mage/cards/s/SummaryJudgment.java
@@ -51,7 +51,7 @@ class SummaryJudgementEffect extends OneShotEffect {
SummaryJudgementEffect() {
super(Outcome.Benefit);
staticText = "{this} deals 3 damage to target tapped creature." +
- "
Addendum — f you cast this spell during your main phase, " +
+ "
Addendum — If you cast this spell during your main phase, " +
"it deals 5 damage to that creature instead.";
}
diff --git a/Mage.Sets/src/mage/cards/s/SunDroplet.java b/Mage.Sets/src/mage/cards/s/SunDroplet.java
index 6ff432b37d1..08b3f4e79c8 100644
--- a/Mage.Sets/src/mage/cards/s/SunDroplet.java
+++ b/Mage.Sets/src/mage/cards/s/SunDroplet.java
@@ -1,22 +1,15 @@
package mage.cards.s;
-import java.util.UUID;
-import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
-import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.common.RemoveCountersSourceCost;
-import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
-import mage.abilities.effects.Effect;
-import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
-import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
@@ -24,26 +17,28 @@ import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
+import java.util.UUID;
+
/**
- *
* @author LevelX2
*/
public final class SunDroplet extends CardImpl {
public SunDroplet(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// Whenever you're dealt damage, put that many charge counters on Sun Droplet.
this.addAbility(new SunDropletTriggeredAbility());
+
// At the beginning of each upkeep, you may remove a charge counter from Sun Droplet. If you do, you gain 1 life.
- //TODO this shouldn't be conditional because you can respond to the trigger by adding counters.
- Effect effect = new DoIfCostPaid(new GainLifeEffect(1), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance(1)));
- this.addAbility(new ConditionalInterveningIfTriggeredAbility(new BeginningOfUpkeepTriggeredAbility(effect, TargetController.ANY, false),
- new SourceHasCounterCondition(CounterType.CHARGE, 1),
- "At the beginning of each upkeep, you may remove a charge counter from Sun Droplet. If you do, you gain 1 life"));
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(
+ new DoIfCostPaid(
+ new GainLifeEffect(1), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance())
+ ), TargetController.ANY, false
+ ));
}
- public SunDroplet(final SunDroplet card) {
+ private SunDroplet(final SunDroplet card) {
super(card);
}
@@ -55,11 +50,11 @@ public final class SunDroplet extends CardImpl {
class SunDropletTriggeredAbility extends TriggeredAbilityImpl {
- public SunDropletTriggeredAbility() {
- super(Zone.BATTLEFIELD, new SunDropletEffect(), false);
+ SunDropletTriggeredAbility() {
+ super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance()), false);
}
- public SunDropletTriggeredAbility(final SunDropletTriggeredAbility ability) {
+ private SunDropletTriggeredAbility(final SunDropletTriggeredAbility ability) {
super(ability);
}
@@ -76,7 +71,8 @@ class SunDropletTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(this.getControllerId())) {
- this.getEffects().get(0).setValue("damageAmount", event.getAmount());
+ this.getEffects().clear();
+ this.addEffect(new AddCountersSourceEffect(CounterType.CHARGE.createInstance(event.getAmount())));
return true;
}
return false;
@@ -87,24 +83,3 @@ class SunDropletTriggeredAbility extends TriggeredAbilityImpl {
return "Whenever you're dealt damage, put that many charge counters on {this}.";
}
}
-
-class SunDropletEffect extends OneShotEffect {
-
- public SunDropletEffect() {
- super(Outcome.Benefit);
- }
-
- public SunDropletEffect(final SunDropletEffect effect) {
- super(effect);
- }
-
- @Override
- public SunDropletEffect copy() {
- return new SunDropletEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- return new AddCountersSourceEffect(CounterType.CHARGE.createInstance((Integer) this.getValue("damageAmount"))).apply(game, source);
- }
-}
diff --git a/Mage.Sets/src/mage/cards/s/SunbringersTouch.java b/Mage.Sets/src/mage/cards/s/SunbringersTouch.java
index d1a1104cd42..1cca7cfa8c3 100644
--- a/Mage.Sets/src/mage/cards/s/SunbringersTouch.java
+++ b/Mage.Sets/src/mage/cards/s/SunbringersTouch.java
@@ -30,7 +30,7 @@ public final class SunbringersTouch extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{G}{G}");
// Bolster X, where X is the number of cards in your hand.
- this.getSpellAbility().addEffect(new BolsterEffect(new CardsInControllerHandCount()));
+ this.getSpellAbility().addEffect(new BolsterEffect(CardsInControllerHandCount.instance));
// Each creature you control with a +1/+1 counter on it gains trample until end of turn.
Effect effect = new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filter);
diff --git a/Mage.Sets/src/mage/cards/s/SupplyDemand.java b/Mage.Sets/src/mage/cards/s/SupplyDemand.java
index 8085fd8f4ea..a9ca239a289 100644
--- a/Mage.Sets/src/mage/cards/s/SupplyDemand.java
+++ b/Mage.Sets/src/mage/cards/s/SupplyDemand.java
@@ -31,7 +31,7 @@ public final class SupplyDemand extends SplitCard {
// Supply
// create X 1/1 green Saproling creature tokens.
- getLeftHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), new ManacostVariableValue()));
+ getLeftHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new SaprolingToken(), ManacostVariableValue.instance));
// Demand
// Search your library for a multicolored card, reveal it, and put it into your hand. Then shuffle your library.
diff --git a/Mage.Sets/src/mage/cards/s/SurgeOfStrength.java b/Mage.Sets/src/mage/cards/s/SurgeOfStrength.java
index 7a9a5d79248..d71e125bb65 100644
--- a/Mage.Sets/src/mage/cards/s/SurgeOfStrength.java
+++ b/Mage.Sets/src/mage/cards/s/SurgeOfStrength.java
@@ -42,7 +42,7 @@ public final class SurgeOfStrength extends CardImpl {
Effect effect = new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
effect.setText("Target creature gains trample");
this.getSpellAbility().addEffect(effect);
- effect = new BoostTargetEffect(new TargetConvertedManaCost(), new StaticValue(0), Duration.EndOfTurn, true);
+ effect = new BoostTargetEffect(TargetConvertedManaCost.instance, new StaticValue(0), Duration.EndOfTurn, true);
effect.setText("and gets +X/+0 until end of turn, where X is that creature's converted mana cost");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
diff --git a/Mage.Sets/src/mage/cards/s/SwallowingPlague.java b/Mage.Sets/src/mage/cards/s/SwallowingPlague.java
index 9b17abee582..7392aca66bb 100644
--- a/Mage.Sets/src/mage/cards/s/SwallowingPlague.java
+++ b/Mage.Sets/src/mage/cards/s/SwallowingPlague.java
@@ -23,8 +23,8 @@ public final class SwallowingPlague extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{B}{B}");
this.subtype.add(SubType.ARCANE);
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
- this.getSpellAbility().addEffect(new GainLifeEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
+ this.getSpellAbility().addEffect(new GainLifeEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/s/SwellOfCourage.java b/Mage.Sets/src/mage/cards/s/SwellOfCourage.java
index 372a09d6c5a..457048a651c 100644
--- a/Mage.Sets/src/mage/cards/s/SwellOfCourage.java
+++ b/Mage.Sets/src/mage/cards/s/SwellOfCourage.java
@@ -24,7 +24,7 @@ public final class SwellOfCourage extends CardImpl {
// Creatures you control get +2/+2 until end of turn.
this.getSpellAbility().addEffect(new BoostControlledEffect(2,2, Duration.EndOfTurn));
// Reinforce X-{X}{W}{W}
- this.addAbility(new ReinforceAbility(new ManacostVariableValue(), new ManaCostsImpl("{X}{W}{W}")));
+ this.addAbility(new ReinforceAbility(ManacostVariableValue.instance, new ManaCostsImpl("{X}{W}{W}")));
}
public SwellOfCourage(final SwellOfCourage card) {
diff --git a/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java b/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java
index d0035791005..9968d14771f 100644
--- a/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java
+++ b/Mage.Sets/src/mage/cards/s/SwordOfWarAndPeace.java
@@ -69,7 +69,7 @@ class SwordOfWarAndPeaceAbility extends TriggeredAbilityImpl {
public SwordOfWarAndPeaceAbility() {
super(Zone.BATTLEFIELD, new SwordOfWarAndPeaceDamageEffect());
- this.addEffect(new GainLifeEffect(new CardsInControllerHandCount()));
+ this.addEffect(new GainLifeEffect(CardsInControllerHandCount.instance));
}
public SwordOfWarAndPeaceAbility(final SwordOfWarAndPeaceAbility ability) {
diff --git a/Mage.Sets/src/mage/cards/s/SylvanYeti.java b/Mage.Sets/src/mage/cards/s/SylvanYeti.java
index 688718f865e..d402b7450b6 100644
--- a/Mage.Sets/src/mage/cards/s/SylvanYeti.java
+++ b/Mage.Sets/src/mage/cards/s/SylvanYeti.java
@@ -27,7 +27,7 @@ public final class SylvanYeti extends CardImpl {
this.toughness = new MageInt(4);
// Sylvan Yeti's power is equal to the number of cards in your hand.
- Effect effect = new SetPowerSourceEffect(new CardsInControllerHandCount(), Duration.EndOfGame);
+ Effect effect = new SetPowerSourceEffect(CardsInControllerHandCount.instance, Duration.EndOfGame);
this.addAbility(new SimpleStaticAbility(Zone.ALL, effect));
}
diff --git a/Mage.Sets/src/mage/cards/t/TalonOfPain.java b/Mage.Sets/src/mage/cards/t/TalonOfPain.java
index 0558c9b9333..b6fa0d37241 100644
--- a/Mage.Sets/src/mage/cards/t/TalonOfPain.java
+++ b/Mage.Sets/src/mage/cards/t/TalonOfPain.java
@@ -42,7 +42,7 @@ public final class TalonOfPain extends CardImpl {
this.addAbility(new TalonOfPainTriggeredAbility());
// {X}, {T}, Remove X charge counters from Talon of Pain: Talon of Pain deals X damage to any target.
- Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(new ManacostVariableValue()), new ManaCostsImpl("{X}"));
+ Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(ManacostVariableValue.instance), new ManaCostsImpl("{X}"));
ability.addCost(new TapSourceCost());
ability.addCost(new TalonOfPainRemoveVariableCountersSourceCost(CounterType.CHARGE.createInstance()));
ability.addTarget(new TargetAnyTarget());
diff --git a/Mage.Sets/src/mage/cards/t/TavernSwindler.java b/Mage.Sets/src/mage/cards/t/TavernSwindler.java
index 0c5645c8023..e816947ea23 100644
--- a/Mage.Sets/src/mage/cards/t/TavernSwindler.java
+++ b/Mage.Sets/src/mage/cards/t/TavernSwindler.java
@@ -62,7 +62,7 @@ class TavernSwindlerEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
game.informPlayers(controller.getLogName() + " got " + controller.gainLife(6, game, source)+ " live");
}
}
diff --git a/Mage.Sets/src/mage/cards/t/TectonicBreak.java b/Mage.Sets/src/mage/cards/t/TectonicBreak.java
index c8c47de18c9..14bd9c35651 100644
--- a/Mage.Sets/src/mage/cards/t/TectonicBreak.java
+++ b/Mage.Sets/src/mage/cards/t/TectonicBreak.java
@@ -19,7 +19,7 @@ public final class TectonicBreak extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{R}{R}");
// Each player sacrifices X lands.
- this.getSpellAbility().addEffect(new SacrificeAllEffect(new ManacostVariableValue(), new FilterControlledLandPermanent("lands")));
+ this.getSpellAbility().addEffect(new SacrificeAllEffect(ManacostVariableValue.instance, new FilterControlledLandPermanent("lands")));
}
public TectonicBreak(final TectonicBreak card) {
diff --git a/Mage.Sets/src/mage/cards/t/Temper.java b/Mage.Sets/src/mage/cards/t/Temper.java
index 602872e0853..b0bdd776b14 100644
--- a/Mage.Sets/src/mage/cards/t/Temper.java
+++ b/Mage.Sets/src/mage/cards/t/Temper.java
@@ -26,7 +26,7 @@ public final class Temper extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{1}{W}");
// Prevent the next X damage that would be dealt to target creature this turn. For each 1 damage prevented this way, put a +1/+1 counter on that creature.
- this.getSpellAbility().addEffect(new TemperPreventDamageTargetEffect(new ManacostVariableValue(), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new TemperPreventDamageTargetEffect(ManacostVariableValue.instance, Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/t/TeysaKarlov.java b/Mage.Sets/src/mage/cards/t/TeysaKarlov.java
index 461fbb03a52..5b4c94bf5c8 100644
--- a/Mage.Sets/src/mage/cards/t/TeysaKarlov.java
+++ b/Mage.Sets/src/mage/cards/t/TeysaKarlov.java
@@ -33,7 +33,7 @@ public final class TeysaKarlov extends CardImpl {
this.toughness = new MageInt(4);
// If a creature dying causes a triggered ability of a permanent you control to trigger, that ability triggers an additional time.
- this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TeysaKarlovEffect()));
+ this.addAbility(new SimpleStaticAbility(new TeysaKarlovEffect()));
// Creature tokens you control have vigilance and lifelink.
Ability ability = new SimpleStaticAbility(
@@ -89,15 +89,13 @@ class TeysaKarlovEffect extends ReplacementEffectImpl {
if (event instanceof NumberOfTriggersEvent) {
NumberOfTriggersEvent numberOfTriggersEvent = (NumberOfTriggersEvent) event;
if (source.isControlledBy(event.getPlayerId())
- && game.getPermanent(numberOfTriggersEvent.getSourceId()) != null
+ && game.getPermanentOrLKIBattlefield(numberOfTriggersEvent.getSourceId()) != null
&& numberOfTriggersEvent.getSourceEvent() instanceof ZoneChangeEvent) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) numberOfTriggersEvent.getSourceEvent();
- if (zEvent.getFromZone() == Zone.BATTLEFIELD
+ return zEvent.getFromZone() == Zone.BATTLEFIELD
&& zEvent.getToZone() == Zone.GRAVEYARD
&& zEvent.getTarget() != null
- && zEvent.getTarget().isCreature()) {
- return true;
- }
+ && zEvent.getTarget().isCreature();
}
}
return false;
diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfEndor.java b/Mage.Sets/src/mage/cards/t/TheBattleOfEndor.java
index 6c6ee7f1a9a..4362c26c536 100644
--- a/Mage.Sets/src/mage/cards/t/TheBattleOfEndor.java
+++ b/Mage.Sets/src/mage/cards/t/TheBattleOfEndor.java
@@ -32,7 +32,7 @@ public final class TheBattleOfEndor extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{X}{G}{G}{G}");
// Create X 1/1 green Ewok creature tokens.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new EwokToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new EwokToken(), ManacostVariableValue.instance));
// Put X +1/+1 counters on each creature you control.
this.getSpellAbility().addEffect(new TheBattleOfEndorEffect());
diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfGeonosis.java b/Mage.Sets/src/mage/cards/t/TheBattleOfGeonosis.java
index 5c8f41b4c3f..7207f52b1ac 100644
--- a/Mage.Sets/src/mage/cards/t/TheBattleOfGeonosis.java
+++ b/Mage.Sets/src/mage/cards/t/TheBattleOfGeonosis.java
@@ -27,15 +27,15 @@ public final class TheBattleOfGeonosis extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{R}{R}");
// The Battle of Geonosis deals X + 1 damage to each opponent and each creature your opponents control.
- Effect effect = new DamagePlayersEffect(Outcome.Damage, new IntPlusDynamicValue(1, new ManacostVariableValue()), TargetController.OPPONENT);
+ Effect effect = new DamagePlayersEffect(Outcome.Damage, new IntPlusDynamicValue(1, ManacostVariableValue.instance), TargetController.OPPONENT);
effect.setText("The Battle of Geonosis deals X plus 1 damage to each opponent");
this.getSpellAbility().addEffect(effect);
- effect = new DamageAllEffect(new IntPlusDynamicValue(1, new ManacostVariableValue()), new FilterOpponentsCreaturePermanent());
+ effect = new DamageAllEffect(new IntPlusDynamicValue(1, ManacostVariableValue.instance), new FilterOpponentsCreaturePermanent());
effect.setText("and each creature your opponents control");
this.getSpellAbility().addEffect(effect);
// Creatures you control get +X/+0 until end of turn.
- this.getSpellAbility().addEffect(new BoostControlledEffect(new ManacostVariableValue(), new StaticValue(0), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostControlledEffect(ManacostVariableValue.instance, new StaticValue(0), Duration.EndOfTurn));
}
diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfHoth.java b/Mage.Sets/src/mage/cards/t/TheBattleOfHoth.java
index 3ce64d602b5..dda5b9c9b68 100644
--- a/Mage.Sets/src/mage/cards/t/TheBattleOfHoth.java
+++ b/Mage.Sets/src/mage/cards/t/TheBattleOfHoth.java
@@ -19,7 +19,7 @@ public final class TheBattleOfHoth extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{X}{W}{W}{W}");
// Create X 5/5 white artifact AT-AT creature tokens wiht "When this creature dies, create two 1/1 white Trooper creature tokens."
- this.getSpellAbility().addEffect(new CreateTokenEffect(new ATATToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new ATATToken(), ManacostVariableValue.instance));
}
public TheBattleOfHoth(final TheBattleOfHoth card) {
diff --git a/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java b/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java
index 5377a77dc81..90ec0851cdf 100644
--- a/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java
+++ b/Mage.Sets/src/mage/cards/t/TheBattleOfYavin.java
@@ -65,7 +65,7 @@ class TheBattleOfYavinEffect extends OneShotEffect {
return false;
}
- int amount = (new ManacostVariableValue()).calculate(game, source, this);
+ int amount = (ManacostVariableValue.instance).calculate(game, source, this);
if (amount > 0) {
LinkedList sacrifices = new LinkedList<>();
diff --git a/Mage.Sets/src/mage/cards/t/ThoughtDissector.java b/Mage.Sets/src/mage/cards/t/ThoughtDissector.java
index 2238235f421..f8170540896 100644
--- a/Mage.Sets/src/mage/cards/t/ThoughtDissector.java
+++ b/Mage.Sets/src/mage/cards/t/ThoughtDissector.java
@@ -49,7 +49,7 @@ public final class ThoughtDissector extends CardImpl {
class ThoughtDissectorEffect extends OneShotEffect {
- private static final ManacostVariableValue amount = new ManacostVariableValue();
+ private static final ManacostVariableValue amount = ManacostVariableValue.instance;
public ThoughtDissectorEffect() {
super(Outcome.Detriment);
diff --git a/Mage.Sets/src/mage/cards/t/Thud.java b/Mage.Sets/src/mage/cards/t/Thud.java
index 54c775bc203..cdcc431c5ba 100644
--- a/Mage.Sets/src/mage/cards/t/Thud.java
+++ b/Mage.Sets/src/mage/cards/t/Thud.java
@@ -26,7 +26,7 @@ public final class Thud extends CardImpl {
));
// Thud deals damage equal to the sacrificed creature's power to any target.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new SacrificeCostCreaturesPower()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(SacrificeCostCreaturesPower.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java b/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java
index a83deed0d49..5805188ef9e 100644
--- a/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java
+++ b/Mage.Sets/src/mage/cards/t/TibaltTheFiendBlooded.java
@@ -53,7 +53,7 @@ public final class TibaltTheFiendBlooded extends CardImpl {
ability.addEffect(effect);
this.addAbility(ability);
// -4: Tibalt, the Fiend-Blooded deals damage equal to the number of cards in target player's hand to that player.
- effect = new DamageTargetEffect(new CardsInTargetHandCount(), true);
+ effect = new DamageTargetEffect(CardsInTargetHandCount.instance, true);
effect.setText("{this} deals damage equal to the number of cards in target player's hand to that player");
ability = new LoyaltyAbility(effect, -4);
ability.addTarget(new TargetPlayer());
diff --git a/Mage.Sets/src/mage/cards/t/TideOfWar.java b/Mage.Sets/src/mage/cards/t/TideOfWar.java
index 772b8c800d8..6c48d0af6bf 100644
--- a/Mage.Sets/src/mage/cards/t/TideOfWar.java
+++ b/Mage.Sets/src/mage/cards/t/TideOfWar.java
@@ -101,7 +101,7 @@ class TideOfWarEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Set toSacrifice = new HashSet<>();
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
// each blocking creature is sacrificed by its controller
for (CombatGroup combatGroup: game.getCombat().getGroups()) {
for (UUID blockerId: combatGroup.getBlockers()) {
diff --git a/Mage.Sets/src/mage/cards/t/TidehollowSculler.java b/Mage.Sets/src/mage/cards/t/TidehollowSculler.java
index 7b2acc5c855..b1e2bacc962 100644
--- a/Mage.Sets/src/mage/cards/t/TidehollowSculler.java
+++ b/Mage.Sets/src/mage/cards/t/TidehollowSculler.java
@@ -1,4 +1,3 @@
-
package mage.cards.t;
import java.util.UUID;
@@ -32,7 +31,7 @@ import mage.util.CardUtil;
public final class TidehollowSculler extends CardImpl {
public TidehollowSculler(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{W}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{W}{B}");
this.subtype.add(SubType.ZOMBIE);
this.power = new MageInt(2);
@@ -80,23 +79,30 @@ class TidehollowScullerExileEffect extends OneShotEffect {
// 6/7/2013 If Tidehollow Sculler leaves the battlefield before its first ability has resolved,
// its second ability will trigger. This ability will do nothing when it resolves.
// Then its first ability will resolve and exile the chosen card forever.
- Permanent sourcePermanent = (Permanent) source.getSourceObject(game);
- if (controller != null && opponent != null && sourcePermanent != null) {
+ Permanent sourcePermanent = (Permanent) source.getSourcePermanentIfItStillExists(game);
+ if (controller != null
+ && opponent != null
+ && sourcePermanent != null) {
opponent.revealCards(sourcePermanent.getName(), opponent.getHand(), game);
-
TargetCard target = new TargetCard(Zone.HAND, new FilterNonlandCard("nonland card to exile"));
if (controller.choose(Outcome.Exile, opponent.getHand(), target, game)) {
Card card = opponent.getHand().get(target.getFirstTarget(), game);
if (card != null) {
- controller.moveCardToExileWithInfo(card, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.HAND, true);
+ controller.moveCardsToExile(
+ card,
+ source,
+ game,
+ true,
+ CardUtil.getExileZoneId(game,
+ source.getSourceId(),
+ source.getSourceObjectZoneChangeCounter()),
+ sourcePermanent.getIdName());
}
}
-
return true;
}
return false;
}
-
}
class TidehollowScullerLeaveEffect extends OneShotEffect {
@@ -120,8 +126,11 @@ class TidehollowScullerLeaveEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) {
- int zoneChangeCounter = (sourceObject instanceof PermanentToken) ? source.getSourceObjectZoneChangeCounter() : source.getSourceObjectZoneChangeCounter() - 1;
- ExileZone exZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter));
+ int zoneChangeCounter = (sourceObject instanceof PermanentToken)
+ ? source.getSourceObjectZoneChangeCounter()
+ : source.getSourceObjectZoneChangeCounter() - 1;
+ ExileZone exZone = game.getExile().getExileZone(
+ CardUtil.getExileZoneId(game, source.getSourceId(), zoneChangeCounter));
if (exZone != null) {
controller.moveCards(exZone, Zone.HAND, source, game);
}
diff --git a/Mage.Sets/src/mage/cards/t/TishanaVoiceOfThunder.java b/Mage.Sets/src/mage/cards/t/TishanaVoiceOfThunder.java
index 50ec788f1a4..2a83a5105e2 100644
--- a/Mage.Sets/src/mage/cards/t/TishanaVoiceOfThunder.java
+++ b/Mage.Sets/src/mage/cards/t/TishanaVoiceOfThunder.java
@@ -37,7 +37,7 @@ public final class TishanaVoiceOfThunder extends CardImpl {
this.toughness = new MageInt(0);
// Tishana, Voice of Thunder's power and toughness are each equal to the number of cards in your hand.
- DynamicValue xValue = new CardsInControllerHandCount();
+ DynamicValue xValue = CardsInControllerHandCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SetPowerToughnessSourceEffect(xValue, Duration.EndOfGame)));
// You have no maximum hand size.
diff --git a/Mage.Sets/src/mage/cards/t/TitansRevenge.java b/Mage.Sets/src/mage/cards/t/TitansRevenge.java
index 0ce6a02ea83..37529c24697 100644
--- a/Mage.Sets/src/mage/cards/t/TitansRevenge.java
+++ b/Mage.Sets/src/mage/cards/t/TitansRevenge.java
@@ -21,7 +21,7 @@ public final class TitansRevenge extends CardImpl {
// Titan's Revenge deals X damage to any target. Clash with an opponent. If you win, return Titan's Revenge to its owner's hand.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
this.getSpellAbility().addEffect(ClashWinReturnToHandSpellEffect.getInstance());
}
diff --git a/Mage.Sets/src/mage/cards/t/ToilTrouble.java b/Mage.Sets/src/mage/cards/t/ToilTrouble.java
index c3783993f1d..7a18f7047c5 100644
--- a/Mage.Sets/src/mage/cards/t/ToilTrouble.java
+++ b/Mage.Sets/src/mage/cards/t/ToilTrouble.java
@@ -26,7 +26,7 @@ public final class ToilTrouble extends SplitCard {
// Trouble
// Trouble deals damage to target player equal to the number of cards in that player's hand.
- Effect effect = new DamageTargetEffect(new CardsInTargetHandCount());
+ Effect effect = new DamageTargetEffect(CardsInTargetHandCount.instance);
effect.setText("Trouble deals damage to target player equal to the number of cards in that player's hand");
getRightHalfCard().getSpellAbility().addEffect(effect);
getRightHalfCard().getSpellAbility().addTarget(new TargetPlayer());
diff --git a/Mage.Sets/src/mage/cards/t/ToxicDeluge.java b/Mage.Sets/src/mage/cards/t/ToxicDeluge.java
index b3f9b3e9e40..ec64b49f4fa 100644
--- a/Mage.Sets/src/mage/cards/t/ToxicDeluge.java
+++ b/Mage.Sets/src/mage/cards/t/ToxicDeluge.java
@@ -26,7 +26,7 @@ public final class ToxicDeluge extends CardImpl {
// As an additional cost to cast Toxic Deluge, pay X life.
this.getSpellAbility().addCost(new PayVariableLifeCost(true));
// All creatures get -X/-X until end of turn.
- DynamicValue xValue = new SignInversionDynamicValue(new GetXValue());
+ DynamicValue xValue = new SignInversionDynamicValue(GetXValue.instance);
this.getSpellAbility().addEffect(new BoostAllEffect(xValue, xValue, Duration.EndOfTurn, new FilterCreaturePermanent("All creatures"), false,
null, true));
}
diff --git a/Mage.Sets/src/mage/cards/t/TransguildCourier.java b/Mage.Sets/src/mage/cards/t/TransguildCourier.java
index b480250f6bc..2161aa0e94d 100644
--- a/Mage.Sets/src/mage/cards/t/TransguildCourier.java
+++ b/Mage.Sets/src/mage/cards/t/TransguildCourier.java
@@ -1,30 +1,34 @@
package mage.cards.t;
-import java.util.UUID;
import mage.MageInt;
+import mage.abilities.common.SimpleStaticAbility;
+import mage.abilities.effects.common.InfoEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
+import mage.constants.Zone;
+
+import java.util.UUID;
/**
- *
* @author Wehk
*/
public final class TransguildCourier extends CardImpl {
public TransguildCourier(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{4}");
+ super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}");
this.subtype.add(SubType.GOLEM);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
-
+
this.color.setWhite(true);
this.color.setBlue(true);
this.color.setBlack(true);
this.color.setRed(true);
this.color.setGreen(true);
+ this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect("{this} is all colors")));
}
public TransguildCourier(final TransguildCourier card) {
diff --git a/Mage.Sets/src/mage/cards/t/TribalUnity.java b/Mage.Sets/src/mage/cards/t/TribalUnity.java
index bb468b356d0..8d03dd04711 100644
--- a/Mage.Sets/src/mage/cards/t/TribalUnity.java
+++ b/Mage.Sets/src/mage/cards/t/TribalUnity.java
@@ -30,7 +30,7 @@ public final class TribalUnity extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{2}{G}");
// Creatures of the creature type of your choice get +X/+X until end of turn.
- this.getSpellAbility().addEffect(new TribalUnityEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new TribalUnityEffect(ManacostVariableValue.instance));
}
public TribalUnity(final TribalUnity card) {
diff --git a/Mage.Sets/src/mage/cards/t/TropicalStorm.java b/Mage.Sets/src/mage/cards/t/TropicalStorm.java
index b85d7c05d0b..0178952b1a6 100644
--- a/Mage.Sets/src/mage/cards/t/TropicalStorm.java
+++ b/Mage.Sets/src/mage/cards/t/TropicalStorm.java
@@ -31,7 +31,7 @@ public final class TropicalStorm extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{G}");
// Tropical Storm deals X damage to each creature with flying and 1 additional damage to each blue creature.
- this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), filter));
+ this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, filter));
this.getSpellAbility().addEffect(new DamageAllEffect(1, filter2).setText("and 1 additional damage to each blue creature"));
}
diff --git a/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java b/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java
index 5d1a729b304..d6ff2a36a32 100644
--- a/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java
+++ b/Mage.Sets/src/mage/cards/t/TrostaniSelesnyasVoice.java
@@ -77,7 +77,8 @@ class TrostaniSelesnyasVoiceTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
- if (permanent.isCreature()
+ if (permanent != null
+ && permanent.isCreature()
&& permanent.isControlledBy(this.controllerId)
&& !Objects.equals(event.getTargetId(), this.getSourceId())) {
Effect effect = this.getEffects().get(0);
diff --git a/Mage.Sets/src/mage/cards/t/TwoHeadedGiant.java b/Mage.Sets/src/mage/cards/t/TwoHeadedGiant.java
index 996d78d67b4..e786e0bb8e8 100644
--- a/Mage.Sets/src/mage/cards/t/TwoHeadedGiant.java
+++ b/Mage.Sets/src/mage/cards/t/TwoHeadedGiant.java
@@ -69,8 +69,8 @@ class TwoHeadedGiantEffect extends OneShotEffect {
if (player == null) {
return false;
}
- boolean head1 = player.flipCoin(game);
- boolean head2 = player.flipCoin(game);
+ boolean head1 = player.flipCoin(source, game, false);
+ boolean head2 = player.flipCoin(source, game, false);
if (head1 == head2) {
if (head1) {
game.addEffect(new GainAbilitySourceEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn), source);
diff --git a/Mage.Sets/src/mage/cards/u/UnbreakableFormation.java b/Mage.Sets/src/mage/cards/u/UnbreakableFormation.java
index 2c53b53b4a3..62ced3ec1d4 100644
--- a/Mage.Sets/src/mage/cards/u/UnbreakableFormation.java
+++ b/Mage.Sets/src/mage/cards/u/UnbreakableFormation.java
@@ -6,6 +6,7 @@ import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.counter.AddCountersAllEffect;
import mage.abilities.keyword.IndestructibleAbility;
+import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@@ -68,7 +69,7 @@ class UnbreakableFormationEffect extends OneShotEffect {
return false;
}
game.addEffect(new GainAbilityControlledEffect(
- IndestructibleAbility.getInstance(), Duration.EndOfTurn,
+ VigilanceAbility.getInstance(), Duration.EndOfTurn,
StaticFilters.FILTER_PERMANENT_CREATURE
), source);
return new AddCountersAllEffect(
diff --git a/Mage.Sets/src/mage/cards/u/UntamedMight.java b/Mage.Sets/src/mage/cards/u/UntamedMight.java
index 3d887eced9b..9ae6aca3a47 100644
--- a/Mage.Sets/src/mage/cards/u/UntamedMight.java
+++ b/Mage.Sets/src/mage/cards/u/UntamedMight.java
@@ -20,7 +20,7 @@ public final class UntamedMight extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{G}");
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new BoostTargetEffect(new ManacostVariableValue(), new ManacostVariableValue(), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(ManacostVariableValue.instance, ManacostVariableValue.instance, Duration.EndOfTurn));
}
public UntamedMight(final UntamedMight card) {
diff --git a/Mage.Sets/src/mage/cards/u/UrborgSyphonMage.java b/Mage.Sets/src/mage/cards/u/UrborgSyphonMage.java
index 94145a9ebec..b8374ff492d 100644
--- a/Mage.Sets/src/mage/cards/u/UrborgSyphonMage.java
+++ b/Mage.Sets/src/mage/cards/u/UrborgSyphonMage.java
@@ -40,7 +40,7 @@ public final class UrborgSyphonMage extends CardImpl {
this.addAbility(ability);
}
- public UrborgSyphonMage(final UrborgSyphonMage card) {
+ private UrborgSyphonMage(final UrborgSyphonMage card) {
super(card);
}
@@ -57,7 +57,7 @@ class UrborgSyphonMageEffect extends OneShotEffect {
staticText = "Each other player loses 2 life. You gain life equal to the life lost this way";
}
- public UrborgSyphonMageEffect(final UrborgSyphonMageEffect effect) {
+ private UrborgSyphonMageEffect(final UrborgSyphonMageEffect effect) {
super(effect);
}
@@ -67,10 +67,10 @@ class UrborgSyphonMageEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
- if (!Objects.equals(playerId, source.getControllerId())) {
+ if (!source.isControlledBy(playerId)) {
Player player = game.getPlayer(playerId);
if (player != null) {
- damage += player.damage(2, source.getSourceId(), game, false, true);
+ damage += player.loseLife(2, game, false);
}
}
}
diff --git a/Mage.Sets/src/mage/cards/v/VengefulArchon.java b/Mage.Sets/src/mage/cards/v/VengefulArchon.java
index 6921e843087..c271f2e00d2 100644
--- a/Mage.Sets/src/mage/cards/v/VengefulArchon.java
+++ b/Mage.Sets/src/mage/cards/v/VengefulArchon.java
@@ -56,7 +56,7 @@ public final class VengefulArchon extends CardImpl {
class VengefulArchonEffect extends PreventDamageToControllerEffect {
public VengefulArchonEffect() {
- super(Duration.EndOfTurn, false, true, new ManacostVariableValue());
+ super(Duration.EndOfTurn, false, true, ManacostVariableValue.instance);
staticText = "Prevent the next X damage that would be dealt to you this turn. If damage is prevented this way, {this} deals that much damage to target player or planeswalker";
}
diff --git a/Mage.Sets/src/mage/cards/v/VensersJournal.java b/Mage.Sets/src/mage/cards/v/VensersJournal.java
index f3b19c26e9b..6bfa3dc7b06 100644
--- a/Mage.Sets/src/mage/cards/v/VensersJournal.java
+++ b/Mage.Sets/src/mage/cards/v/VensersJournal.java
@@ -30,7 +30,7 @@ public final class VensersJournal extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
// At the beginning of your upkeep, you gain 1 life for each card in your hand.
- this.addAbility(new BeginningOfUpkeepTriggeredAbility(new GainLifeEffect(new CardsInControllerHandCount()), TargetController.YOU, false));
+ this.addAbility(new BeginningOfUpkeepTriggeredAbility(new GainLifeEffect(CardsInControllerHandCount.instance), TargetController.YOU, false));
}
public VensersJournal(final VensersJournal card) {
diff --git a/Mage.Sets/src/mage/cards/v/VentifactBottle.java b/Mage.Sets/src/mage/cards/v/VentifactBottle.java
index 92e69ef6516..4b0c2db6e5e 100644
--- a/Mage.Sets/src/mage/cards/v/VentifactBottle.java
+++ b/Mage.Sets/src/mage/cards/v/VentifactBottle.java
@@ -36,7 +36,7 @@ public final class VentifactBottle extends CardImpl {
// {X}{1}, {tap}: Put X charge counters on Ventifact Bottle. Activate this ability only any time you could cast a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD,
- new AddCountersSourceEffect(CounterType.CHARGE.createInstance(), new ManacostVariableValue(), true),
+ new AddCountersSourceEffect(CounterType.CHARGE.createInstance(), ManacostVariableValue.instance, true),
new ManaCostsImpl("{1}{X}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/v/ViashinoSandswimmer.java b/Mage.Sets/src/mage/cards/v/ViashinoSandswimmer.java
index 6668c1ff629..bed9581368d 100644
--- a/Mage.Sets/src/mage/cards/v/ViashinoSandswimmer.java
+++ b/Mage.Sets/src/mage/cards/v/ViashinoSandswimmer.java
@@ -61,7 +61,7 @@ class ViashinoSandswimmerEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
new ReturnToHandSourceEffect().apply(game, source);
return true;
} else {
diff --git a/Mage.Sets/src/mage/cards/v/ViciousBetrayal.java b/Mage.Sets/src/mage/cards/v/ViciousBetrayal.java
index 3d5faf818a2..526707fa82f 100644
--- a/Mage.Sets/src/mage/cards/v/ViciousBetrayal.java
+++ b/Mage.Sets/src/mage/cards/v/ViciousBetrayal.java
@@ -1,7 +1,6 @@
package mage.cards.v;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.VariableCost;
import mage.abilities.costs.common.SacrificeXTargetCost;
@@ -16,21 +15,22 @@ import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.target.common.TargetCreaturePermanent;
+import java.util.UUID;
+
/**
- *
* @author Plopman
*/
public final class ViciousBetrayal extends CardImpl {
public ViciousBetrayal(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}{B}");
+ super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}");
// As an additional cost to cast Vicious Betrayal, sacrifice any number of creatures.
this.getSpellAbility().addCost(new SacrificeXTargetCost(new FilterControlledCreaturePermanent()));
// Target creature gets +2/+2 until end of turn for each creature sacrificed this way.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
- this.getSpellAbility().addEffect(new BoostTargetEffect(new GetXValue(), new GetXValue(), Duration.EndOfTurn));
+ this.getSpellAbility().addEffect(new BoostTargetEffect(GetXValue.instance, GetXValue.instance, Duration.EndOfTurn));
}
public ViciousBetrayal(final ViciousBetrayal card) {
@@ -43,19 +43,21 @@ public final class ViciousBetrayal extends CardImpl {
}
}
-class GetXValue implements DynamicValue {
+enum GetXValue implements DynamicValue {
+ instance;
+
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int amount = 0;
- for (VariableCost cost: sourceAbility.getCosts().getVariableCosts()) {
+ for (VariableCost cost : sourceAbility.getCosts().getVariableCosts()) {
amount += cost.getAmount();
}
- return 2*amount;
+ return 2 * amount;
}
@Override
public GetXValue copy() {
- return new GetXValue();
+ return GetXValue.instance;
}
@Override
diff --git a/Mage.Sets/src/mage/cards/v/ViciousShadows.java b/Mage.Sets/src/mage/cards/v/ViciousShadows.java
index 273cd5bf24e..c65f819cf8e 100644
--- a/Mage.Sets/src/mage/cards/v/ViciousShadows.java
+++ b/Mage.Sets/src/mage/cards/v/ViciousShadows.java
@@ -22,7 +22,7 @@ public final class ViciousShadows extends CardImpl {
// Whenever a creature dies, you may have Vicious Shadows deal damage to target player equal to the number of cards in that player's hand.
- Ability ability = new DiesCreatureTriggeredAbility(new DamageTargetEffect(new CardsInTargetHandCount()), true);
+ Ability ability = new DiesCreatureTriggeredAbility(new DamageTargetEffect(CardsInTargetHandCount.instance), true);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
diff --git a/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java b/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java
index 948eb6ae9e4..dc3d414a5d5 100644
--- a/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java
+++ b/Mage.Sets/src/mage/cards/v/VishKalBloodArbiter.java
@@ -51,7 +51,7 @@ public final class VishKalBloodArbiter extends CardImpl {
this.addAbility(LifelinkAbility.getInstance());
// Sacrifice a creature: Put X +1/+1 counters on Vish Kal, Blood Arbiter, where X is the sacrificed creature's power.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), new SacrificeCostCreaturesPower(), true),
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(0), SacrificeCostCreaturesPower.instance, true),
new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT))));
// Remove all +1/+1 counters from Vish Kal: Target creature gets -1/-1 until end of turn for each +1/+1 counter removed this way.
DynamicValue removedCounters = new SignInversionDynamicValue(new VishKalBloodArbiterDynamicValue());
diff --git a/Mage.Sets/src/mage/cards/v/VitalizingCascade.java b/Mage.Sets/src/mage/cards/v/VitalizingCascade.java
index bb1b0f5288f..2cf79403984 100644
--- a/Mage.Sets/src/mage/cards/v/VitalizingCascade.java
+++ b/Mage.Sets/src/mage/cards/v/VitalizingCascade.java
@@ -1,9 +1,8 @@
package mage.cards.v;
-import java.util.UUID;
import mage.abilities.Ability;
-import mage.abilities.dynamicvalue.common.ManacostVariableValue;
+import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
@@ -11,17 +10,18 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.Game;
+import java.util.UUID;
+
/**
- *
* @author LoneFox
*/
public final class VitalizingCascade extends CardImpl {
public VitalizingCascade(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{G}{W}");
+ super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{X}{G}{W}");
// You gain X plus 3 life.
- this.getSpellAbility().addEffect(new GainLifeEffect(new VitalizingCascadeValue()));
+ this.getSpellAbility().addEffect(new GainLifeEffect(VitalizingCascadeValue.instance));
}
public VitalizingCascade(final VitalizingCascade card) {
@@ -34,16 +34,22 @@ public final class VitalizingCascade extends CardImpl {
}
}
-class VitalizingCascadeValue extends ManacostVariableValue {
+enum VitalizingCascadeValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
- return super.calculate(game, sourceAbility, effect) + 3;
+ return sourceAbility.getManaCosts().getX() + 3;
}
@Override
public VitalizingCascadeValue copy() {
- return new VitalizingCascadeValue();
+ return instance;
+ }
+
+ @Override
+ public String getMessage() {
+ return "";
}
@Override
diff --git a/Mage.Sets/src/mage/cards/v/VolatileRig.java b/Mage.Sets/src/mage/cards/v/VolatileRig.java
index 6ec037917f8..ec5ba97d616 100644
--- a/Mage.Sets/src/mage/cards/v/VolatileRig.java
+++ b/Mage.Sets/src/mage/cards/v/VolatileRig.java
@@ -130,7 +130,7 @@ class VolatileRigEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- if (!player.flipCoin(game)) {
+ if (!player.flipCoin(source, game, true)) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
return permanent.sacrifice(source.getSourceId(), game);
@@ -161,7 +161,7 @@ class VolatileRigEffect2 extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
- if (!player.flipCoin(game)) {
+ if (!player.flipCoin(source, game, true)) {
List permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game);
for (Permanent permanent : permanents) {
diff --git a/Mage.Sets/src/mage/cards/v/VolcanicGeyser.java b/Mage.Sets/src/mage/cards/v/VolcanicGeyser.java
index 85a3f917121..1f13748ea75 100644
--- a/Mage.Sets/src/mage/cards/v/VolcanicGeyser.java
+++ b/Mage.Sets/src/mage/cards/v/VolcanicGeyser.java
@@ -20,7 +20,7 @@ public final class VolcanicGeyser extends CardImpl {
// Volcanic Geyser deals X damage to any target.
- this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new DamageTargetEffect(ManacostVariableValue.instance));
this.getSpellAbility().addTarget(new TargetAnyTarget());
}
diff --git a/Mage.Sets/src/mage/cards/v/VolcanoHellion.java b/Mage.Sets/src/mage/cards/v/VolcanoHellion.java
index de37cde0ff7..b8bd54d50e2 100644
--- a/Mage.Sets/src/mage/cards/v/VolcanoHellion.java
+++ b/Mage.Sets/src/mage/cards/v/VolcanoHellion.java
@@ -32,7 +32,7 @@ public final class VolcanoHellion extends CardImpl {
this.toughness = new MageInt(5);
// Volcano Hellion has echo {X}, where X is your life total.
- this.addAbility(new EchoAbility(new ControllerLifeCount(), "{this} has echo {X}, where X is your life total."));
+ this.addAbility(new EchoAbility(ControllerLifeCount.instance, "{this} has echo {X}, where X is your life total."));
// When Volcano Hellion enters the battlefield, it deals an amount of damage of your choice to you and target creature. The damage can't be prevented.
Ability ability = new EntersBattlefieldTriggeredAbility(new VolcanoHellionEffect(), false);
diff --git a/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java b/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java
index 3e8ebbb7e5e..d7344404e4a 100644
--- a/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java
+++ b/Mage.Sets/src/mage/cards/v/VolrathTheFallen.java
@@ -34,7 +34,7 @@ public final class VolrathTheFallen extends CardImpl {
// {1}{B}, Discard a creature card:
// Volrath the Fallen gets +X/+X until end of turn, where X is the discarded card's converted mana cost.
- Effect effect = new BoostSourceEffect(new DiscardCostCardConvertedMana(),new DiscardCostCardConvertedMana(),Duration.EndOfTurn);
+ Effect effect = new BoostSourceEffect(DiscardCostCardConvertedMana.instance,DiscardCostCardConvertedMana.instance,Duration.EndOfTurn);
effect.setText("{this} gets +X/+X until end of turn, where X is the discarded card's converted mana cost");
Ability ability = new SimpleActivatedAbility(
diff --git a/Mage.Sets/src/mage/cards/v/VolrathsDungeon.java b/Mage.Sets/src/mage/cards/v/VolrathsDungeon.java
index c70ab8f1590..3c8444a70e4 100644
--- a/Mage.Sets/src/mage/cards/v/VolrathsDungeon.java
+++ b/Mage.Sets/src/mage/cards/v/VolrathsDungeon.java
@@ -1,135 +1,135 @@
-package mage.cards.v;
-
-import mage.abilities.Ability;
-import mage.abilities.ActivatedAbility;
-import mage.abilities.common.ActivateAsSorceryActivatedAbility;
-import mage.abilities.common.SimpleActivatedAbility;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.CostImpl;
-import mage.abilities.costs.common.DiscardCardCost;
-import mage.abilities.dynamicvalue.DynamicValue;
-import mage.abilities.dynamicvalue.common.StaticValue;
-import mage.abilities.effects.OneShotEffect;
-import mage.abilities.effects.common.DestroySourceEffect;
-import mage.cards.Card;
-import mage.cards.CardImpl;
-import mage.cards.CardSetInfo;
-import mage.constants.CardType;
-import mage.constants.Outcome;
-import mage.constants.TargetController;
-import mage.constants.Zone;
-import mage.filter.FilterCard;
-import mage.game.Game;
-import mage.players.Player;
-import mage.target.TargetPlayer;
-import mage.target.common.TargetCardInHand;
-
-import java.util.UUID;
-
-/**
- * @author jeffwadsworth
- */
-public final class VolrathsDungeon extends CardImpl {
-
- public VolrathsDungeon(UUID ownerId, CardSetInfo setInfo) {
- super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
-
- // Pay 5 life: Destroy Volrath's Dungeon. Any player may activate this ability but only during his or her turn.
- ActivatedAbility ability = new SimpleActivatedAbility(
- Zone.BATTLEFIELD,
- new DestroySourceEffect().setText("Destroy {this}. Any player may activate this ability but only during his or her turn."),
- new PayLifeActivePlayerCost(5));
- ability.setMayActivate(TargetController.ACTIVE);
- this.addAbility(ability);
-
- // Discard a card: Target player puts a card from his or her hand on top of his or her library. Activate this ability only any time you could cast a sorcery.
- FilterCard filter = new FilterCard("a card for payment");
- Ability ability2 = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new VolrathsDungeonEffect(), new DiscardCardCost(filter));
- ability2.addTarget(new TargetPlayer());
- this.addAbility(ability2);
- }
-
- public VolrathsDungeon(final VolrathsDungeon card) {
- super(card);
- }
-
- @Override
- public VolrathsDungeon copy() {
- return new VolrathsDungeon(this);
- }
-}
-
-class PayLifeActivePlayerCost extends CostImpl {
-
- private final DynamicValue amount;
-
- public PayLifeActivePlayerCost(int amount) {
- this.amount = new StaticValue(amount);
- this.text = "Pay " + amount + " life";
- }
-
- public PayLifeActivePlayerCost(DynamicValue amount, String text) {
- this.amount = amount.copy();
- this.text = "Pay " + text;
- }
-
- public PayLifeActivePlayerCost(PayLifeActivePlayerCost cost) {
- super(cost);
- this.amount = cost.amount.copy();
- }
-
- @Override
- public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
- int lifeToPayAmount = amount.calculate(game, ability, null);
- return game.getPlayer(game.getActivePlayerId()).getLife() >= lifeToPayAmount;
- }
-
- @Override
- public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
- int lifeToPayAmount = amount.calculate(game, ability, null);
- Player activatingPlayer = game.getPlayer(game.getActivePlayerId());
- if (activatingPlayer != null
- && activatingPlayer.chooseUse(Outcome.LoseLife, "Do you wish to pay " + lifeToPayAmount + " life?", ability, game)) {
- Player player = game.getPlayer(game.getActivePlayerId());
- if (player != null) {
- this.paid = player.loseLife(lifeToPayAmount, game, false) == lifeToPayAmount;
- }
- }
- return paid;
- }
-
- @Override
- public PayLifeActivePlayerCost copy() {
- return new PayLifeActivePlayerCost(this);
- }
-}
-
-class VolrathsDungeonEffect extends OneShotEffect {
-
- public VolrathsDungeonEffect() {
- super(Outcome.Detriment);
- this.staticText = "Target player puts a card from his or her hand on top of his or her library";
- }
-
- public VolrathsDungeonEffect(final VolrathsDungeonEffect effect) {
- super(effect);
- }
-
- @Override
- public VolrathsDungeonEffect copy() {
- return new VolrathsDungeonEffect(this);
- }
-
- @Override
- public boolean apply(Game game, Ability source) {
- Player targetedPlayer = game.getPlayer(source.getFirstTarget());
- if (targetedPlayer != null) {
- TargetCardInHand target = new TargetCardInHand();
- if (targetedPlayer.choose(Outcome.Detriment, targetedPlayer.getHand(), target, game)) {
- Card card = game.getCard(target.getFirstTarget());
- return card != null && targetedPlayer.putCardOnTopXOfLibrary(card, game, source, 0);
- }
- }
- return false;
- }
-}
+package mage.cards.v;
+
+import mage.abilities.Ability;
+import mage.abilities.ActivatedAbility;
+import mage.abilities.common.ActivateAsSorceryActivatedAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.Cost;
+import mage.abilities.costs.CostImpl;
+import mage.abilities.costs.common.DiscardCardCost;
+import mage.abilities.dynamicvalue.DynamicValue;
+import mage.abilities.dynamicvalue.common.StaticValue;
+import mage.abilities.effects.OneShotEffect;
+import mage.abilities.effects.common.DestroySourceEffect;
+import mage.cards.Card;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.Outcome;
+import mage.constants.TargetController;
+import mage.constants.Zone;
+import mage.filter.FilterCard;
+import mage.game.Game;
+import mage.players.Player;
+import mage.target.TargetPlayer;
+import mage.target.common.TargetCardInHand;
+
+import java.util.UUID;
+
+/**
+ * @author jeffwadsworth
+ */
+public final class VolrathsDungeon extends CardImpl {
+
+ public VolrathsDungeon(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
+
+ // Pay 5 life: Destroy Volrath's Dungeon. Any player may activate this ability but only during their turn.
+ ActivatedAbility ability = new SimpleActivatedAbility(
+ Zone.BATTLEFIELD,
+ new DestroySourceEffect().setText("Destroy {this}. Any player may activate this ability but only during their turn."),
+ new PayLifeActivePlayerCost(5));
+ ability.setMayActivate(TargetController.ACTIVE);
+ this.addAbility(ability);
+
+ // Discard a card: Target player puts a card from their hand on top of their library. Activate this ability only any time you could cast a sorcery.
+ FilterCard filter = new FilterCard("a card for payment");
+ Ability ability2 = new ActivateAsSorceryActivatedAbility(Zone.BATTLEFIELD, new VolrathsDungeonEffect(), new DiscardCardCost(filter));
+ ability2.addTarget(new TargetPlayer());
+ this.addAbility(ability2);
+ }
+
+ public VolrathsDungeon(final VolrathsDungeon card) {
+ super(card);
+ }
+
+ @Override
+ public VolrathsDungeon copy() {
+ return new VolrathsDungeon(this);
+ }
+}
+
+class PayLifeActivePlayerCost extends CostImpl {
+
+ private final DynamicValue amount;
+
+ public PayLifeActivePlayerCost(int amount) {
+ this.amount = new StaticValue(amount);
+ this.text = "Pay " + amount + " life";
+ }
+
+ public PayLifeActivePlayerCost(DynamicValue amount, String text) {
+ this.amount = amount.copy();
+ this.text = "Pay " + text;
+ }
+
+ public PayLifeActivePlayerCost(PayLifeActivePlayerCost cost) {
+ super(cost);
+ this.amount = cost.amount.copy();
+ }
+
+ @Override
+ public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
+ int lifeToPayAmount = amount.calculate(game, ability, null);
+ return game.getPlayer(game.getActivePlayerId()).getLife() >= lifeToPayAmount;
+ }
+
+ @Override
+ public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
+ int lifeToPayAmount = amount.calculate(game, ability, null);
+ Player activatingPlayer = game.getPlayer(game.getActivePlayerId());
+ if (activatingPlayer != null
+ && activatingPlayer.chooseUse(Outcome.LoseLife, "Do you wish to pay " + lifeToPayAmount + " life?", ability, game)) {
+ Player player = game.getPlayer(game.getActivePlayerId());
+ if (player != null) {
+ this.paid = player.loseLife(lifeToPayAmount, game, false) == lifeToPayAmount;
+ }
+ }
+ return paid;
+ }
+
+ @Override
+ public PayLifeActivePlayerCost copy() {
+ return new PayLifeActivePlayerCost(this);
+ }
+}
+
+class VolrathsDungeonEffect extends OneShotEffect {
+
+ public VolrathsDungeonEffect() {
+ super(Outcome.Detriment);
+ this.staticText = "Target player puts a card from their hand on top of their library";
+ }
+
+ public VolrathsDungeonEffect(final VolrathsDungeonEffect effect) {
+ super(effect);
+ }
+
+ @Override
+ public VolrathsDungeonEffect copy() {
+ return new VolrathsDungeonEffect(this);
+ }
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Player targetedPlayer = game.getPlayer(source.getFirstTarget());
+ if (targetedPlayer != null) {
+ TargetCardInHand target = new TargetCardInHand();
+ if (targetedPlayer.choose(Outcome.Detriment, targetedPlayer.getHand(), target, game)) {
+ Card card = game.getCard(target.getFirstTarget());
+ return card != null && targetedPlayer.putCardOnTopXOfLibrary(card, game, source, 0);
+ }
+ }
+ return false;
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/v/VoyagerDrake.java b/Mage.Sets/src/mage/cards/v/VoyagerDrake.java
index afe52717faa..058ab18bf9e 100644
--- a/Mage.Sets/src/mage/cards/v/VoyagerDrake.java
+++ b/Mage.Sets/src/mage/cards/v/VoyagerDrake.java
@@ -64,7 +64,7 @@ enum VoyagerDrakeAdjuster implements TargetAdjuster {
@Override
public void adjustTargets(Ability ability, Game game) {
ability.getTargets().clear();
- int numbTargets = new MultikickerCount().calculate(game, ability, null);
+ int numbTargets = MultikickerCount.instance.calculate(game, ability, null);
if (numbTargets > 0) {
ability.addTarget(new TargetCreaturePermanent(0, numbTargets));
}
diff --git a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java
index 77d38291e99..1504be0bf43 100644
--- a/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java
+++ b/Mage.Sets/src/mage/cards/w/WakerOfTheWilds.java
@@ -40,7 +40,7 @@ public final class WakerOfTheWilds extends CardImpl {
Zone.BATTLEFIELD,
new AddCountersTargetEffect(
CounterType.P1P1.createInstance(0),
- new ManacostVariableValue()
+ ManacostVariableValue.instance
).setText("Put X +1/+1 counters on target land you control."),
new ManaCostsImpl("{X}{G}{G}")
);
diff --git a/Mage.Sets/src/mage/cards/w/WarCadence.java b/Mage.Sets/src/mage/cards/w/WarCadence.java
index 57c5707a1c3..a3864feb41b 100644
--- a/Mage.Sets/src/mage/cards/w/WarCadence.java
+++ b/Mage.Sets/src/mage/cards/w/WarCadence.java
@@ -44,7 +44,7 @@ public final class WarCadence extends CardImpl {
class WarCadenceReplacementEffect extends ReplacementEffectImpl {
- DynamicValue xCosts = new ManacostVariableValue();
+ DynamicValue xCosts = ManacostVariableValue.instance;
WarCadenceReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
diff --git a/Mage.Sets/src/mage/cards/w/WarTax.java b/Mage.Sets/src/mage/cards/w/WarTax.java
index 3f9fb3cf9d1..e9d14ff8221 100644
--- a/Mage.Sets/src/mage/cards/w/WarTax.java
+++ b/Mage.Sets/src/mage/cards/w/WarTax.java
@@ -45,7 +45,7 @@ public final class WarTax extends CardImpl {
class WarTaxCantAttackUnlessPaysEffect extends PayCostToAttackBlockEffectImpl {
- DynamicValue xCosts = new ManacostVariableValue();
+ DynamicValue xCosts = ManacostVariableValue.instance;
WarTaxCantAttackUnlessPaysEffect() {
super(Duration.EndOfTurn, Outcome.Neutral, RestrictType.ATTACK);
diff --git a/Mage.Sets/src/mage/cards/w/WarbreakTrumpeter.java b/Mage.Sets/src/mage/cards/w/WarbreakTrumpeter.java
index 9bd82846272..6e801451f6a 100644
--- a/Mage.Sets/src/mage/cards/w/WarbreakTrumpeter.java
+++ b/Mage.Sets/src/mage/cards/w/WarbreakTrumpeter.java
@@ -31,7 +31,7 @@ public final class WarbreakTrumpeter extends CardImpl {
this.addAbility(new MorphAbility(this, new ManaCostsImpl("{X}{X}{R}")));
// When Warbreak Trumpeter is turned face up, create X 1/1 red Goblin creature tokens.
- DynamicValue morphX = new MorphManacostVariableValue();
+ DynamicValue morphX = MorphManacostVariableValue.instance;
this.addAbility(new TurnedFaceUpSourceTriggeredAbility(new CreateTokenEffect(new GoblinToken(), morphX)));
}
diff --git a/Mage.Sets/src/mage/cards/w/WarpedPhysique.java b/Mage.Sets/src/mage/cards/w/WarpedPhysique.java
index 9cfa58584cc..2f1fb5588ae 100644
--- a/Mage.Sets/src/mage/cards/w/WarpedPhysique.java
+++ b/Mage.Sets/src/mage/cards/w/WarpedPhysique.java
@@ -26,7 +26,7 @@ public final class WarpedPhysique extends CardImpl {
// Target creature gets +X/-X until end of turn, where X is the number of cards in your hand.
- DynamicValue xValue = new CardsInControllerHandCount();
+ DynamicValue xValue = CardsInControllerHandCount.instance;
this.getSpellAbility().addEffect(new BoostTargetEffect(xValue, new SignInversionDynamicValue(xValue), Duration.EndOfTurn, true));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
diff --git a/Mage.Sets/src/mage/cards/w/WerewolfOfAncientHunger.java b/Mage.Sets/src/mage/cards/w/WerewolfOfAncientHunger.java
index b7df1697b46..61bdd50855f 100644
--- a/Mage.Sets/src/mage/cards/w/WerewolfOfAncientHunger.java
+++ b/Mage.Sets/src/mage/cards/w/WerewolfOfAncientHunger.java
@@ -48,7 +48,7 @@ public final class WerewolfOfAncientHunger extends CardImpl {
// Werewolf of Ancient Hunger's power and toughness are each equal to the total number of cards in all players' hands.
this.addAbility(new SimpleStaticAbility(Zone.ALL,
- new ConditionalContinuousEffect(new SetPowerToughnessSourceEffect(new CardsInAllHandsCount(), Duration.EndOfGame),
+ new ConditionalContinuousEffect(new SetPowerToughnessSourceEffect(CardsInAllHandsCount.instance, Duration.EndOfGame),
new TransformedCondition(false), "{this}'s power and toughness are each equal to the total number of cards in all players' hands")));
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Werewolf of Ancient Hunger.
diff --git a/Mage.Sets/src/mage/cards/w/Whetwheel.java b/Mage.Sets/src/mage/cards/w/Whetwheel.java
index bb37398d793..cc09655c802 100644
--- a/Mage.Sets/src/mage/cards/w/Whetwheel.java
+++ b/Mage.Sets/src/mage/cards/w/Whetwheel.java
@@ -26,7 +26,7 @@ public final class Whetwheel extends CardImpl {
// {X}{X}, {tap}: Target player puts the top X cards of their library into their graveyard.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new PutLibraryIntoGraveTargetEffect(
- new ManacostVariableValue()), new ManaCostsImpl("{X}{X}"));
+ ManacostVariableValue.instance), new ManaCostsImpl("{X}{X}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java
index d5d28212bba..b08a197b181 100644
--- a/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java
+++ b/Mage.Sets/src/mage/cards/w/WhiteManaBattery.java
@@ -36,7 +36,7 @@ public final class WhiteManaBattery extends CardImpl {
// {tap}, Remove any number of charge counters from White Mana Battery: Add {W}, then add an additional {W} for each charge counter removed this way.
ability = new DynamicManaAbility(
Mana.WhiteMana(1),
- new IntPlusDynamicValue(1, new RemovedCountersForCostValue()),
+ new IntPlusDynamicValue(1, RemovedCountersForCostValue.instance),
new TapSourceCost(),
"Add {W}, then add {W} for each charge counter removed this way",
true, new CountersSourceCount(CounterType.CHARGE));
diff --git a/Mage.Sets/src/mage/cards/w/WhiteSunsZenith.java b/Mage.Sets/src/mage/cards/w/WhiteSunsZenith.java
index b13069cf27c..772562ec28c 100644
--- a/Mage.Sets/src/mage/cards/w/WhiteSunsZenith.java
+++ b/Mage.Sets/src/mage/cards/w/WhiteSunsZenith.java
@@ -20,7 +20,7 @@ public final class WhiteSunsZenith extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{W}{W}{W}");
// create X 2/2 white Cat creature tokens. Shuffle White Sun's Zenith into its owner's library.
- this.getSpellAbility().addEffect(new CreateTokenEffect(new CatToken(), new ManacostVariableValue()));
+ this.getSpellAbility().addEffect(new CreateTokenEffect(new CatToken(), ManacostVariableValue.instance));
this.getSpellAbility().addEffect(ShuffleSpellEffect.getInstance());
}
diff --git a/Mage.Sets/src/mage/cards/w/Wiitigo.java b/Mage.Sets/src/mage/cards/w/Wiitigo.java
new file mode 100644
index 00000000000..79f7c766f88
--- /dev/null
+++ b/Mage.Sets/src/mage/cards/w/Wiitigo.java
@@ -0,0 +1,136 @@
+package mage.cards.w;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import mage.MageInt;
+import mage.MageObjectReference;
+import mage.abilities.Ability;
+import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
+import mage.abilities.common.EntersBattlefieldAbility;
+import mage.abilities.condition.Condition;
+import mage.abilities.decorator.ConditionalOneShotEffect;
+import mage.abilities.effects.common.counter.AddCountersSourceEffect;
+import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
+import mage.constants.SubType;
+import mage.cards.CardImpl;
+import mage.cards.CardSetInfo;
+import mage.constants.CardType;
+import mage.constants.TargetController;
+import mage.constants.WatcherScope;
+import mage.counters.CounterType;
+import mage.game.Game;
+import mage.game.events.GameEvent;
+import mage.game.permanent.Permanent;
+import mage.watchers.Watcher;
+
+/**
+ *
+ * @author jeffwadsworth
+ */
+public final class Wiitigo extends CardImpl {
+
+ public Wiitigo(UUID ownerId, CardSetInfo setInfo) {
+ super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}{G}");
+
+ this.subtype.add(SubType.YETI);
+ this.power = new MageInt(0);
+ this.toughness = new MageInt(0);
+
+ // Wiitigo enters the battlefield with six +1/+1 counters on it.
+ this.addAbility(new EntersBattlefieldAbility(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(6))));
+
+ // At the beginning of your upkeep, put a +1/+1 counter on Wiitigo if it has blocked or been blocked since your last upkeep. Otherwise, remove a +1/+1 counter from it.
+ Ability triggeredAbility = new BeginningOfUpkeepTriggeredAbility(
+ new ConditionalOneShotEffect(
+ new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)),
+ new RemoveCounterSourceEffect(CounterType.P1P1.createInstance(1)),
+ new BlockedOrBeenBlockedSinceYourLastUpkeepCondition(),
+ "put a +1/+1 counter on enchanted creature if it blocked or been blocked since your last "
+ + "upkeep. Otherwise, remove a +1/+1 counter from it"),
+ TargetController.YOU,
+ false);
+ triggeredAbility.addWatcher(new BlockedOrBeenBlockedSinceYourLastUpkeepWatcher());
+ this.addAbility(triggeredAbility);
+ }
+
+ private Wiitigo(final Wiitigo card) {
+ super(card);
+ }
+
+ @Override
+ public Wiitigo copy() {
+ return new Wiitigo(this);
+ }
+}
+
+class BlockedOrBeenBlockedSinceYourLastUpkeepCondition implements Condition {
+
+ @Override
+ public boolean apply(Game game, Ability source) {
+ Permanent wiitigo = game.getBattlefield().getPermanent(source.getSourceId());
+ BlockedOrBeenBlockedSinceYourLastUpkeepWatcher watcher = game.getState().getWatcher(
+ BlockedOrBeenBlockedSinceYourLastUpkeepWatcher.class);
+ if (wiitigo != null
+ && watcher != null) {
+ return watcher.blockedOrBeenBlockedSinceLastUpkeep(
+ new MageObjectReference(wiitigo.getId(),
+ wiitigo.getZoneChangeCounter(game),
+ game),
+ wiitigo.getControllerId());
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "it blocked or was blocked since your last upkeep";
+ }
+}
+
+class BlockedOrBeenBlockedSinceYourLastUpkeepWatcher extends Watcher {
+
+ private final Map> blockedOrBeenBlockedCreatures = new HashMap<>();
+
+ public BlockedOrBeenBlockedSinceYourLastUpkeepWatcher() {
+ super(BlockedOrBeenBlockedSinceYourLastUpkeepWatcher.class, WatcherScope.GAME);
+ }
+
+ public BlockedOrBeenBlockedSinceYourLastUpkeepWatcher(BlockedOrBeenBlockedSinceYourLastUpkeepWatcher watcher) {
+ super(watcher);
+ for (Map.Entry> entry : watcher.blockedOrBeenBlockedCreatures.entrySet()) {
+ Set creaturesThatBlockedOrWereBlocked = new HashSet<>(entry.getValue());
+ blockedOrBeenBlockedCreatures.put(entry.getKey(), creaturesThatBlockedOrWereBlocked);
+ }
+ }
+
+ @Override
+ public void watch(GameEvent event, Game game) {
+ if (event.getType() == GameEvent.EventType.UPKEEP_STEP_POST) {
+ blockedOrBeenBlockedCreatures.put(event.getPlayerId(), new HashSet<>()); // clear the watcher after upkeep
+ } else if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) {
+ MageObjectReference morBlocker = new MageObjectReference(event.getSourceId(), game); // store blocker
+ MageObjectReference morAttackerBlocked = new MageObjectReference(event.getTargetId(), game); // store attacker blocked
+ for (UUID player : game.getPlayerList()) {
+ if (!blockedOrBeenBlockedCreatures.containsKey(player)) {
+ blockedOrBeenBlockedCreatures.put(player, new HashSet<>());
+ }
+ blockedOrBeenBlockedCreatures.get(player).add(morBlocker);
+ blockedOrBeenBlockedCreatures.get(player).add(morAttackerBlocked);
+ }
+ }
+ }
+
+ public boolean blockedOrBeenBlockedSinceLastUpkeep(MageObjectReference mor, UUID player) {
+ return (blockedOrBeenBlockedCreatures.get(player) != null)
+ && blockedOrBeenBlockedCreatures.get(player).contains(mor);
+ }
+
+ @Override
+ public BlockedOrBeenBlockedSinceYourLastUpkeepWatcher copy() {
+ return new BlockedOrBeenBlockedSinceYourLastUpkeepWatcher(this);
+ }
+}
diff --git a/Mage.Sets/src/mage/cards/w/WildWurm.java b/Mage.Sets/src/mage/cards/w/WildWurm.java
index 84ee6709483..c56dee1803b 100644
--- a/Mage.Sets/src/mage/cards/w/WildWurm.java
+++ b/Mage.Sets/src/mage/cards/w/WildWurm.java
@@ -58,7 +58,7 @@ class WildWurmEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
return true;
} else {
new ReturnToHandSourceEffect().apply(game, source);
diff --git a/Mage.Sets/src/mage/cards/w/Windstorm.java b/Mage.Sets/src/mage/cards/w/Windstorm.java
index 8d4899a342f..7ad059c67fe 100644
--- a/Mage.Sets/src/mage/cards/w/Windstorm.java
+++ b/Mage.Sets/src/mage/cards/w/Windstorm.java
@@ -27,7 +27,7 @@ public final class Windstorm extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{X}{G}");
- this.getSpellAbility().addEffect(new DamageAllEffect(new ManacostVariableValue(), filter));
+ this.getSpellAbility().addEffect(new DamageAllEffect(ManacostVariableValue.instance, filter));
}
public Windstorm(final Windstorm card) {
diff --git a/Mage.Sets/src/mage/cards/w/WindstormDrake.java b/Mage.Sets/src/mage/cards/w/WindstormDrake.java
index ebb0e3595e1..702a12621b7 100644
--- a/Mage.Sets/src/mage/cards/w/WindstormDrake.java
+++ b/Mage.Sets/src/mage/cards/w/WindstormDrake.java
@@ -13,6 +13,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import java.util.UUID;
+import mage.abilities.effects.Effect;
/**
* @author TheElk801
@@ -20,7 +21,7 @@ import java.util.UUID;
public final class WindstormDrake extends CardImpl {
private static final FilterCreaturePermanent filter
- = new FilterCreaturePermanent("creatures you control with flying");
+ = new FilterCreaturePermanent();
static {
filter.add(new AbilityPredicate(FlyingAbility.class));
@@ -37,9 +38,11 @@ public final class WindstormDrake extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Other creatures you control with flying get +1/+0.
- this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
+ Effect effect = new BoostControlledEffect(
1, 0, Duration.WhileOnBattlefield, filter, true
- )));
+ );
+ effect.setText("Other creatures you control with flying get +1/+0");
+ this.addAbility(new SimpleStaticAbility(effect));
}
private WindstormDrake(final WindstormDrake card) {
diff --git a/Mage.Sets/src/mage/cards/w/WineOfBloodAndIron.java b/Mage.Sets/src/mage/cards/w/WineOfBloodAndIron.java
index 47f98cbfd31..f5e91428984 100644
--- a/Mage.Sets/src/mage/cards/w/WineOfBloodAndIron.java
+++ b/Mage.Sets/src/mage/cards/w/WineOfBloodAndIron.java
@@ -29,7 +29,7 @@ public final class WineOfBloodAndIron extends CardImpl {
// {4}: Target creature gets +X/+0 until end of turn, where X is its power. Sacrifice Wine of Blood and Iron at the beginning of the next end step.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
- new BoostTargetEffect(new TargetPermanentPowerCount(), new StaticValue(0), Duration.EndOfTurn, true),
+ new BoostTargetEffect(TargetPermanentPowerCount.instance, new StaticValue(0), Duration.EndOfTurn, true),
new GenericManaCost(4));
Effect effect = new CreateDelayedTriggeredAbilityEffect(
new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()), false);
diff --git a/Mage.Sets/src/mage/cards/w/WinterSky.java b/Mage.Sets/src/mage/cards/w/WinterSky.java
index 31ac6526b55..6f728a84087 100644
--- a/Mage.Sets/src/mage/cards/w/WinterSky.java
+++ b/Mage.Sets/src/mage/cards/w/WinterSky.java
@@ -52,7 +52,7 @@ class WinterSkyEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
- if (controller.flipCoin(game)) {
+ if (controller.flipCoin(source, game, true)) {
new DamageEverythingEffect(1).apply(game, source);
return true;
} else {
diff --git a/Mage.Sets/src/mage/cards/w/WolfbriarElemental.java b/Mage.Sets/src/mage/cards/w/WolfbriarElemental.java
index 93d321340d4..4a96c707c5c 100644
--- a/Mage.Sets/src/mage/cards/w/WolfbriarElemental.java
+++ b/Mage.Sets/src/mage/cards/w/WolfbriarElemental.java
@@ -31,7 +31,7 @@ public final class WolfbriarElemental extends CardImpl {
this.addAbility(new MultikickerAbility("{G}"));
// When Wolfbriar Elemental enters the battlefield, create a 2/2 green Wolf creature token for each time it was kicked.
- this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WolfToken(), new MultikickerCount())));
+ this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new WolfToken(), MultikickerCount.instance)));
}
public WolfbriarElemental(final WolfbriarElemental card) {
diff --git a/Mage.Sets/src/mage/cards/w/WordOfBlasting.java b/Mage.Sets/src/mage/cards/w/WordOfBlasting.java
index e30c4504316..ee30e19b782 100644
--- a/Mage.Sets/src/mage/cards/w/WordOfBlasting.java
+++ b/Mage.Sets/src/mage/cards/w/WordOfBlasting.java
@@ -31,7 +31,7 @@ public final class WordOfBlasting extends CardImpl {
// Destroy target Wall. It can't be regenerated. Word of Blasting deals damage equal to that Wall's converted mana cost to the Wall's controller.
this.getSpellAbility().addEffect(new DestroyTargetEffect(true));
- Effect effect = new DamageTargetControllerEffect(new TargetConvertedManaCost());
+ Effect effect = new DamageTargetControllerEffect(TargetConvertedManaCost.instance);
effect.setText("{this} deals damage equal to that Wall's converted mana cost to the Wall's controller");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetPermanent(filter));
diff --git a/Mage.Sets/src/mage/cards/w/WorthyCause.java b/Mage.Sets/src/mage/cards/w/WorthyCause.java
index 4d196b4f2c3..3564befc98a 100644
--- a/Mage.Sets/src/mage/cards/w/WorthyCause.java
+++ b/Mage.Sets/src/mage/cards/w/WorthyCause.java
@@ -29,7 +29,7 @@ public final class WorthyCause extends CardImpl {
this.getSpellAbility().addCost(new SacrificeTargetCost(new TargetControlledCreaturePermanent(FILTER_CONTROLLED_CREATURE_SHORT_TEXT)));
// You gain life equal to the sacrificed creature's toughness.
- Effect effect = new GainLifeEffect(new SacrificeCostCreaturesToughness());
+ Effect effect = new GainLifeEffect(SacrificeCostCreaturesToughness.instance);
effect.setText("You gain life equal to the sacrificed creature's toughness");
this.getSpellAbility().addEffect(effect);
}
diff --git a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java
index a392f415b20..560d3acf922 100644
--- a/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java
+++ b/Mage.Sets/src/mage/cards/x/XantchaSleeperAgent.java
@@ -1,35 +1,40 @@
package mage.cards.x;
-import java.util.Objects;
-import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
-import mage.abilities.common.*;
-import mage.abilities.costs.mana.ManaCostsImpl;
-import mage.abilities.effects.ContinuousEffectImpl;
-import mage.abilities.effects.Effect;
+import mage.abilities.common.AsEntersBattlefieldAbility;
+import mage.abilities.common.AttacksEachCombatStaticAbility;
+import mage.abilities.common.SimpleActivatedAbility;
+import mage.abilities.costs.mana.GenericManaCost;
+import mage.abilities.effects.ContinuousEffect;
+import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.LoseLifePermanentControllerEffect;
+import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
+import mage.players.Player;
+import mage.target.Target;
import mage.target.common.TargetOpponent;
+import mage.target.targetpointer.FixedTarget;
+import java.util.Objects;
+import java.util.UUID;
+
+import static mage.constants.Outcome.Benefit;
/**
- *
* @author jesusjbr
*/
public final class XantchaSleeperAgent extends CardImpl {
-
-
public XantchaSleeperAgent(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}");
@@ -39,30 +44,26 @@ public final class XantchaSleeperAgent extends CardImpl {
this.toughness = new MageInt(5);
// As Xantcha, Sleeper Agent enters the battlefield, an opponent of your choice gains control of it.
- Ability ability = new EntersBattlefieldTriggeredAbility(new XantchaSleeperAgentChangeControlEffect()) ;
- ability.addTarget(new TargetOpponent());
- this.addAbility(ability);
+ this.addAbility(new AsEntersBattlefieldAbility(new XantchaSleeperAgentChangeControlEffect()));
// Xantcha attacks each combat if able and can’t attack its owner or planeswalkers its owner controls.
- ability = new AttacksEachCombatStaticAbility();
- Effect effect = new XantchaSleeperAgentAttackRestrictionEffect();
- ability.addEffect(effect);
+ Ability ability = new AttacksEachCombatStaticAbility();
+ ability.addEffect(new XantchaSleeperAgentAttackRestrictionEffect());
this.addAbility(ability);
// {3}: Xantcha’s controller loses 2 life and you draw a card. Any player may activate this ability.
- effect = new LoseLifePermanentControllerEffect(2);
- effect.setText("Xantcha’s controller loses 2 life");
- SimpleActivatedAbility simpleAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{3}"));
-
+ SimpleActivatedAbility simpleAbility = new SimpleActivatedAbility(
+ new LoseLifePermanentControllerEffect(2)
+ .setText("{this}’s controller loses 2 life"),
+ new GenericManaCost(3)
+ );
simpleAbility.addEffect(new DrawCardSourceControllerEffect(1).setText("and you draw a card"));
simpleAbility.addEffect(new InfoEffect("Any player may activate this ability"));
simpleAbility.setMayActivate(TargetController.ANY);
this.addAbility(simpleAbility);
-
-
}
- public XantchaSleeperAgent(final XantchaSleeperAgent card) {
+ private XantchaSleeperAgent(final XantchaSleeperAgent card) {
super(card);
}
@@ -72,16 +73,14 @@ public final class XantchaSleeperAgent extends CardImpl {
}
}
+class XantchaSleeperAgentChangeControlEffect extends OneShotEffect {
-
-class XantchaSleeperAgentChangeControlEffect extends ContinuousEffectImpl {
-
- public XantchaSleeperAgentChangeControlEffect() {
- super(Duration.Custom, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
- staticText = "an opponent of your choice gains control of it";
+ XantchaSleeperAgentChangeControlEffect() {
+ super(Benefit);
+ staticText = "an opponent of your choice gains control of it.";
}
- public XantchaSleeperAgentChangeControlEffect(final XantchaSleeperAgentChangeControlEffect effect) {
+ private XantchaSleeperAgentChangeControlEffect(final XantchaSleeperAgentChangeControlEffect effect) {
super(effect);
}
@@ -92,13 +91,27 @@ class XantchaSleeperAgentChangeControlEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
- Permanent permanent = (Permanent) source.getSourceObjectIfItStillExists(game);
- if (permanent != null) {
- return permanent.changeControllerId(source.getFirstTarget(), game);
- } else {
- discard();
+ Player controller = game.getPlayer(source.getControllerId());
+ if (controller == null) {
+ return false;
}
- return false;
+ Target target = new TargetOpponent();
+ target.setNotTarget(true);
+ if (!controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
+ return false;
+ }
+ Player player = game.getPlayer(target.getFirstTarget());
+ if (player == null) {
+ return false;
+ }
+ ContinuousEffect continuousEffect = new GainControlTargetEffect(
+ Duration.WhileOnBattlefield, true, player.getId()
+ );
+ continuousEffect.setTargetPointer(new FixedTarget(
+ source.getSourceId(), source.getSourceObjectZoneChangeCounter()
+ ));
+ game.addEffect(continuousEffect, source);
+ return true;
}
}
@@ -109,7 +122,7 @@ class XantchaSleeperAgentAttackRestrictionEffect extends RestrictionEffect {
staticText = "and can't attack its owner or planeswalkers its owner controls.";
}
- XantchaSleeperAgentAttackRestrictionEffect(final XantchaSleeperAgentAttackRestrictionEffect effect) {
+ private XantchaSleeperAgentAttackRestrictionEffect(final XantchaSleeperAgentAttackRestrictionEffect effect) {
super(effect);
}
@@ -125,14 +138,12 @@ class XantchaSleeperAgentAttackRestrictionEffect extends RestrictionEffect {
@Override
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
-
boolean allowAttack = true;
UUID ownerPlayerId = source.getSourcePermanentIfItStillExists(game).getOwnerId();
if (defenderId.equals(ownerPlayerId)) {
allowAttack = false;
- }
- else {
+ } else {
Permanent planeswalker = game.getPermanent(defenderId);
if (planeswalker != null && planeswalker.isControlledBy(ownerPlayerId)) {
allowAttack = false;
diff --git a/Mage.Sets/src/mage/cards/y/YdwenEfreet.java b/Mage.Sets/src/mage/cards/y/YdwenEfreet.java
index 9051ac2ca00..8f038cb3a2f 100644
--- a/Mage.Sets/src/mage/cards/y/YdwenEfreet.java
+++ b/Mage.Sets/src/mage/cards/y/YdwenEfreet.java
@@ -60,7 +60,7 @@ class YdwenEfreetEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent creature = game.getPermanent(source.getSourceId());
if (controller != null && creature != null) {
- if (!controller.flipCoin(game)) {
+ if (!controller.flipCoin(source, game, true)) {
creature.removeFromCombat(game);
creature.setMaxBlocks(0);
diff --git a/Mage.Sets/src/mage/cards/z/ZedruuTheGreathearted.java b/Mage.Sets/src/mage/cards/z/ZedruuTheGreathearted.java
index 88c4dfcd3dc..78c292f791e 100644
--- a/Mage.Sets/src/mage/cards/z/ZedruuTheGreathearted.java
+++ b/Mage.Sets/src/mage/cards/z/ZedruuTheGreathearted.java
@@ -35,10 +35,10 @@ public final class ZedruuTheGreathearted extends CardImpl {
this.toughness = new MageInt(4);
// At the beginning of your upkeep, you gain X life and draw X cards, where X is the number of permanents you own that your opponents control.
- Effect effect = new GainLifeEffect(new PermanentsYouOwnThatOpponentsControlCount());
+ Effect effect = new GainLifeEffect(PermanentsYouOwnThatOpponentsControlCount.instance);
effect.setText("you gain X life");
Ability ability = new BeginningOfUpkeepTriggeredAbility(effect, TargetController.YOU, false);
- effect = new DrawCardSourceControllerEffect(new PermanentsYouOwnThatOpponentsControlCount());
+ effect = new DrawCardSourceControllerEffect(PermanentsYouOwnThatOpponentsControlCount.instance);
effect.setText("and draw X cards, where X is the number of permanents you own that your opponents control");
ability.addEffect(effect);
this.addAbility(ability);
diff --git a/Mage.Sets/src/mage/sets/FifthEdition.java b/Mage.Sets/src/mage/sets/FifthEdition.java
index 6d6e93dbc63..5c5fb5f6dfb 100644
--- a/Mage.Sets/src/mage/sets/FifthEdition.java
+++ b/Mage.Sets/src/mage/sets/FifthEdition.java
@@ -368,6 +368,7 @@ public final class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Seasinger", 121, Rarity.UNCOMMON, mage.cards.s.Seasinger.class));
cards.add(new SetCardInfo("Segovian Leviathan", 122, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class));
cards.add(new SetCardInfo("Sengir Autocrat", 193, Rarity.RARE, mage.cards.s.SengirAutocrat.class));
+ cards.add(new SetCardInfo("Seraph", 59, Rarity.RARE, mage.cards.s.Seraph.class));
cards.add(new SetCardInfo("Serpent Generator", 397, Rarity.RARE, mage.cards.s.SerpentGenerator.class));
cards.add(new SetCardInfo("Serra Bestiary", 60, Rarity.UNCOMMON, mage.cards.s.SerraBestiary.class));
cards.add(new SetCardInfo("Serra Paladin", 61, Rarity.UNCOMMON, mage.cards.s.SerraPaladin.class));
diff --git a/Mage.Sets/src/mage/sets/Homelands.java b/Mage.Sets/src/mage/sets/Homelands.java
index cc54407c643..6705fa8c66e 100644
--- a/Mage.Sets/src/mage/sets/Homelands.java
+++ b/Mage.Sets/src/mage/sets/Homelands.java
@@ -136,7 +136,8 @@ public final class Homelands extends ExpansionSet {
cards.add(new SetCardInfo("Roots", 95, Rarity.UNCOMMON, mage.cards.r.Roots.class));
cards.add(new SetCardInfo("Roterothopter", 109, Rarity.COMMON, mage.cards.r.Roterothopter.class));
cards.add(new SetCardInfo("Rysorian Badger", 96, Rarity.RARE, mage.cards.r.RysorianBadger.class));
- cards.add(new SetCardInfo("Samite Alchemist", 117, Rarity.COMMON, mage.cards.s.SamiteAlchemist.class));
+ cards.add(new SetCardInfo("Samite Alchemist", "13a", Rarity.COMMON, mage.cards.s.SamiteAlchemist.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Samite Alchemist", "13b", Rarity.COMMON, mage.cards.s.SamiteAlchemist.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sea Sprite", 38, Rarity.UNCOMMON, mage.cards.s.SeaSprite.class));
cards.add(new SetCardInfo("Sea Troll", 39, Rarity.UNCOMMON, mage.cards.s.SeaTroll.class));
cards.add(new SetCardInfo("Sengir Autocrat", 56, Rarity.UNCOMMON, mage.cards.s.SengirAutocrat.class));
@@ -164,4 +165,4 @@ public final class Homelands extends ExpansionSet {
cards.add(new SetCardInfo("Winter Sky", 80, Rarity.RARE, mage.cards.w.WinterSky.class));
cards.add(new SetCardInfo("Wizards' School", 115, Rarity.UNCOMMON, mage.cards.w.WizardsSchool.class));
}
-}
\ No newline at end of file
+}
diff --git a/Mage.Sets/src/mage/sets/IceAge.java b/Mage.Sets/src/mage/sets/IceAge.java
index fa4f030febe..92bd54a7c97 100644
--- a/Mage.Sets/src/mage/sets/IceAge.java
+++ b/Mage.Sets/src/mage/sets/IceAge.java
@@ -29,6 +29,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Adarkar Sentinel", 306, Rarity.UNCOMMON, mage.cards.a.AdarkarSentinel.class));
cards.add(new SetCardInfo("Adarkar Wastes", 351, Rarity.RARE, mage.cards.a.AdarkarWastes.class));
cards.add(new SetCardInfo("Aegis of the Meek", 307, Rarity.RARE, mage.cards.a.AegisOfTheMeek.class));
+ cards.add(new SetCardInfo("Aggression", 169, Rarity.UNCOMMON, mage.cards.a.Aggression.class));
cards.add(new SetCardInfo("Altar of Bone", 281, Rarity.RARE, mage.cards.a.AltarOfBone.class));
cards.add(new SetCardInfo("Anarchy", 170, Rarity.UNCOMMON, mage.cards.a.Anarchy.class));
cards.add(new SetCardInfo("Arenson's Aura", 3, Rarity.COMMON, mage.cards.a.ArensonsAura.class));
@@ -62,6 +63,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Caribou Range", 11, Rarity.RARE, mage.cards.c.CaribouRange.class));
cards.add(new SetCardInfo("Celestial Sword", 314, Rarity.RARE, mage.cards.c.CelestialSword.class));
cards.add(new SetCardInfo("Centaur Archer", 282, Rarity.UNCOMMON, mage.cards.c.CentaurArcher.class));
+ cards.add(new SetCardInfo("Chaos Lord", 178, Rarity.RARE, mage.cards.c.ChaosLord.class));
cards.add(new SetCardInfo("Chaos Moon", 179, Rarity.RARE, mage.cards.c.ChaosMoon.class));
cards.add(new SetCardInfo("Chub Toad", 229, Rarity.COMMON, mage.cards.c.ChubToad.class));
cards.add(new SetCardInfo("Circle of Protection: Black", 12, Rarity.COMMON, mage.cards.c.CircleOfProtectionBlack.class));
@@ -287,6 +289,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Scaled Wurm", 262, Rarity.COMMON, mage.cards.s.ScaledWurm.class));
cards.add(new SetCardInfo("Sea Spirit", 95, Rarity.UNCOMMON, mage.cards.s.SeaSpirit.class));
cards.add(new SetCardInfo("Seizures", 159, Rarity.COMMON, mage.cards.s.Seizures.class));
+ cards.add(new SetCardInfo("Seraph", 51, Rarity.RARE, mage.cards.s.Seraph.class));
cards.add(new SetCardInfo("Shambling Strider", 263, Rarity.COMMON, mage.cards.s.ShamblingStrider.class));
cards.add(new SetCardInfo("Shatter", 216, Rarity.COMMON, mage.cards.s.Shatter.class));
cards.add(new SetCardInfo("Shield Bearer", 52, Rarity.COMMON, mage.cards.s.ShieldBearer.class));
@@ -356,6 +359,7 @@ public final class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Whalebone Glider", 349, Rarity.UNCOMMON, mage.cards.w.WhaleboneGlider.class));
cards.add(new SetCardInfo("White Scarab", 56, Rarity.UNCOMMON, mage.cards.w.WhiteScarab.class));
cards.add(new SetCardInfo("Whiteout", 275, Rarity.UNCOMMON, mage.cards.w.Whiteout.class));
+ cards.add(new SetCardInfo("Wiitigo", 276, Rarity.RARE, mage.cards.w.Wiitigo.class));
cards.add(new SetCardInfo("Wild Growth", 277, Rarity.COMMON, mage.cards.w.WildGrowth.class));
cards.add(new SetCardInfo("Wind Spirit", 106, Rarity.UNCOMMON, mage.cards.w.WindSpirit.class));
cards.add(new SetCardInfo("Wings of Aesthir", 305, Rarity.UNCOMMON, mage.cards.w.WingsOfAesthir.class));
diff --git a/Mage.Sets/src/mage/sets/Legends.java b/Mage.Sets/src/mage/sets/Legends.java
index 134bb3b75cb..f62c528b514 100644
--- a/Mage.Sets/src/mage/sets/Legends.java
+++ b/Mage.Sets/src/mage/sets/Legends.java
@@ -70,6 +70,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Cleanse", 5, Rarity.RARE, mage.cards.c.Cleanse.class));
cards.add(new SetCardInfo("Clergy of the Holy Nimbus", 6, Rarity.COMMON, mage.cards.c.ClergyOfTheHolyNimbus.class));
cards.add(new SetCardInfo("Concordant Crossroads", 179, Rarity.RARE, mage.cards.c.ConcordantCrossroads.class));
+ cards.add(new SetCardInfo("Cocoon", 178, Rarity.UNCOMMON, mage.cards.c.Cocoon.class));
cards.add(new SetCardInfo("Cosmic Horror", 92, Rarity.RARE, mage.cards.c.CosmicHorror.class));
cards.add(new SetCardInfo("Craw Giant", 180, Rarity.UNCOMMON, mage.cards.c.CrawGiant.class));
cards.add(new SetCardInfo("Crevasse", 138, Rarity.UNCOMMON, mage.cards.c.Crevasse.class));
@@ -101,6 +102,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Eureka", 185, Rarity.RARE, mage.cards.e.Eureka.class));
cards.add(new SetCardInfo("Evil Eye of Orms-by-Gore", 96, Rarity.UNCOMMON, mage.cards.e.EvilEyeOfOrmsByGore.class));
cards.add(new SetCardInfo("Fallen Angel", 97, Rarity.UNCOMMON, mage.cards.f.FallenAngel.class));
+ cards.add(new SetCardInfo("Feint", 146, Rarity.COMMON, mage.cards.f.Feint.class));
cards.add(new SetCardInfo("Field of Dreams", 55, Rarity.RARE, mage.cards.f.FieldOfDreams.class));
cards.add(new SetCardInfo("Fire Sprites", 186, Rarity.COMMON, mage.cards.f.FireSprites.class));
cards.add(new SetCardInfo("Flash Counter", 56, Rarity.COMMON, mage.cards.f.FlashCounter.class));
@@ -114,11 +116,13 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Gaseous Form", 59, Rarity.COMMON, mage.cards.g.GaseousForm.class));
cards.add(new SetCardInfo("Gauntlets of Chaos", 278, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class));
cards.add(new SetCardInfo("Ghosts of the Damned", 98, Rarity.COMMON, mage.cards.g.GhostsOfTheDamned.class));
+ cards.add(new SetCardInfo("Giant Slug", 99, Rarity.COMMON, mage.cards.g.GiantSlug.class));
cards.add(new SetCardInfo("Giant Strength", 149, Rarity.COMMON, mage.cards.g.GiantStrength.class));
cards.add(new SetCardInfo("Giant Turtle", 188, Rarity.COMMON, mage.cards.g.GiantTurtle.class));
cards.add(new SetCardInfo("Glyph of Destruction", 150, Rarity.COMMON, mage.cards.g.GlyphOfDestruction.class));
cards.add(new SetCardInfo("Glyph of Doom", 100, Rarity.COMMON, mage.cards.g.GlyphOfDoom.class));
cards.add(new SetCardInfo("Glyph of Life", 15, Rarity.COMMON, mage.cards.g.GlyphOfLife.class));
+ cards.add(new SetCardInfo("Glyph of Reincarnation", 189, Rarity.COMMON, mage.cards.g.GlyphOfReincarnation.class));
cards.add(new SetCardInfo("Gosta Dirk", 227, Rarity.RARE, mage.cards.g.GostaDirk.class));
cards.add(new SetCardInfo("Gravity Sphere", 151, Rarity.RARE, mage.cards.g.GravitySphere.class));
cards.add(new SetCardInfo("Great Defender", 16, Rarity.UNCOMMON, mage.cards.g.GreatDefender.class));
@@ -172,6 +176,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Land Equilibrium", 64, Rarity.RARE, mage.cards.l.LandEquilibrium.class));
cards.add(new SetCardInfo("Land Tax", 26, Rarity.UNCOMMON, mage.cards.l.LandTax.class));
cards.add(new SetCardInfo("Land's Edge", 158, Rarity.RARE, mage.cards.l.LandsEdge.class));
+ cards.add(new SetCardInfo("Lesser Werewolf", 110, Rarity.UNCOMMON, mage.cards.l.LesserWerewolf.class));
cards.add(new SetCardInfo("Life Chisel", 283, Rarity.UNCOMMON, mage.cards.l.LifeChisel.class));
cards.add(new SetCardInfo("Lifeblood", 27, Rarity.RARE, mage.cards.l.Lifeblood.class));
cards.add(new SetCardInfo("Living Plane", 193, Rarity.RARE, mage.cards.l.LivingPlane.class));
@@ -208,6 +213,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Princess Lucrezia", 249, Rarity.UNCOMMON, mage.cards.p.PrincessLucrezia.class));
cards.add(new SetCardInfo("Psionic Entity", 67, Rarity.RARE, mage.cards.p.PsionicEntity.class));
cards.add(new SetCardInfo("Psychic Purge", 68, Rarity.COMMON, mage.cards.p.PsychicPurge.class));
+ cards.add(new SetCardInfo("Puppet Master", 69, Rarity.UNCOMMON, mage.cards.p.PuppetMaster.class));
cards.add(new SetCardInfo("Pyrotechnics", 161, Rarity.COMMON, mage.cards.p.Pyrotechnics.class));
cards.add(new SetCardInfo("Quagmire", 115, Rarity.UNCOMMON, mage.cards.q.Quagmire.class));
cards.add(new SetCardInfo("Rabid Wombat", 198, Rarity.UNCOMMON, mage.cards.r.RabidWombat.class));
@@ -216,6 +222,7 @@ public final class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Ragnar", 250, Rarity.RARE, mage.cards.r.Ragnar.class));
cards.add(new SetCardInfo("Ramirez DePietro", 251, Rarity.UNCOMMON, mage.cards.r.RamirezDePietro.class));
cards.add(new SetCardInfo("Ramses Overdark", 252, Rarity.RARE, mage.cards.r.RamsesOverdark.class));
+ cards.add(new SetCardInfo("Rapid Fire", 32, Rarity.RARE, mage.cards.r.RapidFire.class));
cards.add(new SetCardInfo("Rasputin Dreamweaver", 253, Rarity.RARE, mage.cards.r.RasputinDreamweaver.class));
cards.add(new SetCardInfo("Recall", 70, Rarity.RARE, mage.cards.r.Recall.class));
cards.add(new SetCardInfo("Red Mana Battery", 291, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class));
diff --git a/Mage.Sets/src/mage/sets/MastersEdition.java b/Mage.Sets/src/mage/sets/MastersEdition.java
index 99486fa7575..17317b3cd8a 100644
--- a/Mage.Sets/src/mage/sets/MastersEdition.java
+++ b/Mage.Sets/src/mage/sets/MastersEdition.java
@@ -1,222 +1,223 @@
-
-package mage.sets;
-
-import mage.cards.ExpansionSet;
-import mage.constants.Rarity;
-import mage.constants.SetType;
-
-/**
- * @author LevelX2
- */
-public final class MastersEdition extends ExpansionSet {
-
- private static final MastersEdition instance = new MastersEdition();
-
- public static MastersEdition getInstance() {
- return instance;
- }
-
- private MastersEdition() {
- super("Masters Edition", "MED", ExpansionSet.buildDate(2007, 9, 10), SetType.MAGIC_ONLINE);
- this.hasBasicLands = true;
- this.hasBoosters = true;
- this.numBoosterLands = 1;
- this.numBoosterCommon = 10;
- this.numBoosterUncommon = 3;
- this.numBoosterRare = 1;
- this.ratioBoosterMythic = 0;
-
- cards.add(new SetCardInfo("Adun Oakenshield", 141, Rarity.RARE, mage.cards.a.AdunOakenshield.class));
- cards.add(new SetCardInfo("Amnesia", 29, Rarity.RARE, mage.cards.a.Amnesia.class));
- cards.add(new SetCardInfo("Angry Mob", 1, Rarity.UNCOMMON, mage.cards.a.AngryMob.class));
- cards.add(new SetCardInfo("Animate Dead", 57, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class));
- cards.add(new SetCardInfo("Animate Wall", 2, Rarity.UNCOMMON, mage.cards.a.AnimateWall.class));
- cards.add(new SetCardInfo("Ankh of Mishra", 151, Rarity.RARE, mage.cards.a.AnkhOfMishra.class));
- cards.add(new SetCardInfo("Apprentice Wizard", 30, Rarity.COMMON, mage.cards.a.ApprenticeWizard.class));
- cards.add(new SetCardInfo("Arcane Denial", 31, Rarity.COMMON, mage.cards.a.ArcaneDenial.class));
- cards.add(new SetCardInfo("Argivian Archaeologist", 3, Rarity.RARE, mage.cards.a.ArgivianArchaeologist.class));
- cards.add(new SetCardInfo("Armageddon", 4, Rarity.RARE, mage.cards.a.Armageddon.class));
- cards.add(new SetCardInfo("Artifact Blast", 85, Rarity.COMMON, mage.cards.a.ArtifactBlast.class));
- cards.add(new SetCardInfo("Ashnod's Transmogrant", 152, Rarity.COMMON, mage.cards.a.AshnodsTransmogrant.class));
- cards.add(new SetCardInfo("Autumn Willow", 113, Rarity.RARE, mage.cards.a.AutumnWillow.class));
- cards.add(new SetCardInfo("Balduvian Horde", 86, Rarity.RARE, mage.cards.b.BalduvianHorde.class));
- cards.add(new SetCardInfo("Ball Lightning", 87, Rarity.RARE, mage.cards.b.BallLightning.class));
- cards.add(new SetCardInfo("Baron Sengir", 58, Rarity.RARE, mage.cards.b.BaronSengir.class));
- cards.add(new SetCardInfo("Basal Thrull", 59, Rarity.COMMON, mage.cards.b.BasalThrull.class));
- cards.add(new SetCardInfo("Benalish Hero", 5, Rarity.COMMON, mage.cards.b.BenalishHero.class));
- cards.add(new SetCardInfo("Berserk", 114, Rarity.RARE, mage.cards.b.Berserk.class));
- cards.add(new SetCardInfo("Bestial Fury", 88, Rarity.COMMON, mage.cards.b.BestialFury.class));
- cards.add(new SetCardInfo("Black Knight", 60, Rarity.UNCOMMON, mage.cards.b.BlackKnight.class));
- cards.add(new SetCardInfo("Blight", 61, Rarity.UNCOMMON, mage.cards.b.Blight.class));
- cards.add(new SetCardInfo("Breeding Pit", 62, Rarity.UNCOMMON, mage.cards.b.BreedingPit.class));
- cards.add(new SetCardInfo("Brothers of Fire", 89, Rarity.COMMON, mage.cards.b.BrothersOfFire.class));
- cards.add(new SetCardInfo("Carnivorous Plant", 115, Rarity.UNCOMMON, mage.cards.c.CarnivorousPlant.class));
- cards.add(new SetCardInfo("Centaur Archer", 142, Rarity.UNCOMMON, mage.cards.c.CentaurArcher.class));
- cards.add(new SetCardInfo("Chains of Mephistopheles", 63, Rarity.RARE, mage.cards.c.ChainsOfMephistopheles.class));
- cards.add(new SetCardInfo("Chub Toad", 116, Rarity.COMMON, mage.cards.c.ChubToad.class));
- cards.add(new SetCardInfo("Clockwork Beast", 153, Rarity.UNCOMMON, mage.cards.c.ClockworkBeast.class));
- cards.add(new SetCardInfo("Contagion", 64, Rarity.RARE, mage.cards.c.Contagion.class));
- cards.add(new SetCardInfo("Copper Tablet", 154, Rarity.UNCOMMON, mage.cards.c.CopperTablet.class));
- cards.add(new SetCardInfo("Crookshank Kobolds", 90, Rarity.COMMON, mage.cards.c.CrookshankKobolds.class));
- cards.add(new SetCardInfo("Crusade", 6, Rarity.RARE, mage.cards.c.Crusade.class));
- cards.add(new SetCardInfo("Cuombajj Witches", 65, Rarity.COMMON, mage.cards.c.CuombajjWitches.class));
- cards.add(new SetCardInfo("Cursed Rack", 155, Rarity.UNCOMMON, mage.cards.c.CursedRack.class));
- cards.add(new SetCardInfo("Dakkon Blackblade", 143, Rarity.RARE, mage.cards.d.DakkonBlackblade.class));
- cards.add(new SetCardInfo("Death Speakers", 7, Rarity.COMMON, mage.cards.d.DeathSpeakers.class));
- cards.add(new SetCardInfo("Death Ward", 8, Rarity.COMMON, mage.cards.d.DeathWard.class));
- cards.add(new SetCardInfo("Derelor", 66, Rarity.UNCOMMON, mage.cards.d.Derelor.class));
- cards.add(new SetCardInfo("Diamond Valley", 175, Rarity.RARE, mage.cards.d.DiamondValley.class));
- cards.add(new SetCardInfo("Diminishing Returns", 32, Rarity.RARE, mage.cards.d.DiminishingReturns.class));
- cards.add(new SetCardInfo("Divine Transformation", 9, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class));
- cards.add(new SetCardInfo("Dragon Engine", 156, Rarity.COMMON, mage.cards.d.DragonEngine.class));
- cards.add(new SetCardInfo("Dust to Dust", 10, Rarity.COMMON, mage.cards.d.DustToDust.class));
- cards.add(new SetCardInfo("Dwarven Catapult", 91, Rarity.UNCOMMON, mage.cards.d.DwarvenCatapult.class));
- cards.add(new SetCardInfo("Dwarven Soldier", 92, Rarity.COMMON, mage.cards.d.DwarvenSoldier.class));
- cards.add(new SetCardInfo("Eater of the Dead", 67, Rarity.UNCOMMON, mage.cards.e.EaterOfTheDead.class));
- cards.add(new SetCardInfo("Elder Land Wurm", 11, Rarity.UNCOMMON, mage.cards.e.ElderLandWurm.class));
- cards.add(new SetCardInfo("Erg Raiders", 68, Rarity.COMMON, mage.cards.e.ErgRaiders.class));
- cards.add(new SetCardInfo("Eureka", 117, Rarity.RARE, mage.cards.e.Eureka.class));
- cards.add(new SetCardInfo("Exile", 12, Rarity.COMMON, mage.cards.e.Exile.class));
- cards.add(new SetCardInfo("The Fallen", 69, Rarity.UNCOMMON, mage.cards.t.TheFallen.class));
- cards.add(new SetCardInfo("Feast or Famine", 70, Rarity.COMMON, mage.cards.f.FeastOrFamine.class));
- cards.add(new SetCardInfo("Fire Covenant", 145, Rarity.UNCOMMON, mage.cards.f.FireCovenant.class));
- cards.add(new SetCardInfo("Fissure", 93, Rarity.COMMON, mage.cards.f.Fissure.class));
- cards.add(new SetCardInfo("Forcefield", 157, Rarity.RARE, mage.cards.f.Forcefield.class));
- cards.add(new SetCardInfo("Force of Will", 33, Rarity.RARE, mage.cards.f.ForceOfWill.class));
- cards.add(new SetCardInfo("Forest", 193, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Forest", 194, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Forest", 195, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Fyndhorn Elves", 118, Rarity.COMMON, mage.cards.f.FyndhornElves.class));
- cards.add(new SetCardInfo("Ghazban Ogre", 120, Rarity.COMMON, mage.cards.g.GhazbanOgre.class));
- cards.add(new SetCardInfo("Giant Tortoise", 34, Rarity.COMMON, mage.cards.g.GiantTortoise.class));
- cards.add(new SetCardInfo("Goblin Chirurgeon", 94, Rarity.COMMON, mage.cards.g.GoblinChirurgeon.class));
- cards.add(new SetCardInfo("Goblin Grenade", 95, Rarity.UNCOMMON, mage.cards.g.GoblinGrenade.class));
- cards.add(new SetCardInfo("Goblin Mutant", 96, Rarity.UNCOMMON, mage.cards.g.GoblinMutant.class));
- cards.add(new SetCardInfo("Goblins of the Flarg", 98, Rarity.COMMON, mage.cards.g.GoblinsOfTheFlarg.class));
- cards.add(new SetCardInfo("Goblin Wizard", 97, Rarity.RARE, mage.cards.g.GoblinWizard.class));
- cards.add(new SetCardInfo("Granite Gargoyle", 99, Rarity.UNCOMMON, mage.cards.g.GraniteGargoyle.class));
- cards.add(new SetCardInfo("Greater Realm of Preservation", 13, Rarity.UNCOMMON, mage.cards.g.GreaterRealmOfPreservation.class));
- cards.add(new SetCardInfo("Hallowed Ground", 14, Rarity.UNCOMMON, mage.cards.h.HallowedGround.class));
- cards.add(new SetCardInfo("Hand of Justice", 15, Rarity.RARE, mage.cards.h.HandOfJustice.class));
- cards.add(new SetCardInfo("Hecatomb", 71, Rarity.RARE, mage.cards.h.Hecatomb.class));
- cards.add(new SetCardInfo("High Tide", 35, Rarity.UNCOMMON, mage.cards.h.HighTide.class));
- cards.add(new SetCardInfo("Holy Light", 16, Rarity.COMMON, mage.cards.h.HolyLight.class));
- cards.add(new SetCardInfo("Homarid Spawning Bed", 36, Rarity.UNCOMMON, mage.cards.h.HomaridSpawningBed.class));
- cards.add(new SetCardInfo("Hungry Mist", 121, Rarity.COMMON, mage.cards.h.HungryMist.class));
- cards.add(new SetCardInfo("Hyalopterous Lemure", 72, Rarity.COMMON, mage.cards.h.HyalopterousLemure.class));
- cards.add(new SetCardInfo("Hydroblast", 37, Rarity.COMMON, mage.cards.h.Hydroblast.class));
- cards.add(new SetCardInfo("Hymn of Rebirth", 146, Rarity.UNCOMMON, mage.cards.h.HymnOfRebirth.class));
- cards.add(new SetCardInfo("Hymn to Tourach", 73, Rarity.UNCOMMON, mage.cards.h.HymnToTourach.class));
- cards.add(new SetCardInfo("Icatian Lieutenant", 17, Rarity.COMMON, mage.cards.i.IcatianLieutenant.class));
- cards.add(new SetCardInfo("Icatian Town", 18, Rarity.UNCOMMON, mage.cards.i.IcatianTown.class));
- cards.add(new SetCardInfo("Ice Storm", 122, Rarity.UNCOMMON, mage.cards.i.IceStorm.class));
- cards.add(new SetCardInfo("Ifh-Biff Efreet", 123, Rarity.RARE, mage.cards.i.IfhBiffEfreet.class));
- cards.add(new SetCardInfo("Illusionary Forces", 38, Rarity.UNCOMMON, mage.cards.i.IllusionaryForces.class));
- cards.add(new SetCardInfo("Illusionary Wall", 39, Rarity.COMMON, mage.cards.i.IllusionaryWall.class));
- cards.add(new SetCardInfo("Illusions of Grandeur", 40, Rarity.RARE, mage.cards.i.IllusionsOfGrandeur.class));
- cards.add(new SetCardInfo("Island", 184, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Island", 185, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Island", 186, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Island of Wak-Wak", 176, Rarity.RARE, mage.cards.i.IslandOfWakWak.class));
- cards.add(new SetCardInfo("Ivory Tower", 158, Rarity.RARE, mage.cards.i.IvoryTower.class));
- cards.add(new SetCardInfo("Jacques le Vert", 147, Rarity.RARE, mage.cards.j.JacquesLeVert.class));
- cards.add(new SetCardInfo("Jokulhaups", 100, Rarity.RARE, mage.cards.j.Jokulhaups.class));
- cards.add(new SetCardInfo("Juxtapose", 41, Rarity.UNCOMMON, mage.cards.j.Juxtapose.class));
- cards.add(new SetCardInfo("Juzam Djinn", 74, Rarity.RARE, mage.cards.j.JuzamDjinn.class));
- cards.add(new SetCardInfo("Keldon Warlord", 101, Rarity.UNCOMMON, mage.cards.k.KeldonWarlord.class));
- cards.add(new SetCardInfo("Khabal Ghoul", 75, Rarity.RARE, mage.cards.k.KhabalGhoul.class));
- cards.add(new SetCardInfo("Knights of Thorn", 19, Rarity.COMMON, mage.cards.k.KnightsOfThorn.class));
- cards.add(new SetCardInfo("Lake of the Dead", 177, Rarity.RARE, mage.cards.l.LakeOfTheDead.class));
- cards.add(new SetCardInfo("Lightning Bolt", 102, Rarity.COMMON, mage.cards.l.LightningBolt.class));
- cards.add(new SetCardInfo("Lim-Dul's Vault", 148, Rarity.UNCOMMON, mage.cards.l.LimDulsVault.class));
- cards.add(new SetCardInfo("Lord of Tresserhorn", 149, Rarity.RARE, mage.cards.l.LordOfTresserhorn.class));
- cards.add(new SetCardInfo("Mana Flare", 103, Rarity.RARE, mage.cards.m.ManaFlare.class));
- cards.add(new SetCardInfo("Marton Stromgald", 104, Rarity.RARE, mage.cards.m.MartonStromgald.class));
- cards.add(new SetCardInfo("Mesa Pegasus", 20, Rarity.COMMON, mage.cards.m.MesaPegasus.class));
- cards.add(new SetCardInfo("Mindstab Thrull", 76, Rarity.COMMON, mage.cards.m.MindstabThrull.class));
- cards.add(new SetCardInfo("Mirror Universe", 159, Rarity.RARE, mage.cards.m.MirrorUniverse.class));
- cards.add(new SetCardInfo("Mishra's Factory", 178, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class));
- cards.add(new SetCardInfo("Moat", 21, Rarity.RARE, mage.cards.m.Moat.class));
- cards.add(new SetCardInfo("Mountain", 190, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Mountain", 191, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Mountain", 192, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Mountain Yeti", 105, Rarity.COMMON, mage.cards.m.MountainYeti.class));
- cards.add(new SetCardInfo("Mystic Remora", 42, Rarity.UNCOMMON, mage.cards.m.MysticRemora.class));
- cards.add(new SetCardInfo("Nature's Lore", 124, Rarity.COMMON, mage.cards.n.NaturesLore.class));
- cards.add(new SetCardInfo("Nether Shadow", 77, Rarity.UNCOMMON, mage.cards.n.NetherShadow.class));
- cards.add(new SetCardInfo("Nevinyrral's Disk", 160, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class));
- cards.add(new SetCardInfo("Onulet", 161, Rarity.COMMON, mage.cards.o.Onulet.class));
- cards.add(new SetCardInfo("Orcish Mechanics", 106, Rarity.UNCOMMON, mage.cards.o.OrcishMechanics.class));
- cards.add(new SetCardInfo("Order of Leitbur", 22, Rarity.COMMON, mage.cards.o.OrderOfLeitbur.class));
- cards.add(new SetCardInfo("Order of the Ebon Hand", 78, Rarity.COMMON, mage.cards.o.OrderOfTheEbonHand.class));
- cards.add(new SetCardInfo("Oubliette", 79, Rarity.COMMON, mage.cards.o.Oubliette.class));
- cards.add(new SetCardInfo("Paralyze", 80, Rarity.COMMON, mage.cards.p.Paralyze.class));
- cards.add(new SetCardInfo("Petra Sphinx", 23, Rarity.RARE, mage.cards.p.PetraSphinx.class));
- cards.add(new SetCardInfo("Phantom Monster", 43, Rarity.COMMON, mage.cards.p.PhantomMonster.class));
- cards.add(new SetCardInfo("Phelddagrif", 150, Rarity.RARE, mage.cards.p.Phelddagrif.class));
- cards.add(new SetCardInfo("Phyrexian Boon", 81, Rarity.COMMON, mage.cards.p.PhyrexianBoon.class));
- cards.add(new SetCardInfo("Phyrexian War Beast", 162, Rarity.UNCOMMON, mage.cards.p.PhyrexianWarBeast.class));
- cards.add(new SetCardInfo("Plains", 181, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Plains", 182, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Plains", 183, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Polar Kraken", 44, Rarity.RARE, mage.cards.p.PolarKraken.class));
- cards.add(new SetCardInfo("Pox", 82, Rarity.RARE, mage.cards.p.Pox.class));
- cards.add(new SetCardInfo("Preacher", 24, Rarity.RARE, mage.cards.p.Preacher.class));
- cards.add(new SetCardInfo("Primal Order", 125, Rarity.RARE, mage.cards.p.PrimalOrder.class));
- cards.add(new SetCardInfo("Psychic Purge", 45, Rarity.UNCOMMON, mage.cards.p.PsychicPurge.class));
- cards.add(new SetCardInfo("Psychic Venom", 46, Rarity.COMMON, mage.cards.p.PsychicVenom.class));
- cards.add(new SetCardInfo("Pyroblast", 107, Rarity.COMMON, mage.cards.p.Pyroblast.class));
- cards.add(new SetCardInfo("Rabid Wombat", 126, Rarity.UNCOMMON, mage.cards.r.RabidWombat.class));
- cards.add(new SetCardInfo("Rainbow Vale", 179, Rarity.RARE, mage.cards.r.RainbowVale.class));
- cards.add(new SetCardInfo("Righteous Avengers", 25, Rarity.COMMON, mage.cards.r.RighteousAvengers.class));
- cards.add(new SetCardInfo("Ring of Ma'ruf", 163, Rarity.RARE, mage.cards.r.RingOfMaruf.class));
- cards.add(new SetCardInfo("River Merfolk", 47, Rarity.COMMON, mage.cards.r.RiverMerfolk.class));
- cards.add(new SetCardInfo("Roots", 127, Rarity.COMMON, mage.cards.r.Roots.class));
- cards.add(new SetCardInfo("Scryb Sprites", 128, Rarity.COMMON, mage.cards.s.ScrybSprites.class));
- cards.add(new SetCardInfo("Seasinger", 49, Rarity.UNCOMMON, mage.cards.s.Seasinger.class));
- cards.add(new SetCardInfo("Sea Sprite", 48, Rarity.COMMON, mage.cards.s.SeaSprite.class));
- cards.add(new SetCardInfo("Serendib Efreet", 50, Rarity.RARE, mage.cards.s.SerendibEfreet.class));
- cards.add(new SetCardInfo("Serpent Generator", 164, Rarity.RARE, mage.cards.s.SerpentGenerator.class));
- cards.add(new SetCardInfo("Shambling Strider", 129, Rarity.COMMON, mage.cards.s.ShamblingStrider.class));
- cards.add(new SetCardInfo("Shield of the Ages", 165, Rarity.UNCOMMON, mage.cards.s.ShieldOfTheAges.class));
- cards.add(new SetCardInfo("Shield Sphere", 166, Rarity.COMMON, mage.cards.s.ShieldSphere.class));
- cards.add(new SetCardInfo("Singing Tree", 130, Rarity.UNCOMMON, mage.cards.s.SingingTree.class));
- cards.add(new SetCardInfo("Spectral Bears", 131, Rarity.UNCOMMON, mage.cards.s.SpectralBears.class));
- cards.add(new SetCardInfo("Spinal Villain", 108, Rarity.UNCOMMON, mage.cards.s.SpinalVillain.class));
- cards.add(new SetCardInfo("Stone Calendar", 167, Rarity.UNCOMMON, mage.cards.s.StoneCalendar.class));
- cards.add(new SetCardInfo("Stone Giant", 109, Rarity.UNCOMMON, mage.cards.s.StoneGiant.class));
- cards.add(new SetCardInfo("Storm Seeker", 132, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class));
- cards.add(new SetCardInfo("Su-Chi", 168, Rarity.RARE, mage.cards.s.SuChi.class));
- cards.add(new SetCardInfo("Sunken City", 51, Rarity.UNCOMMON, mage.cards.s.SunkenCity.class));
- cards.add(new SetCardInfo("Swamp", 187, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Swamp", 188, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Swamp", 189, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
- cards.add(new SetCardInfo("Sylvan Library", 133, Rarity.RARE, mage.cards.s.SylvanLibrary.class));
- cards.add(new SetCardInfo("Tawnos's Coffin", 169, Rarity.RARE, mage.cards.t.TawnossCoffin.class));
- cards.add(new SetCardInfo("Telekinesis", 52, Rarity.COMMON, mage.cards.t.Telekinesis.class));
- cards.add(new SetCardInfo("Thawing Glaciers", 180, Rarity.RARE, mage.cards.t.ThawingGlaciers.class));
- cards.add(new SetCardInfo("Thicket Basilisk", 134, Rarity.UNCOMMON, mage.cards.t.ThicketBasilisk.class));
- cards.add(new SetCardInfo("Thorn Thallid", 135, Rarity.COMMON, mage.cards.t.ThornThallid.class));
- cards.add(new SetCardInfo("Thrull Champion", 83, Rarity.RARE, mage.cards.t.ThrullChampion.class));
- cards.add(new SetCardInfo("Thrull Retainer", 84, Rarity.COMMON, mage.cards.t.ThrullRetainer.class));
- cards.add(new SetCardInfo("Thunder Spirit", 27, Rarity.UNCOMMON, mage.cards.t.ThunderSpirit.class));
- cards.add(new SetCardInfo("Time Elemental", 53, Rarity.RARE, mage.cards.t.TimeElemental.class));
- cards.add(new SetCardInfo("Tivadar's Crusade", 28, Rarity.UNCOMMON, mage.cards.t.TivadarsCrusade.class));
- cards.add(new SetCardInfo("Tornado", 136, Rarity.RARE, mage.cards.t.Tornado.class));
- cards.add(new SetCardInfo("Urza's Bauble", 170, Rarity.UNCOMMON, mage.cards.u.UrzasBauble.class));
- cards.add(new SetCardInfo("Urza's Chalice", 171, Rarity.COMMON, mage.cards.u.UrzasChalice.class));
- cards.add(new SetCardInfo("Varchild's War-Riders", 110, Rarity.RARE, mage.cards.v.VarchildsWarRiders.class));
- cards.add(new SetCardInfo("Vesuvan Doppelganger", 54, Rarity.RARE, mage.cards.v.VesuvanDoppelganger.class));
- cards.add(new SetCardInfo("Vodalian Knights", 55, Rarity.UNCOMMON, mage.cards.v.VodalianKnights.class));
- cards.add(new SetCardInfo("Walking Wall", 172, Rarity.UNCOMMON, mage.cards.w.WalkingWall.class));
- cards.add(new SetCardInfo("Wanderlust", 137, Rarity.COMMON, mage.cards.w.Wanderlust.class));
- cards.add(new SetCardInfo("Winds of Change", 111, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class));
- cards.add(new SetCardInfo("Winter Blast", 138, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class));
- cards.add(new SetCardInfo("Winter Orb", 173, Rarity.RARE, mage.cards.w.WinterOrb.class));
- cards.add(new SetCardInfo("Word of Undoing", 56, Rarity.COMMON, mage.cards.w.WordOfUndoing.class));
- cards.add(new SetCardInfo("Wyluli Wolf", 139, Rarity.COMMON, mage.cards.w.WyluliWolf.class));
- cards.add(new SetCardInfo("Yavimaya Ants", 140, Rarity.UNCOMMON, mage.cards.y.YavimayaAnts.class));
- cards.add(new SetCardInfo("Ydwen Efreet", 112, Rarity.RARE, mage.cards.y.YdwenEfreet.class));
- cards.add(new SetCardInfo("Zuran Orb", 174, Rarity.UNCOMMON, mage.cards.z.ZuranOrb.class));
- }
+
+package mage.sets;
+
+import mage.cards.ExpansionSet;
+import mage.constants.Rarity;
+import mage.constants.SetType;
+
+/**
+ * @author LevelX2
+ */
+public final class MastersEdition extends ExpansionSet {
+
+ private static final MastersEdition instance = new MastersEdition();
+
+ public static MastersEdition getInstance() {
+ return instance;
+ }
+
+ private MastersEdition() {
+ super("Masters Edition", "MED", ExpansionSet.buildDate(2007, 9, 10), SetType.MAGIC_ONLINE);
+ this.hasBasicLands = true;
+ this.hasBoosters = true;
+ this.numBoosterLands = 1;
+ this.numBoosterCommon = 10;
+ this.numBoosterUncommon = 3;
+ this.numBoosterRare = 1;
+ this.ratioBoosterMythic = 0;
+
+ cards.add(new SetCardInfo("Adun Oakenshield", 141, Rarity.RARE, mage.cards.a.AdunOakenshield.class));
+ cards.add(new SetCardInfo("Amnesia", 29, Rarity.RARE, mage.cards.a.Amnesia.class));
+ cards.add(new SetCardInfo("Angry Mob", 1, Rarity.UNCOMMON, mage.cards.a.AngryMob.class));
+ cards.add(new SetCardInfo("Animate Dead", 57, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class));
+ cards.add(new SetCardInfo("Animate Wall", 2, Rarity.UNCOMMON, mage.cards.a.AnimateWall.class));
+ cards.add(new SetCardInfo("Ankh of Mishra", 151, Rarity.RARE, mage.cards.a.AnkhOfMishra.class));
+ cards.add(new SetCardInfo("Apprentice Wizard", 30, Rarity.COMMON, mage.cards.a.ApprenticeWizard.class));
+ cards.add(new SetCardInfo("Arcane Denial", 31, Rarity.COMMON, mage.cards.a.ArcaneDenial.class));
+ cards.add(new SetCardInfo("Argivian Archaeologist", 3, Rarity.RARE, mage.cards.a.ArgivianArchaeologist.class));
+ cards.add(new SetCardInfo("Armageddon", 4, Rarity.RARE, mage.cards.a.Armageddon.class));
+ cards.add(new SetCardInfo("Artifact Blast", 85, Rarity.COMMON, mage.cards.a.ArtifactBlast.class));
+ cards.add(new SetCardInfo("Ashnod's Transmogrant", 152, Rarity.COMMON, mage.cards.a.AshnodsTransmogrant.class));
+ cards.add(new SetCardInfo("Autumn Willow", 113, Rarity.RARE, mage.cards.a.AutumnWillow.class));
+ cards.add(new SetCardInfo("Balduvian Horde", 86, Rarity.RARE, mage.cards.b.BalduvianHorde.class));
+ cards.add(new SetCardInfo("Ball Lightning", 87, Rarity.RARE, mage.cards.b.BallLightning.class));
+ cards.add(new SetCardInfo("Baron Sengir", 58, Rarity.RARE, mage.cards.b.BaronSengir.class));
+ cards.add(new SetCardInfo("Basal Thrull", 59, Rarity.COMMON, mage.cards.b.BasalThrull.class));
+ cards.add(new SetCardInfo("Benalish Hero", 5, Rarity.COMMON, mage.cards.b.BenalishHero.class));
+ cards.add(new SetCardInfo("Berserk", 114, Rarity.RARE, mage.cards.b.Berserk.class));
+ cards.add(new SetCardInfo("Bestial Fury", 88, Rarity.COMMON, mage.cards.b.BestialFury.class));
+ cards.add(new SetCardInfo("Black Knight", 60, Rarity.UNCOMMON, mage.cards.b.BlackKnight.class));
+ cards.add(new SetCardInfo("Blight", 61, Rarity.UNCOMMON, mage.cards.b.Blight.class));
+ cards.add(new SetCardInfo("Breeding Pit", 62, Rarity.UNCOMMON, mage.cards.b.BreedingPit.class));
+ cards.add(new SetCardInfo("Brothers of Fire", 89, Rarity.COMMON, mage.cards.b.BrothersOfFire.class));
+ cards.add(new SetCardInfo("Carnivorous Plant", 115, Rarity.UNCOMMON, mage.cards.c.CarnivorousPlant.class));
+ cards.add(new SetCardInfo("Centaur Archer", 142, Rarity.UNCOMMON, mage.cards.c.CentaurArcher.class));
+ cards.add(new SetCardInfo("Chains of Mephistopheles", 63, Rarity.RARE, mage.cards.c.ChainsOfMephistopheles.class));
+ cards.add(new SetCardInfo("Chub Toad", 116, Rarity.COMMON, mage.cards.c.ChubToad.class));
+ cards.add(new SetCardInfo("Clockwork Beast", 153, Rarity.UNCOMMON, mage.cards.c.ClockworkBeast.class));
+ cards.add(new SetCardInfo("Contagion", 64, Rarity.RARE, mage.cards.c.Contagion.class));
+ cards.add(new SetCardInfo("Copper Tablet", 154, Rarity.UNCOMMON, mage.cards.c.CopperTablet.class));
+ cards.add(new SetCardInfo("Crookshank Kobolds", 90, Rarity.COMMON, mage.cards.c.CrookshankKobolds.class));
+ cards.add(new SetCardInfo("Crusade", 6, Rarity.RARE, mage.cards.c.Crusade.class));
+ cards.add(new SetCardInfo("Cuombajj Witches", 65, Rarity.COMMON, mage.cards.c.CuombajjWitches.class));
+ cards.add(new SetCardInfo("Cursed Rack", 155, Rarity.UNCOMMON, mage.cards.c.CursedRack.class));
+ cards.add(new SetCardInfo("Dakkon Blackblade", 143, Rarity.RARE, mage.cards.d.DakkonBlackblade.class));
+ cards.add(new SetCardInfo("Death Speakers", 7, Rarity.COMMON, mage.cards.d.DeathSpeakers.class));
+ cards.add(new SetCardInfo("Death Ward", 8, Rarity.COMMON, mage.cards.d.DeathWard.class));
+ cards.add(new SetCardInfo("Derelor", 66, Rarity.UNCOMMON, mage.cards.d.Derelor.class));
+ cards.add(new SetCardInfo("Diamond Valley", 175, Rarity.RARE, mage.cards.d.DiamondValley.class));
+ cards.add(new SetCardInfo("Diminishing Returns", 32, Rarity.RARE, mage.cards.d.DiminishingReturns.class));
+ cards.add(new SetCardInfo("Divine Transformation", 9, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class));
+ cards.add(new SetCardInfo("Dragon Engine", 156, Rarity.COMMON, mage.cards.d.DragonEngine.class));
+ cards.add(new SetCardInfo("Dust to Dust", 10, Rarity.COMMON, mage.cards.d.DustToDust.class));
+ cards.add(new SetCardInfo("Dwarven Catapult", 91, Rarity.UNCOMMON, mage.cards.d.DwarvenCatapult.class));
+ cards.add(new SetCardInfo("Dwarven Soldier", 92, Rarity.COMMON, mage.cards.d.DwarvenSoldier.class));
+ cards.add(new SetCardInfo("Eater of the Dead", 67, Rarity.UNCOMMON, mage.cards.e.EaterOfTheDead.class));
+ cards.add(new SetCardInfo("Elder Land Wurm", 11, Rarity.UNCOMMON, mage.cards.e.ElderLandWurm.class));
+ cards.add(new SetCardInfo("Erg Raiders", 68, Rarity.COMMON, mage.cards.e.ErgRaiders.class));
+ cards.add(new SetCardInfo("Eureka", 117, Rarity.RARE, mage.cards.e.Eureka.class));
+ cards.add(new SetCardInfo("Exile", 12, Rarity.COMMON, mage.cards.e.Exile.class));
+ cards.add(new SetCardInfo("The Fallen", 69, Rarity.UNCOMMON, mage.cards.t.TheFallen.class));
+ cards.add(new SetCardInfo("Feast or Famine", 70, Rarity.COMMON, mage.cards.f.FeastOrFamine.class));
+ cards.add(new SetCardInfo("Fire Covenant", 145, Rarity.UNCOMMON, mage.cards.f.FireCovenant.class));
+ cards.add(new SetCardInfo("Fissure", 93, Rarity.COMMON, mage.cards.f.Fissure.class));
+ cards.add(new SetCardInfo("Forcefield", 157, Rarity.RARE, mage.cards.f.Forcefield.class));
+ cards.add(new SetCardInfo("Force of Will", 33, Rarity.RARE, mage.cards.f.ForceOfWill.class));
+ cards.add(new SetCardInfo("Forest", 193, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Forest", 194, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Forest", 195, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Fyndhorn Elves", 118, Rarity.COMMON, mage.cards.f.FyndhornElves.class));
+ cards.add(new SetCardInfo("Ghazban Ogre", 120, Rarity.COMMON, mage.cards.g.GhazbanOgre.class));
+ cards.add(new SetCardInfo("Giant Tortoise", 34, Rarity.COMMON, mage.cards.g.GiantTortoise.class));
+ cards.add(new SetCardInfo("Goblin Chirurgeon", 94, Rarity.COMMON, mage.cards.g.GoblinChirurgeon.class));
+ cards.add(new SetCardInfo("Goblin Grenade", 95, Rarity.UNCOMMON, mage.cards.g.GoblinGrenade.class));
+ cards.add(new SetCardInfo("Goblin Mutant", 96, Rarity.UNCOMMON, mage.cards.g.GoblinMutant.class));
+ cards.add(new SetCardInfo("Goblins of the Flarg", 98, Rarity.COMMON, mage.cards.g.GoblinsOfTheFlarg.class));
+ cards.add(new SetCardInfo("Goblin Wizard", 97, Rarity.RARE, mage.cards.g.GoblinWizard.class));
+ cards.add(new SetCardInfo("Granite Gargoyle", 99, Rarity.UNCOMMON, mage.cards.g.GraniteGargoyle.class));
+ cards.add(new SetCardInfo("Greater Realm of Preservation", 13, Rarity.UNCOMMON, mage.cards.g.GreaterRealmOfPreservation.class));
+ cards.add(new SetCardInfo("Hallowed Ground", 14, Rarity.UNCOMMON, mage.cards.h.HallowedGround.class));
+ cards.add(new SetCardInfo("Hand of Justice", 15, Rarity.RARE, mage.cards.h.HandOfJustice.class));
+ cards.add(new SetCardInfo("Hecatomb", 71, Rarity.RARE, mage.cards.h.Hecatomb.class));
+ cards.add(new SetCardInfo("High Tide", 35, Rarity.UNCOMMON, mage.cards.h.HighTide.class));
+ cards.add(new SetCardInfo("Holy Light", 16, Rarity.COMMON, mage.cards.h.HolyLight.class));
+ cards.add(new SetCardInfo("Homarid Spawning Bed", 36, Rarity.UNCOMMON, mage.cards.h.HomaridSpawningBed.class));
+ cards.add(new SetCardInfo("Hungry Mist", 121, Rarity.COMMON, mage.cards.h.HungryMist.class));
+ cards.add(new SetCardInfo("Hyalopterous Lemure", 72, Rarity.COMMON, mage.cards.h.HyalopterousLemure.class));
+ cards.add(new SetCardInfo("Hydroblast", 37, Rarity.COMMON, mage.cards.h.Hydroblast.class));
+ cards.add(new SetCardInfo("Hymn of Rebirth", 146, Rarity.UNCOMMON, mage.cards.h.HymnOfRebirth.class));
+ cards.add(new SetCardInfo("Hymn to Tourach", 73, Rarity.UNCOMMON, mage.cards.h.HymnToTourach.class));
+ cards.add(new SetCardInfo("Icatian Lieutenant", 17, Rarity.COMMON, mage.cards.i.IcatianLieutenant.class));
+ cards.add(new SetCardInfo("Icatian Town", 18, Rarity.UNCOMMON, mage.cards.i.IcatianTown.class));
+ cards.add(new SetCardInfo("Ice Storm", 122, Rarity.UNCOMMON, mage.cards.i.IceStorm.class));
+ cards.add(new SetCardInfo("Ifh-Biff Efreet", 123, Rarity.RARE, mage.cards.i.IfhBiffEfreet.class));
+ cards.add(new SetCardInfo("Illusionary Forces", 38, Rarity.UNCOMMON, mage.cards.i.IllusionaryForces.class));
+ cards.add(new SetCardInfo("Illusionary Wall", 39, Rarity.COMMON, mage.cards.i.IllusionaryWall.class));
+ cards.add(new SetCardInfo("Illusions of Grandeur", 40, Rarity.RARE, mage.cards.i.IllusionsOfGrandeur.class));
+ cards.add(new SetCardInfo("Island", 184, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Island", 185, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Island", 186, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Island of Wak-Wak", 176, Rarity.RARE, mage.cards.i.IslandOfWakWak.class));
+ cards.add(new SetCardInfo("Ivory Tower", 158, Rarity.RARE, mage.cards.i.IvoryTower.class));
+ cards.add(new SetCardInfo("Jacques le Vert", 147, Rarity.RARE, mage.cards.j.JacquesLeVert.class));
+ cards.add(new SetCardInfo("Jokulhaups", 100, Rarity.RARE, mage.cards.j.Jokulhaups.class));
+ cards.add(new SetCardInfo("Juxtapose", 41, Rarity.UNCOMMON, mage.cards.j.Juxtapose.class));
+ cards.add(new SetCardInfo("Juzam Djinn", 74, Rarity.RARE, mage.cards.j.JuzamDjinn.class));
+ cards.add(new SetCardInfo("Keldon Warlord", 101, Rarity.UNCOMMON, mage.cards.k.KeldonWarlord.class));
+ cards.add(new SetCardInfo("Khabal Ghoul", 75, Rarity.RARE, mage.cards.k.KhabalGhoul.class));
+ cards.add(new SetCardInfo("Knights of Thorn", 19, Rarity.COMMON, mage.cards.k.KnightsOfThorn.class));
+ cards.add(new SetCardInfo("Lake of the Dead", 177, Rarity.RARE, mage.cards.l.LakeOfTheDead.class));
+ cards.add(new SetCardInfo("Lightning Bolt", 102, Rarity.COMMON, mage.cards.l.LightningBolt.class));
+ cards.add(new SetCardInfo("Lim-Dul's Vault", 148, Rarity.UNCOMMON, mage.cards.l.LimDulsVault.class));
+ cards.add(new SetCardInfo("Lord of Tresserhorn", 149, Rarity.RARE, mage.cards.l.LordOfTresserhorn.class));
+ cards.add(new SetCardInfo("Mana Flare", 103, Rarity.RARE, mage.cards.m.ManaFlare.class));
+ cards.add(new SetCardInfo("Marton Stromgald", 104, Rarity.RARE, mage.cards.m.MartonStromgald.class));
+ cards.add(new SetCardInfo("Mesa Pegasus", 20, Rarity.COMMON, mage.cards.m.MesaPegasus.class));
+ cards.add(new SetCardInfo("Mindstab Thrull", 76, Rarity.COMMON, mage.cards.m.MindstabThrull.class));
+ cards.add(new SetCardInfo("Mirror Universe", 159, Rarity.RARE, mage.cards.m.MirrorUniverse.class));
+ cards.add(new SetCardInfo("Mishra's Factory", 178, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class));
+ cards.add(new SetCardInfo("Moat", 21, Rarity.RARE, mage.cards.m.Moat.class));
+ cards.add(new SetCardInfo("Mountain", 190, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Mountain", 191, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Mountain", 192, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Mountain Yeti", 105, Rarity.COMMON, mage.cards.m.MountainYeti.class));
+ cards.add(new SetCardInfo("Mystic Remora", 42, Rarity.UNCOMMON, mage.cards.m.MysticRemora.class));
+ cards.add(new SetCardInfo("Nature's Lore", 124, Rarity.COMMON, mage.cards.n.NaturesLore.class));
+ cards.add(new SetCardInfo("Nether Shadow", 77, Rarity.UNCOMMON, mage.cards.n.NetherShadow.class));
+ cards.add(new SetCardInfo("Nevinyrral's Disk", 160, Rarity.RARE, mage.cards.n.NevinyrralsDisk.class));
+ cards.add(new SetCardInfo("Onulet", 161, Rarity.COMMON, mage.cards.o.Onulet.class));
+ cards.add(new SetCardInfo("Orcish Mechanics", 106, Rarity.UNCOMMON, mage.cards.o.OrcishMechanics.class));
+ cards.add(new SetCardInfo("Order of Leitbur", 22, Rarity.COMMON, mage.cards.o.OrderOfLeitbur.class));
+ cards.add(new SetCardInfo("Order of the Ebon Hand", 78, Rarity.COMMON, mage.cards.o.OrderOfTheEbonHand.class));
+ cards.add(new SetCardInfo("Oubliette", 79, Rarity.COMMON, mage.cards.o.Oubliette.class));
+ cards.add(new SetCardInfo("Paralyze", 80, Rarity.COMMON, mage.cards.p.Paralyze.class));
+ cards.add(new SetCardInfo("Petra Sphinx", 23, Rarity.RARE, mage.cards.p.PetraSphinx.class));
+ cards.add(new SetCardInfo("Phantom Monster", 43, Rarity.COMMON, mage.cards.p.PhantomMonster.class));
+ cards.add(new SetCardInfo("Phelddagrif", 150, Rarity.RARE, mage.cards.p.Phelddagrif.class));
+ cards.add(new SetCardInfo("Phyrexian Boon", 81, Rarity.COMMON, mage.cards.p.PhyrexianBoon.class));
+ cards.add(new SetCardInfo("Phyrexian War Beast", 162, Rarity.UNCOMMON, mage.cards.p.PhyrexianWarBeast.class));
+ cards.add(new SetCardInfo("Plains", 181, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Plains", 182, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Plains", 183, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Polar Kraken", 44, Rarity.RARE, mage.cards.p.PolarKraken.class));
+ cards.add(new SetCardInfo("Pox", 82, Rarity.RARE, mage.cards.p.Pox.class));
+ cards.add(new SetCardInfo("Preacher", 24, Rarity.RARE, mage.cards.p.Preacher.class));
+ cards.add(new SetCardInfo("Primal Order", 125, Rarity.RARE, mage.cards.p.PrimalOrder.class));
+ cards.add(new SetCardInfo("Psychic Purge", 45, Rarity.UNCOMMON, mage.cards.p.PsychicPurge.class));
+ cards.add(new SetCardInfo("Psychic Venom", 46, Rarity.COMMON, mage.cards.p.PsychicVenom.class));
+ cards.add(new SetCardInfo("Pyroblast", 107, Rarity.COMMON, mage.cards.p.Pyroblast.class));
+ cards.add(new SetCardInfo("Rabid Wombat", 126, Rarity.UNCOMMON, mage.cards.r.RabidWombat.class));
+ cards.add(new SetCardInfo("Rainbow Vale", 179, Rarity.RARE, mage.cards.r.RainbowVale.class));
+ cards.add(new SetCardInfo("Righteous Avengers", 25, Rarity.COMMON, mage.cards.r.RighteousAvengers.class));
+ cards.add(new SetCardInfo("Ring of Ma'ruf", 163, Rarity.RARE, mage.cards.r.RingOfMaruf.class));
+ cards.add(new SetCardInfo("River Merfolk", 47, Rarity.COMMON, mage.cards.r.RiverMerfolk.class));
+ cards.add(new SetCardInfo("Roots", 127, Rarity.COMMON, mage.cards.r.Roots.class));
+ cards.add(new SetCardInfo("Scryb Sprites", 128, Rarity.COMMON, mage.cards.s.ScrybSprites.class));
+ cards.add(new SetCardInfo("Seasinger", 49, Rarity.UNCOMMON, mage.cards.s.Seasinger.class));
+ cards.add(new SetCardInfo("Sea Sprite", 48, Rarity.COMMON, mage.cards.s.SeaSprite.class));
+ cards.add(new SetCardInfo("Seraph", 26, Rarity.RARE, mage.cards.s.Seraph.class));
+ cards.add(new SetCardInfo("Serendib Efreet", 50, Rarity.RARE, mage.cards.s.SerendibEfreet.class));
+ cards.add(new SetCardInfo("Serpent Generator", 164, Rarity.RARE, mage.cards.s.SerpentGenerator.class));
+ cards.add(new SetCardInfo("Shambling Strider", 129, Rarity.COMMON, mage.cards.s.ShamblingStrider.class));
+ cards.add(new SetCardInfo("Shield of the Ages", 165, Rarity.UNCOMMON, mage.cards.s.ShieldOfTheAges.class));
+ cards.add(new SetCardInfo("Shield Sphere", 166, Rarity.COMMON, mage.cards.s.ShieldSphere.class));
+ cards.add(new SetCardInfo("Singing Tree", 130, Rarity.UNCOMMON, mage.cards.s.SingingTree.class));
+ cards.add(new SetCardInfo("Spectral Bears", 131, Rarity.UNCOMMON, mage.cards.s.SpectralBears.class));
+ cards.add(new SetCardInfo("Spinal Villain", 108, Rarity.UNCOMMON, mage.cards.s.SpinalVillain.class));
+ cards.add(new SetCardInfo("Stone Calendar", 167, Rarity.UNCOMMON, mage.cards.s.StoneCalendar.class));
+ cards.add(new SetCardInfo("Stone Giant", 109, Rarity.UNCOMMON, mage.cards.s.StoneGiant.class));
+ cards.add(new SetCardInfo("Storm Seeker", 132, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class));
+ cards.add(new SetCardInfo("Su-Chi", 168, Rarity.RARE, mage.cards.s.SuChi.class));
+ cards.add(new SetCardInfo("Sunken City", 51, Rarity.UNCOMMON, mage.cards.s.SunkenCity.class));
+ cards.add(new SetCardInfo("Swamp", 187, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Swamp", 188, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Swamp", 189, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
+ cards.add(new SetCardInfo("Sylvan Library", 133, Rarity.RARE, mage.cards.s.SylvanLibrary.class));
+ cards.add(new SetCardInfo("Tawnos's Coffin", 169, Rarity.RARE, mage.cards.t.TawnossCoffin.class));
+ cards.add(new SetCardInfo("Telekinesis", 52, Rarity.COMMON, mage.cards.t.Telekinesis.class));
+ cards.add(new SetCardInfo("Thawing Glaciers", 180, Rarity.RARE, mage.cards.t.ThawingGlaciers.class));
+ cards.add(new SetCardInfo("Thicket Basilisk", 134, Rarity.UNCOMMON, mage.cards.t.ThicketBasilisk.class));
+ cards.add(new SetCardInfo("Thorn Thallid", 135, Rarity.COMMON, mage.cards.t.ThornThallid.class));
+ cards.add(new SetCardInfo("Thrull Champion", 83, Rarity.RARE, mage.cards.t.ThrullChampion.class));
+ cards.add(new SetCardInfo("Thrull Retainer", 84, Rarity.COMMON, mage.cards.t.ThrullRetainer.class));
+ cards.add(new SetCardInfo("Thunder Spirit", 27, Rarity.UNCOMMON, mage.cards.t.ThunderSpirit.class));
+ cards.add(new SetCardInfo("Time Elemental", 53, Rarity.RARE, mage.cards.t.TimeElemental.class));
+ cards.add(new SetCardInfo("Tivadar's Crusade", 28, Rarity.UNCOMMON, mage.cards.t.TivadarsCrusade.class));
+ cards.add(new SetCardInfo("Tornado", 136, Rarity.RARE, mage.cards.t.Tornado.class));
+ cards.add(new SetCardInfo("Urza's Bauble", 170, Rarity.UNCOMMON, mage.cards.u.UrzasBauble.class));
+ cards.add(new SetCardInfo("Urza's Chalice", 171, Rarity.COMMON, mage.cards.u.UrzasChalice.class));
+ cards.add(new SetCardInfo("Varchild's War-Riders", 110, Rarity.RARE, mage.cards.v.VarchildsWarRiders.class));
+ cards.add(new SetCardInfo("Vesuvan Doppelganger", 54, Rarity.RARE, mage.cards.v.VesuvanDoppelganger.class));
+ cards.add(new SetCardInfo("Vodalian Knights", 55, Rarity.UNCOMMON, mage.cards.v.VodalianKnights.class));
+ cards.add(new SetCardInfo("Walking Wall", 172, Rarity.UNCOMMON, mage.cards.w.WalkingWall.class));
+ cards.add(new SetCardInfo("Wanderlust", 137, Rarity.COMMON, mage.cards.w.Wanderlust.class));
+ cards.add(new SetCardInfo("Winds of Change", 111, Rarity.UNCOMMON, mage.cards.w.WindsOfChange.class));
+ cards.add(new SetCardInfo("Winter Blast", 138, Rarity.UNCOMMON, mage.cards.w.WinterBlast.class));
+ cards.add(new SetCardInfo("Winter Orb", 173, Rarity.RARE, mage.cards.w.WinterOrb.class));
+ cards.add(new SetCardInfo("Word of Undoing", 56, Rarity.COMMON, mage.cards.w.WordOfUndoing.class));
+ cards.add(new SetCardInfo("Wyluli Wolf", 139, Rarity.COMMON, mage.cards.w.WyluliWolf.class));
+ cards.add(new SetCardInfo("Yavimaya Ants", 140, Rarity.UNCOMMON, mage.cards.y.YavimayaAnts.class));
+ cards.add(new SetCardInfo("Ydwen Efreet", 112, Rarity.RARE, mage.cards.y.YdwenEfreet.class));
+ cards.add(new SetCardInfo("Zuran Orb", 174, Rarity.UNCOMMON, mage.cards.z.ZuranOrb.class));
+ }
}
\ No newline at end of file
diff --git a/Mage.Sets/src/mage/sets/MastersEditionII.java b/Mage.Sets/src/mage/sets/MastersEditionII.java
index 891cfdbd1f0..706fd806055 100644
--- a/Mage.Sets/src/mage/sets/MastersEditionII.java
+++ b/Mage.Sets/src/mage/sets/MastersEditionII.java
@@ -249,6 +249,7 @@ public final class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Warning", 38, Rarity.COMMON, mage.cards.w.Warning.class));
cards.add(new SetCardInfo("Whirling Catapult", 224, Rarity.UNCOMMON, mage.cards.w.WhirlingCatapult.class));
cards.add(new SetCardInfo("Whiteout", 185, Rarity.COMMON, mage.cards.w.Whiteout.class));
+ cards.add(new SetCardInfo("Wiitigo", 186, Rarity.RARE, mage.cards.w.Wiitigo.class));
cards.add(new SetCardInfo("Wind Spirit", 75, Rarity.UNCOMMON, mage.cards.w.WindSpirit.class));
cards.add(new SetCardInfo("Wings of Aesthir", 199, Rarity.UNCOMMON, mage.cards.w.WingsOfAesthir.class));
cards.add(new SetCardInfo("Winter's Night", 200, Rarity.RARE, mage.cards.w.WintersNight.class));
diff --git a/Mage.Stats/pom.xml b/Mage.Stats/pom.xml
index 627a28c8368..ae93dd043b6 100644
--- a/Mage.Stats/pom.xml
+++ b/Mage.Stats/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage-stats
diff --git a/Mage.Tests/pom.xml b/Mage.Tests/pom.xml
index 210ea3d16e4..06830c290ef 100644
--- a/Mage.Tests/pom.xml
+++ b/Mage.Tests/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage-tests
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/abilitywords/RevoltTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/abilitywords/RevoltTest.java
index b5e1ca8afd4..c25d6cad2d8 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/abilitywords/RevoltTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/abilitywords/RevoltTest.java
@@ -1,56 +1,56 @@
-
-package org.mage.test.cards.abilities.abilitywords;
-
-import mage.constants.PhaseStep;
-import mage.constants.Zone;
-import org.junit.Test;
-import org.mage.test.serverside.base.CardTestPlayerBase;
-
-/**
- *
- * @author LevelX2
- */
-public class RevoltTest extends CardTestPlayerBase {
-
- /**
- * In a duel commander match, I played a turn 1 Narnam Renegade off a basic
- * forest, and it entered the battlefield with a +1/+1 counter (it shouldn't
- * have).
- */
- @Test
- public void testFalseCondition() {
- // Deathtouch
- // Revolt — Narnam Renegade enters the battlefield with a +1/+1 counter on it if a permanent you controlled left this battlefield this turn.
- addCard(Zone.HAND, playerA, "Narnam Renegade", 1); // Creature 1/2 {G}
- addCard(Zone.HAND, playerA, "Forest", 1);
-
- playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Narnam Renegade");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertPowerToughness(playerA, "Narnam Renegade", 1, 2);
- }
-
- @Test
- public void testTrueCondition() {
- // Deathtouch
- // Revolt — Narnam Renegade enters the battlefield with a +1/+1 counter on it if a permanent you controlled left this battlefield this turn.
- addCard(Zone.HAND, playerA, "Narnam Renegade", 1); // Creature 1/2 {G}
- // {T}, Sacrifice Terramorphic Expanse: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library.
- addCard(Zone.BATTLEFIELD, playerA, "Terramorphic Expanse", 1);
- addCard(Zone.HAND, playerA, "Forest", 1);
-
- playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
- activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice");
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Narnam Renegade");
-
- setStopAt(1, PhaseStep.BEGIN_COMBAT);
- execute();
-
- assertGraveyardCount(playerA, "Terramorphic Expanse", 1);
- assertPowerToughness(playerA, "Narnam Renegade", 2, 3);
- }
-
-}
+
+package org.mage.test.cards.abilities.abilitywords;
+
+import mage.constants.PhaseStep;
+import mage.constants.Zone;
+import org.junit.Test;
+import org.mage.test.serverside.base.CardTestPlayerBase;
+
+/**
+ *
+ * @author LevelX2
+ */
+public class RevoltTest extends CardTestPlayerBase {
+
+ /**
+ * In a duel commander match, I played a turn 1 Narnam Renegade off a basic
+ * forest, and it entered the battlefield with a +1/+1 counter (it shouldn't
+ * have).
+ */
+ @Test
+ public void testFalseCondition() {
+ // Deathtouch
+ // Revolt — Narnam Renegade enters the battlefield with a +1/+1 counter on it if a permanent you controlled left this battlefield this turn.
+ addCard(Zone.HAND, playerA, "Narnam Renegade", 1); // Creature 1/2 {G}
+ addCard(Zone.HAND, playerA, "Forest", 1);
+
+ playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
+ castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Narnam Renegade");
+
+ setStopAt(1, PhaseStep.BEGIN_COMBAT);
+ execute();
+
+ assertPowerToughness(playerA, "Narnam Renegade", 1, 2);
+ }
+
+ @Test
+ public void testTrueCondition() {
+ // Deathtouch
+ // Revolt — Narnam Renegade enters the battlefield with a +1/+1 counter on it if a permanent you controlled left this battlefield this turn.
+ addCard(Zone.HAND, playerA, "Narnam Renegade", 1); // Creature 1/2 {G}
+ // {T}, Sacrifice Terramorphic Expanse: Search your library for a basic land card and put it onto the battlefield tapped. Then shuffle your library.
+ addCard(Zone.BATTLEFIELD, playerA, "Terramorphic Expanse", 1);
+ addCard(Zone.HAND, playerA, "Forest", 1);
+
+ playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest");
+ activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}, Sacrifice");
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Narnam Renegade");
+
+ setStopAt(1, PhaseStep.END_TURN);
+ execute();
+
+ assertGraveyardCount(playerA, "Terramorphic Expanse", 1);
+ assertPowerToughness(playerA, "Narnam Renegade", 2, 3);
+ }
+
+}
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/curses/CursesTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/curses/CursesTest.java
index 6d7715abb6d..fd43fd20614 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/curses/CursesTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/curses/CursesTest.java
@@ -196,7 +196,7 @@ public class CursesTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Curse of Bloodletting");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Bloodletting", playerB);
- castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Thirst", playerB);
+ castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Curse of Thirst", playerB);
setStopAt(2, PhaseStep.DRAW);
execute();
@@ -284,9 +284,9 @@ public class CursesTest extends CardTestPlayerBase {
// {2}{G/U}{G/U}: Put the top two cards of your library into your graveyard, then return a nonland card of an opponent's choice from your graveyard to your hand.
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{2}{G/U}{G/U}: Put the top two cards");
- castSpell(3, PhaseStep.PRECOMBAT_MAIN, playerA, "Curse of Death's Hold", playerB);
+ castSpell(3, PhaseStep.POSTCOMBAT_MAIN, playerA, "Curse of Death's Hold", playerB);
- setStopAt(3, PhaseStep.END_COMBAT);
+ setStopAt(3, PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/BloodMoonTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/BloodMoonTest.java
index 9fa648f4387..c7c39c5f608 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/BloodMoonTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/enters/BloodMoonTest.java
@@ -192,9 +192,9 @@ public class BloodMoonTest extends CardTestPlayerBase {
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Pithing Needle");
setChoice(playerB, "Blood Moon");
- playLand(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Ghost Quarter");
+ playLand(2, PhaseStep.POSTCOMBAT_MAIN, playerB, "Ghost Quarter");
- setStopAt(2, PhaseStep.BEGIN_COMBAT);
+ setStopAt(2, PhaseStep.END_TURN);
execute();
assertPermanentCount(playerA, "Blood Moon", 1);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RiotTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RiotTest.java
index 9503cd53886..41b7b56991e 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RiotTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/abilities/keywords/RiotTest.java
@@ -31,11 +31,12 @@ public class RiotTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Rampaging Rendhorn", 1); // Creature {4}{G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rampaging Rendhorn");
- setChoice(playerA, "Yes");
+ setChoice(playerA, "Yes"); // yes - counter
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
+ assertAllCommandsUsed();
assertPermanentCount(playerA, "Rampaging Rendhorn", 1);
assertPowerToughness(playerA, "Rampaging Rendhorn", 5, 5);
@@ -51,11 +52,12 @@ public class RiotTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Rampaging Rendhorn", 1); // Creature {4}{G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Rampaging Rendhorn");
- setChoice(playerA, "No");
+ setChoice(playerA, "No"); // no - haste
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
+ assertAllCommandsUsed();
assertPermanentCount(playerA, "Rampaging Rendhorn", 1);
assertPowerToughness(playerA, "Rampaging Rendhorn", 4, 4);
@@ -74,11 +76,12 @@ public class RiotTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1); // Creature {1}{W} 2/2
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
- setChoice(playerA, "Yes");
+ setChoice(playerA, "Yes"); // yes - counter
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
+ assertAllCommandsUsed();
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPowerToughness(playerA, "Silvercoat Lion", 3, 3);
@@ -98,11 +101,12 @@ public class RiotTest extends CardTestPlayerBase {
addCard(Zone.HAND, playerA, "Silvercoat Lion", 1); // Creature {1}{W} 2/2
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Silvercoat Lion");
- setChoice(playerA, "No");
+ setChoice(playerA, "No"); // no - haste
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
+ assertAllCommandsUsed();
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPowerToughness(playerA, "Silvercoat Lion", 2, 2);
diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/control/DackFaydenTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/control/DackFaydenTest.java
index ec07d310585..643b869a3a8 100644
--- a/Mage.Tests/src/test/java/org/mage/test/cards/control/DackFaydenTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/cards/control/DackFaydenTest.java
@@ -59,7 +59,7 @@ public class DackFaydenTest extends CardTestPlayerBase {
castSpell(10, PhaseStep.PRECOMBAT_MAIN, playerA, "Gut Shot", "Ornithopter");
castSpell(10, PhaseStep.PRECOMBAT_MAIN, playerA, "Unsummon", "Ornithopter", "Gut Shot", StackClause.WHILE_NOT_ON_STACK);
- castSpell(10, PhaseStep.PRECOMBAT_MAIN, playerB, "Ornithopter");
+ castSpell(10, PhaseStep.POSTCOMBAT_MAIN, playerB, "Ornithopter");
setStopAt(10, PhaseStep.END_TURN);
execute();
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
index bf78aae676a..80c72166753 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
@@ -800,7 +800,7 @@ public class TestPlayer implements Player {
}
private void printCards(Set cards) {
- printCards(cards.stream().collect(Collectors.toList()));
+ printCards(new ArrayList<>(cards));
}
private void printCards(List cards) {
@@ -2609,13 +2609,13 @@ public class TestPlayer implements Player {
}
@Override
- public boolean flipCoin(Game game) {
- return computerPlayer.flipCoin(game);
+ public boolean flipCoin(Ability source, Game game, boolean winnable) {
+ return computerPlayer.flipCoin(source, game, true);
}
@Override
- public boolean flipCoin(Game game, ArrayList appliedEffects) {
- return computerPlayer.flipCoin(game, appliedEffects);
+ public boolean flipCoin(Ability source, Game game, boolean winnable, ArrayList appliedEffects) {
+ return computerPlayer.flipCoin(source, game, true, appliedEffects);
}
@Override
diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java
index 502be627e4c..384d89c21f1 100644
--- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java
+++ b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java
@@ -642,12 +642,12 @@ public class PlayerStub implements Player {
}
@Override
- public boolean flipCoin(Game game) {
+ public boolean flipCoin(Ability source, Game game, boolean winnable) {
return false;
}
@Override
- public boolean flipCoin(Game game, ArrayList appliedEffects) {
+ public boolean flipCoin(Ability source, Game game, boolean winnable, ArrayList appliedEffects) {
return false;
}
diff --git a/Mage.Updater/pom.xml b/Mage.Updater/pom.xml
index 183b4f90e1e..f4d46c76553 100644
--- a/Mage.Updater/pom.xml
+++ b/Mage.Updater/pom.xml
@@ -5,7 +5,7 @@
mage-root
org.mage
- 1.4.32
+ 1.4.33
4.0.0
diff --git a/Mage.Updater/src/main/java/com/magefree/update/helpers/FileHelper.java b/Mage.Updater/src/main/java/com/magefree/update/helpers/FileHelper.java
index d23c0bdf4c5..6ca8233d86d 100644
--- a/Mage.Updater/src/main/java/com/magefree/update/helpers/FileHelper.java
+++ b/Mage.Updater/src/main/java/com/magefree/update/helpers/FileHelper.java
@@ -68,8 +68,9 @@ public final class FileHelper {
for (String filename : files) {
File f = new File(filename);
if (f.exists()) {
- f.delete();
- System.out.println("File has been deleted: " + filename);
+ if(f.delete()) {
+ System.out.println("File has been deleted: " + filename);
+ }
} else {
System.out.println("ERROR. Couldn't find file to delete: " + filename);
}
@@ -84,17 +85,14 @@ public final class FileHelper {
*/
public static void downloadFile(String filename, HttpURLConnection urlConnection) {
System.out.println("Downloading " + filename);
- InputStream in = null;
- FileOutputStream out = null;
- try {
- in = urlConnection.getInputStream();
+ try (InputStream in = urlConnection.getInputStream() ; FileOutputStream out = new FileOutputStream(filename)){
File f = new File(filename);
if (!f.exists() && f.getParentFile() != null) {
- f.getParentFile().mkdirs();
- System.out.println("Directories have been created: " + f.getParentFile().getPath());
+ if(f.getParentFile().mkdirs()) {
+ System.out.println("Directories have been created: " + f.getParentFile().getPath());
+ }
}
- out = new FileOutputStream(filename);
byte[] buf = new byte[4 * 1024];
int bytesRead;
@@ -105,19 +103,6 @@ public final class FileHelper {
System.out.println("File has been updated: " + filename);
} catch (IOException e) {
System.out.println("i/o exception - " + e.getMessage());
- } finally {
- closeQuietly(in);
- closeQuietly(out);
- }
- }
-
- public static void closeQuietly(Closeable s) {
- if(s != null) {
- try {
- s.close();
- } catch (Exception e) {
- System.out.println("i/o exception - " + e.getMessage());
- }
}
}
}
diff --git a/Mage.Verify/pom.xml b/Mage.Verify/pom.xml
index 7f58ec4e885..d4f35af8f7c 100644
--- a/Mage.Verify/pom.xml
+++ b/Mage.Verify/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage-verify
@@ -49,7 +49,7 @@
org.mage
mage-client
- 1.4.32
+ 1.4.33
diff --git a/Mage.Verify/src/main/java/mage/verify/JsonCard.java b/Mage.Verify/src/main/java/mage/verify/JsonCard.java
index d01d9c8ba02..bb85a00e7d2 100644
--- a/Mage.Verify/src/main/java/mage/verify/JsonCard.java
+++ b/Mage.Verify/src/main/java/mage/verify/JsonCard.java
@@ -1,7 +1,12 @@
package mage.verify;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
import java.util.List;
+import static mage.verify.MtgJson.MTGJSON_IGNORE_NEW_PROPERTIES;
+
+@JsonIgnoreProperties(ignoreUnknown = MTGJSON_IGNORE_NEW_PROPERTIES)
class JsonCard {
// docs: https://mtgjson.com/v4/docs.html
diff --git a/Mage.Verify/src/main/java/mage/verify/JsonForeignData.java b/Mage.Verify/src/main/java/mage/verify/JsonForeignData.java
index c6ca9353e46..5c85acd664a 100644
--- a/Mage.Verify/src/main/java/mage/verify/JsonForeignData.java
+++ b/Mage.Verify/src/main/java/mage/verify/JsonForeignData.java
@@ -1,5 +1,10 @@
package mage.verify;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import static mage.verify.MtgJson.MTGJSON_IGNORE_NEW_PROPERTIES;
+
+@JsonIgnoreProperties(ignoreUnknown = MTGJSON_IGNORE_NEW_PROPERTIES)
public class JsonForeignData {
public String flavorText;
public String language;
diff --git a/Mage.Verify/src/main/java/mage/verify/JsonSet.java b/Mage.Verify/src/main/java/mage/verify/JsonSet.java
index 614d73123d2..d53d310d04f 100644
--- a/Mage.Verify/src/main/java/mage/verify/JsonSet.java
+++ b/Mage.Verify/src/main/java/mage/verify/JsonSet.java
@@ -1,7 +1,12 @@
package mage.verify;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
import java.util.List;
+import static mage.verify.MtgJson.MTGJSON_IGNORE_NEW_PROPERTIES;
+
+@JsonIgnoreProperties(ignoreUnknown = MTGJSON_IGNORE_NEW_PROPERTIES)
class JsonSet {
public int baseSetSize;
public String block;
diff --git a/Mage.Verify/src/main/java/mage/verify/JsonToken.java b/Mage.Verify/src/main/java/mage/verify/JsonToken.java
index 92237ae01f9..c3484856890 100644
--- a/Mage.Verify/src/main/java/mage/verify/JsonToken.java
+++ b/Mage.Verify/src/main/java/mage/verify/JsonToken.java
@@ -1,7 +1,12 @@
package mage.verify;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
import java.util.List;
+import static mage.verify.MtgJson.MTGJSON_IGNORE_NEW_PROPERTIES;
+
+@JsonIgnoreProperties(ignoreUnknown = MTGJSON_IGNORE_NEW_PROPERTIES)
public class JsonToken {
public String artist;
public String borderColor;
diff --git a/Mage.Verify/src/main/java/mage/verify/MtgJson.java b/Mage.Verify/src/main/java/mage/verify/MtgJson.java
index 11f147029a7..e6de2c378ec 100644
--- a/Mage.Verify/src/main/java/mage/verify/MtgJson.java
+++ b/Mage.Verify/src/main/java/mage/verify/MtgJson.java
@@ -2,7 +2,6 @@ package mage.verify;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
-import mage.util.StreamUtils;
import java.io.File;
import java.io.FileInputStream;
@@ -24,6 +23,8 @@ public final class MtgJson {
public static Map mtgJsonToXMageCodes = new HashMap<>();
public static Map xMageToMtgJsonCodes = new HashMap<>();
+ public static final boolean MTGJSON_IGNORE_NEW_PROPERTIES = true; // set it to false for full mtgjson checks and research (new fields finds or mtgjson updates)
+
static {
mtgJsonToXMageCodes.put("pWCQ", "WMCQ");
mtgJsonToXMageCodes.put("pSUS", "SUS");
@@ -131,14 +132,9 @@ public final class MtgJson {
}
stream = new FileInputStream(file);
}
- ZipInputStream zipInputStream = null;
- try {
- zipInputStream = new ZipInputStream(stream);
+ try (ZipInputStream zipInputStream = new ZipInputStream(stream)) {
zipInputStream.getNextEntry();
return new ObjectMapper().readValue(zipInputStream, ref);
- } finally {
- StreamUtils.closeQuietly(zipInputStream);
- StreamUtils.closeQuietly(stream);
}
}
diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
index 6dc4d002136..6dc375d3b27 100644
--- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
+++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java
@@ -4,6 +4,7 @@ import mage.ObjectColor;
import mage.abilities.keyword.MultikickerAbility;
import mage.cards.*;
import mage.cards.basiclands.BasicLand;
+import mage.cards.repository.*;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.SubType;
@@ -565,6 +566,7 @@ public class VerifyCardDataTest {
//checkNumbers(card, ref); // TODO: load data from allsets.json and check it (allcards.json do not have card numbers)
checkBasicLands(card, ref);
checkMissingAbilities(card, ref);
+ //checkWrongCosts(card, ref);
}
private void checkColors(Card card, JsonCard ref) {
@@ -656,6 +658,128 @@ public class VerifyCardDataTest {
}
}
+ private String prepareRule(String cardName, String rule) {
+ // remove and optimize rule text for analyze
+ String newRule = rule;
+
+ // remove reminder text
+ newRule = newRule.replaceAll("(?i)\\(.+\\)", "");
+
+ // replace special text and symbols
+ newRule = newRule
+ .replace("{this}", cardName)
+ .replace("—", "—");
+
+ // remove html marks
+ newRule = newRule
+ .replace("", "")
+ .replace("", "");
+
+ return newRule;
+ }
+
+ @Test
+ @Ignore
+ public void showCardInfo() throws Exception {
+ // debug only: show direct card info (takes it from class file, not from db repository)
+ String cardName = "Essence Capture";
+ CardScanner.scan();
+ CardSetInfo testSet = new CardSetInfo("test", "test", "123", Rarity.COMMON);
+ CardInfo cardInfo = CardRepository.instance.findCard(cardName);
+ Card card = CardImpl.createCard(cardInfo.getClassName(), testSet);
+ card.getRules().stream().forEach(System.out::println);
+ }
+
+ private void checkWrongCosts(Card card, JsonCard ref) {
+ // checks missing or wrong cost
+ if (!card.getExpansionSetCode().equals("RNA")) {
+ return;
+ }
+
+ String[] refRules = ref.text.split("[\\$\\\n]"); // ref card's abilities can be splited by \n or $ chars
+ for (int i = 0; i < refRules.length; i++) {
+ refRules[i] = prepareRule(card.getName(), refRules[i]);
+ }
+
+ String[] cardRules = card.getRules().toArray(new String[0]);
+ for (int i = 0; i < cardRules.length; i++) {
+ cardRules[i] = prepareRule(card.getName(), cardRules[i]);
+ }
+
+ for (String cardRule : cardRules) {
+ boolean isAbilityFounded = false;
+ boolean isCostOk = false;
+ for (String refRule : refRules) {
+ if (cardRule.equals(refRule)) {
+ isAbilityFounded = true;
+ isCostOk = true;
+ break;
+ }
+ }
+
+ if (!isCostOk) {
+ fail(card, "abilities", "card ability have cost, but can't find in ref [" + "xxx" + ": " + card.getRules() + "]");
+ }
+ }
+ }
+
+
+ /*
+ for(String rule : card.getRules()) {
+ rule = rule.replaceAll("(?i).+", ""); // Ignoring reminder text in italic
+ // TODO: add Equip {3} checks
+ // TODO: add Raid and other words checks
+ String[] sl = rule.split(":");
+ if (sl.length == 2 && !sl[0].isEmpty()) {
+ String cardCost = sl[0]
+ .replace("{this}", card.getName())
+ //.replace("", "")
+ //.replace("", "")
+ .replace("—", "—");
+ String cardAbility = sl[1]
+ .trim()
+ .replace("{this}", card.getName())
+ //.replace("", "")
+ //.replace("", "")
+ .replace("—", "—");;
+
+ boolean found = false;
+ for (String refRule : refRules) {
+ refRule = refRule.replaceAll("(?i).+", ""); // Ignoring reminder text in italic
+
+ // fix for ref mana: ref card have xxx instead {T}: Add {xxx}, example: W
+ if (refRule.length() == 1) {
+ refRule = "{T}: Add {" + refRule + "}";
+ }
+ refRule = refRule
+ .trim()
+ //.replace("", "")
+ //.replace("", "")
+ .replace("—", "—");
+
+ // normal
+ if (refRule.startsWith(cardCost)) {
+ found = true;
+ break;
+ }
+
+ // ref card have (xxx) instead xxx, example: ({T}: Add {G}.)
+ // ref card have (xxx) instead xxx, example: ({T}: Add {G}.)
+ // TODO: delete?
+ if (refRule.startsWith("(" + cardCost)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ fail(card, "abilities", "card ability have cost, but can't find in ref [" + cardCost + ": " + cardAbility + "]");
+ }
+ }
+
+ }
+ }*/
+
+
private void checkTypes(Card card, JsonCard ref) {
if (skipListHaveName("TYPE", card.getExpansionSetCode(), card.getName())) {
return;
diff --git a/Mage/pom.xml b/Mage/pom.xml
index ecb37107e1a..981365c3eea 100644
--- a/Mage/pom.xml
+++ b/Mage/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
mage
diff --git a/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java
index 09bf317c733..f78e0f9d3e1 100644
--- a/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/GainLifeControllerTriggeredAbility.java
@@ -9,12 +9,11 @@ import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
/**
- *
* @author LevelX2
*/
public class GainLifeControllerTriggeredAbility extends TriggeredAbilityImpl {
- private boolean setTargetPointer;
+ private final boolean setTargetPointer;
public GainLifeControllerTriggeredAbility(Effect effect, boolean optional) {
this(effect, optional, false);
@@ -56,7 +55,6 @@ public class GainLifeControllerTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
- return new StringBuilder("Whenever you gain life, ").append(super.getRule()).toString();
+ return "Whenever you gain life, " + super.getRule();
}
-
}
diff --git a/Mage/src/main/java/mage/abilities/common/OneOrMoreCountersAddedTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/OneOrMoreCountersAddedTriggeredAbility.java
index 6619fcd8533..e00c6bf00da 100644
--- a/Mage/src/main/java/mage/abilities/common/OneOrMoreCountersAddedTriggeredAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/OneOrMoreCountersAddedTriggeredAbility.java
@@ -48,6 +48,6 @@ public class OneOrMoreCountersAddedTriggeredAbility extends TriggeredAbilityImpl
@Override
public String getRule() {
- return "Whenever one or more " + counterType + " counters are put on {this}, " + super.getRule();
+ return "Whenever one or more " + counterType.getName() + " counters are put on {this}, " + super.getRule();
}
}
diff --git a/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java
index 704ff18af23..f80b41a544a 100644
--- a/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java
+++ b/Mage/src/main/java/mage/abilities/common/WinsCoinFlipTriggeredAbility.java
@@ -5,10 +5,10 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.game.Game;
+import mage.game.events.CoinFlippedEvent;
import mage.game.events.GameEvent;
/**
- *
* @author TheElk801
*/
public class WinsCoinFlipTriggeredAbility extends TriggeredAbilityImpl {
@@ -33,7 +33,8 @@ public class WinsCoinFlipTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
- return event.getFlag();
+ CoinFlippedEvent flipEvent = (CoinFlippedEvent) event;
+ return flipEvent.isWinnable() && (flipEvent.getChosen() == flipEvent.getResult());
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/condition/common/AfterCombatCondition.java b/Mage/src/main/java/mage/abilities/condition/common/AfterCombatCondition.java
new file mode 100644
index 00000000000..76bdc4be626
--- /dev/null
+++ b/Mage/src/main/java/mage/abilities/condition/common/AfterCombatCondition.java
@@ -0,0 +1,25 @@
+
+package mage.abilities.condition.common;
+
+import mage.abilities.Ability;
+import mage.abilities.condition.Condition;
+import mage.constants.PhaseStep;
+import mage.game.Game;
+
+/**
+ * @author L_J
+ */
+public enum AfterCombatCondition implements Condition {
+
+ instance;
+ @Override
+
+ public boolean apply(Game game, Ability source) {
+ return game.getStep().getType().isAfter(PhaseStep.END_COMBAT);
+ }
+
+ @Override
+ public String toString() {
+ return "after combat";
+ }
+}
diff --git a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java
index 7f3a4b7abeb..9a5de3b0769 100644
--- a/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java
+++ b/Mage/src/main/java/mage/abilities/costs/common/SacrificeTargetCost.java
@@ -27,8 +27,14 @@ public class SacrificeTargetCost extends CostImpl {
this.addTarget(target);
target.setNotTarget(true); // sacrifice is never targeted
this.text = "sacrifice "
- + ((target.getNumberOfTargets() != 1 || (target.getTargetName().startsWith("an") || target.getTargetName().startsWith("a ")))
- ? (target.getMinNumberOfTargets() == target.getMaxNumberOfTargets() && target.getMinNumberOfTargets() > 1 ? CardUtil.numberToText(target.getNumberOfTargets()) : "" ) : (target.getTargetName().startsWith("artifact") ? "an " : "a ")) + target.getTargetName();
+ + ((target.getNumberOfTargets() != 1
+ || (target.getTargetName().startsWith("an")
+ || target.getTargetName().startsWith("a ")))
+ ? (target.getMinNumberOfTargets() == target.getMaxNumberOfTargets()
+ && target.getMinNumberOfTargets() > 1
+ ? CardUtil.numberToText(target.getNumberOfTargets()) + " " : "")
+ : (target.getTargetName().startsWith("artifact") ? "an " : "a "))
+ + target.getTargetName();
target.setTargetName(target.getTargetName() + " (to sacrifice)");
}
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttachedPermanentToughnessValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttachedPermanentToughnessValue.java
index 2dab3cdd799..43529161fe3 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttachedPermanentToughnessValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttachedPermanentToughnessValue.java
@@ -12,29 +12,29 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
/**
- *
* @author MTGfan
*/
-public class AttachedPermanentToughnessValue implements DynamicValue {
-
+public enum AttachedPermanentToughnessValue implements DynamicValue {
+ instance;
+
@Override
public int calculate(Game game, Ability source, Effect effect) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
Permanent enchanted = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo());
return enchanted.getToughness().getValue();
}
-
+
@Override
- public AttachedPermanentToughnessValue copy(){
- return new AttachedPermanentToughnessValue();
+ public AttachedPermanentToughnessValue copy() {
+ return AttachedPermanentToughnessValue.instance;
}
-
+
@Override
public String toString() {
return "equal to";
}
-
- @Override
+
+ @Override
public String getMessage() {
return "that creature's toughness";
}
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java
index 1e69de1d4f7..2435fda94a7 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/AttackedThisTurnOpponentsCount.java
@@ -7,29 +7,24 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
import mage.watchers.common.PlayersAttackedThisTurnWatcher;
-import java.util.UUID;
-
/**
* @author JayDi85
*/
-public class AttackedThisTurnOpponentsCount implements DynamicValue {
+public enum AttackedThisTurnOpponentsCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
- return this.calculate(game, sourceAbility.getControllerId());
- }
-
- public int calculate(Game game, UUID controllerId) {
PlayersAttackedThisTurnWatcher watcher = game.getState().getWatcher(PlayersAttackedThisTurnWatcher.class);
if (watcher != null) {
- return watcher.getAttackedOpponentsCount(controllerId);
+ return watcher.getAttackedOpponentsCount(sourceAbility.getControllerId());
}
return 0;
}
@Override
public AttackedThisTurnOpponentsCount copy() {
- return new AttackedThisTurnOpponentsCount();
+ return AttackedThisTurnOpponentsCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllHandsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllHandsCount.java
index 7220265e7bf..5910f57a6c9 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllHandsCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInAllHandsCount.java
@@ -1,26 +1,26 @@
package mage.abilities.dynamicvalue.common;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.game.Game;
import mage.players.Player;
+import java.util.UUID;
+
/**
- *
* @author emerald000
*/
-public class CardsInAllHandsCount implements DynamicValue {
-
+public enum CardsInAllHandsCount implements DynamicValue {
+ instance;
+
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int count = 0;
for (UUID playerId : game.getState().getPlayersInRange(sourceAbility.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
- if (player != null)
- {
+ if (player != null) {
count += player.getHand().size();
}
}
@@ -29,7 +29,7 @@ public class CardsInAllHandsCount implements DynamicValue {
@Override
public CardsInAllHandsCount copy() {
- return new CardsInAllHandsCount();
+ return CardsInAllHandsCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInControllerHandCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInControllerHandCount.java
index 476057003c4..ea8cde0572d 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInControllerHandCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInControllerHandCount.java
@@ -6,7 +6,8 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
import mage.players.Player;
-public class CardsInControllerHandCount implements DynamicValue {
+public enum CardsInControllerHandCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -21,7 +22,7 @@ public class CardsInControllerHandCount implements DynamicValue {
@Override
public CardsInControllerHandCount copy() {
- return new CardsInControllerHandCount();
+ return CardsInControllerHandCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetHandCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetHandCount.java
index dd7ac467d9d..c5e63adb19c 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetHandCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetHandCount.java
@@ -6,7 +6,8 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
import mage.players.Player;
-public class CardsInTargetHandCount implements DynamicValue {
+public enum CardsInTargetHandCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -21,7 +22,7 @@ public class CardsInTargetHandCount implements DynamicValue {
@Override
public DynamicValue copy() {
- return new CardsInTargetHandCount();
+ return CardsInTargetHandCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetPlayerHandCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetPlayerHandCount.java
index 393f45db14e..686f85b9596 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetPlayerHandCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CardsInTargetPlayerHandCount.java
@@ -7,10 +7,10 @@ import mage.game.Game;
import mage.players.Player;
/**
- *
* @author cbrianhill
*/
-public class CardsInTargetPlayerHandCount implements DynamicValue {
+public enum CardsInTargetPlayerHandCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -23,7 +23,7 @@ public class CardsInTargetPlayerHandCount implements DynamicValue {
@Override
public CardsInTargetPlayerHandCount copy() {
- return new CardsInTargetPlayerHandCount();
+ return CardsInTargetPlayerHandCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeCount.java
index e756e77e3e4..512691fd8fe 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ControllerLifeCount.java
@@ -6,7 +6,8 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
import mage.players.Player;
-public class ControllerLifeCount implements DynamicValue {
+public enum ControllerLifeCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -19,7 +20,7 @@ public class ControllerLifeCount implements DynamicValue {
@Override
public ControllerLifeCount copy() {
- return new ControllerLifeCount();
+ return ControllerLifeCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CreaturesDiedThisTurnCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CreaturesDiedThisTurnCount.java
index ef2ae61ed2d..d5b3fb0b137 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/CreaturesDiedThisTurnCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/CreaturesDiedThisTurnCount.java
@@ -10,7 +10,8 @@ import mage.watchers.common.CreaturesDiedWatcher;
/**
* @author LoneFox
*/
-public class CreaturesDiedThisTurnCount implements DynamicValue {
+public enum CreaturesDiedThisTurnCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -23,7 +24,7 @@ public class CreaturesDiedThisTurnCount implements DynamicValue {
@Override
public CreaturesDiedThisTurnCount copy() {
- return new CreaturesDiedThisTurnCount();
+ return CreaturesDiedThisTurnCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/DiscardCostCardConvertedMana.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/DiscardCostCardConvertedMana.java
index 145cf7ddafd..03e750bcc39 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/DiscardCostCardConvertedMana.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/DiscardCostCardConvertedMana.java
@@ -11,7 +11,8 @@ import mage.game.Game;
/**
* @author LevelX2
*/
-public class DiscardCostCardConvertedMana implements DynamicValue {
+public enum DiscardCostCardConvertedMana implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -26,7 +27,7 @@ public class DiscardCostCardConvertedMana implements DynamicValue {
@Override
public DiscardCostCardConvertedMana copy() {
- return new DiscardCostCardConvertedMana();
+ return DiscardCostCardConvertedMana.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ExileFromHandCostCardConvertedMana.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ExileFromHandCostCardConvertedMana.java
index f13c39c2824..48bba827662 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ExileFromHandCostCardConvertedMana.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ExileFromHandCostCardConvertedMana.java
@@ -14,10 +14,10 @@ import mage.game.Game;
* cost. If no card was exiled the getManaCostsToPay().getX() will be used as
* value.
*
- *
* @author LevelX2
*/
-public class ExileFromHandCostCardConvertedMana implements DynamicValue {
+public enum ExileFromHandCostCardConvertedMana implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -35,7 +35,7 @@ public class ExileFromHandCostCardConvertedMana implements DynamicValue {
@Override
public ExileFromHandCostCardConvertedMana copy() {
- return new ExileFromHandCostCardConvertedMana();
+ return ExileFromHandCostCardConvertedMana.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXValue.java
index 07c5eefe0f3..84a0302bb46 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GetXValue.java
@@ -8,14 +8,15 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
/**
- *
* @author BetaSteward_at_googlemail.com
*/
-public class GetXValue implements DynamicValue {
+public enum GetXValue implements DynamicValue {
+ instance;
+
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
int amount = 0;
- for (VariableCost cost: sourceAbility.getCosts().getVariableCosts()) {
+ for (VariableCost cost : sourceAbility.getCosts().getVariableCosts()) {
amount += cost.getAmount();
}
return amount;
@@ -23,7 +24,7 @@ public class GetXValue implements DynamicValue {
@Override
public GetXValue copy() {
- return new GetXValue();
+ return GetXValue.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestPowerAmongControlledCreaturesValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestPowerAmongControlledCreaturesValue.java
index a668e5c3375..714cc80a631 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestPowerAmongControlledCreaturesValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/GreatestPowerAmongControlledCreaturesValue.java
@@ -10,10 +10,10 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
/**
- *
* @author Styxo
*/
-public class GreatestPowerAmongControlledCreaturesValue implements DynamicValue {
+public enum GreatestPowerAmongControlledCreaturesValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -32,7 +32,7 @@ public class GreatestPowerAmongControlledCreaturesValue implements DynamicValue
@Override
public GreatestPowerAmongControlledCreaturesValue copy() {
- return new GreatestPowerAmongControlledCreaturesValue();
+ return GreatestPowerAmongControlledCreaturesValue.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaSpentToCastCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaSpentToCastCount.java
index 767c185e7a6..0ad7fed22b4 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaSpentToCastCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManaSpentToCastCount.java
@@ -10,13 +10,10 @@ import mage.game.Game;
import mage.game.stack.Spell;
/**
- *
* @author LevelX2
*/
-public class ManaSpentToCastCount implements DynamicValue {
-
- public ManaSpentToCastCount() {
- }
+public enum ManaSpentToCastCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability source, Effect effect) {
@@ -36,7 +33,7 @@ public class ManaSpentToCastCount implements DynamicValue {
@Override
public ManaSpentToCastCount copy() {
- return new ManaSpentToCastCount();
+ return ManaSpentToCastCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManacostVariableValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManacostVariableValue.java
index e29a7a9a88f..bade65f5446 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManacostVariableValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ManacostVariableValue.java
@@ -5,7 +5,8 @@ import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.game.Game;
-public class ManacostVariableValue implements DynamicValue {
+public enum ManacostVariableValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -14,7 +15,7 @@ public class ManacostVariableValue implements DynamicValue {
@Override
public ManacostVariableValue copy() {
- return new ManacostVariableValue();
+ return ManacostVariableValue.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/MorphManacostVariableValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/MorphManacostVariableValue.java
index b3f84b9a60f..bc137d87e22 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/MorphManacostVariableValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/MorphManacostVariableValue.java
@@ -11,10 +11,10 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
/**
- *
* @author LevelX2
*/
-public class MorphManacostVariableValue implements DynamicValue {
+public enum MorphManacostVariableValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -27,7 +27,7 @@ public class MorphManacostVariableValue implements DynamicValue {
@Override
public MorphManacostVariableValue copy() {
- return new MorphManacostVariableValue();
+ return MorphManacostVariableValue.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/MultikickerCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/MultikickerCount.java
index 4d693677630..b4b583c1da6 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/MultikickerCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/MultikickerCount.java
@@ -9,20 +9,17 @@ import mage.cards.Card;
import mage.game.Game;
/**
- *
* @author LevelX2
*/
-public class MultikickerCount implements DynamicValue {
-
- public MultikickerCount() {
- }
+public enum MultikickerCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability source, Effect effect) {
int count = 0;
Card card = game.getCard(source.getSourceId());
if (card != null) {
- for (Ability ability: card.getAbilities()) {
+ for (Ability ability : card.getAbilities()) {
if (ability instanceof KickerAbility) {
count += ((KickerAbility) ability).getKickedCounter(game, source);
}
@@ -33,7 +30,7 @@ public class MultikickerCount implements DynamicValue {
@Override
public MultikickerCount copy() {
- return new MultikickerCount();
+ return MultikickerCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java
index 2435bb53add..d8eee3f6276 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsCount.java
@@ -8,7 +8,8 @@ import mage.game.Game;
/**
* @author JayDi85
*/
-public class OpponentsCount implements DynamicValue {
+public enum OpponentsCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -17,7 +18,7 @@ public class OpponentsCount implements DynamicValue {
@Override
public OpponentsCount copy() {
- return new OpponentsCount();
+ return OpponentsCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsPoisonCountersCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsPoisonCountersCount.java
index 8851841caa2..76f16fe6ad9 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsPoisonCountersCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/OpponentsPoisonCountersCount.java
@@ -10,7 +10,8 @@ import mage.players.Player;
import java.util.Set;
import java.util.UUID;
-public class OpponentsPoisonCountersCount implements DynamicValue {
+public enum OpponentsPoisonCountersCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -27,7 +28,7 @@ public class OpponentsPoisonCountersCount implements DynamicValue {
@Override
public DynamicValue copy() {
- return new OpponentsPoisonCountersCount();
+ return OpponentsPoisonCountersCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java
index 66c49c96185..3a98ec1d655 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/PermanentsYouOwnThatOpponentsControlCount.java
@@ -1,15 +1,17 @@
package mage.abilities.dynamicvalue.common;
-import java.util.Set;
-import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.game.Game;
import mage.game.permanent.Permanent;
-public class PermanentsYouOwnThatOpponentsControlCount implements DynamicValue {
+import java.util.Set;
+import java.util.UUID;
+
+public enum PermanentsYouOwnThatOpponentsControlCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -28,7 +30,7 @@ public class PermanentsYouOwnThatOpponentsControlCount implements DynamicValue {
@Override
public PermanentsYouOwnThatOpponentsControlCount copy() {
- return new PermanentsYouOwnThatOpponentsControlCount();
+ return PermanentsYouOwnThatOpponentsControlCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/RemovedCountersForCostValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/RemovedCountersForCostValue.java
index 26c45840993..2b8620a5611 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/RemovedCountersForCostValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/RemovedCountersForCostValue.java
@@ -13,10 +13,10 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
/**
- *
* @author LevelX2
*/
-public class RemovedCountersForCostValue implements DynamicValue {
+public enum RemovedCountersForCostValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -35,7 +35,7 @@ public class RemovedCountersForCostValue implements DynamicValue {
@Override
public RemovedCountersForCostValue copy() {
- return new RemovedCountersForCostValue();
+ return RemovedCountersForCostValue.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/RevealTargetFromHandCostCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/RevealTargetFromHandCostCount.java
index b7574ac2f58..f9994726cc9 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/RevealTargetFromHandCostCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/RevealTargetFromHandCostCount.java
@@ -13,10 +13,10 @@ import mage.abilities.effects.Effect;
import mage.game.Game;
/**
- *
* @author emerald000
*/
-public class RevealTargetFromHandCostCount implements DynamicValue {
+public enum RevealTargetFromHandCostCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -35,7 +35,7 @@ public class RevealTargetFromHandCostCount implements DynamicValue {
@Override
public RevealTargetFromHandCostCount copy() {
- return new RevealTargetFromHandCostCount();
+ return RevealTargetFromHandCostCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesPower.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesPower.java
index 290a303c887..4cdaed1a82c 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesPower.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesPower.java
@@ -10,8 +10,8 @@ import mage.game.Game;
/**
* @author LevelX2
*/
-public class SacrificeCostCreaturesPower implements DynamicValue {
-
+public enum SacrificeCostCreaturesPower implements DynamicValue {
+instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
for (Cost cost : sourceAbility.getCosts()) {
@@ -26,7 +26,7 @@ public class SacrificeCostCreaturesPower implements DynamicValue {
@Override
public SacrificeCostCreaturesPower copy() {
- return new SacrificeCostCreaturesPower();
+ return SacrificeCostCreaturesPower.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesToughness.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesToughness.java
index bfc03a261ce..514b24f8a3f 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesToughness.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SacrificeCostCreaturesToughness.java
@@ -10,7 +10,8 @@ import mage.game.Game;
/**
* @author LevelX2
*/
-public class SacrificeCostCreaturesToughness implements DynamicValue {
+public enum SacrificeCostCreaturesToughness implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -25,7 +26,7 @@ public class SacrificeCostCreaturesToughness implements DynamicValue {
@Override
public SacrificeCostCreaturesToughness copy() {
- return new SacrificeCostCreaturesToughness();
+ return SacrificeCostCreaturesToughness.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/SunburstCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SunburstCount.java
index d42cc3f5281..6c49909cad5 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/SunburstCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/SunburstCount.java
@@ -10,14 +10,10 @@ import mage.game.stack.Spell;
import mage.game.stack.StackObject;
/**
- *
* @author Nicolas
*/
-public class SunburstCount implements DynamicValue {
-
- public SunburstCount() {
-
- }
+public enum SunburstCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability source, Effect effect) {
@@ -48,7 +44,7 @@ public class SunburstCount implements DynamicValue {
@Override
public SunburstCount copy() {
- return new SunburstCount();
+ return SunburstCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetConvertedManaCost.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetConvertedManaCost.java
index 7be84e3585c..26fe5ed8f5a 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetConvertedManaCost.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetConvertedManaCost.java
@@ -8,10 +8,10 @@ import mage.cards.Card;
import mage.game.Game;
/**
- *
* @author North
*/
-public class TargetConvertedManaCost implements DynamicValue {
+public enum TargetConvertedManaCost implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability source, Effect effect) {
@@ -24,7 +24,7 @@ public class TargetConvertedManaCost implements DynamicValue {
@Override
public TargetConvertedManaCost copy() {
- return new TargetConvertedManaCost();
+ return instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetPermanentPowerCount.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetPermanentPowerCount.java
index 814eb19970d..ab7e13d4b97 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetPermanentPowerCount.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/TargetPermanentPowerCount.java
@@ -9,10 +9,10 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
/**
- *
* @author North
*/
-public class TargetPermanentPowerCount implements DynamicValue {
+public enum TargetPermanentPowerCount implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
@@ -29,7 +29,7 @@ public class TargetPermanentPowerCount implements DynamicValue {
@Override
public TargetPermanentPowerCount copy() {
- return new TargetPermanentPowerCount();
+ return TargetPermanentPowerCount.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ZuberasDiedDynamicValue.java b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ZuberasDiedDynamicValue.java
index e81289233cc..c9310b63115 100644
--- a/Mage/src/main/java/mage/abilities/dynamicvalue/common/ZuberasDiedDynamicValue.java
+++ b/Mage/src/main/java/mage/abilities/dynamicvalue/common/ZuberasDiedDynamicValue.java
@@ -9,20 +9,21 @@ import mage.watchers.common.ZuberasDiedWatcher;
/**
* Created by Eric on 9/24/2016.
*/
-public class ZuberasDiedDynamicValue implements DynamicValue {
+public enum ZuberasDiedDynamicValue implements DynamicValue {
+ instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
ZuberasDiedWatcher watcher = game.getState().getWatcher(ZuberasDiedWatcher.class);
- if(watcher == null){
+ if (watcher == null) {
return 0;
}
- return watcher.getZuberasDiedThisTurn();
+ return watcher.getZuberasDiedThisTurn();
}
@Override
public ZuberasDiedDynamicValue copy() {
- return new ZuberasDiedDynamicValue();
+ return ZuberasDiedDynamicValue.instance;
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java
index 6e7abd8d267..32b1b7940db 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/FlipCoinEffect.java
@@ -60,7 +60,7 @@ public class FlipCoinEffect extends OneShotEffect {
MageObject mageObject = game.getObject(source.getSourceId());
if (controller != null && mageObject != null) {
boolean result = true;
- for (Effect effect : controller.flipCoin(game) ? executingEffectsWon : executingEffectsLost) {
+ for (Effect effect : controller.flipCoin(source, game, true) ? executingEffectsWon : executingEffectsLost) {
effect.setTargetPointer(this.targetPointer);
if (effect instanceof OneShotEffect) {
result &= effect.apply(game, source);
diff --git a/Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java b/Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java
index 365e6b3a6a1..6d1abe14fdd 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/FlipUntilLoseEffect.java
@@ -34,7 +34,7 @@ public class FlipUntilLoseEffect extends OneShotEffect {
return false;
}
while (true) {
- if (!player.flipCoin(game)) {
+ if (!player.flipCoin(source, game, true)) {
return true;
}
}
diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java
index 76c0e120248..9254999b2ba 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/BoostTargetEffect.java
@@ -99,7 +99,7 @@ public class BoostTargetEffect extends ContinuousEffectImpl {
Target target = mode.getTargets().get(0);
StringBuilder sb = new StringBuilder();
if (target.getMaxNumberOfTargets() > 1) {
- if (target.getNumberOfTargets() < target.getNumberOfTargets()) {
+ if (target.getNumberOfTargets() < target.getMaxNumberOfTargets()) {
sb.append("up to ");
}
sb.append(CardUtil.numberToText(target.getMaxNumberOfTargets())).append(" target ").append(target.getTargetName()).append(" get ");
diff --git a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersTargetEffect.java
index e50680a73c1..4c717eb6e49 100644
--- a/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersTargetEffect.java
+++ b/Mage/src/main/java/mage/abilities/effects/common/counter/AddCountersTargetEffect.java
@@ -1,8 +1,5 @@
-
package mage.abilities.effects.common.counter;
-import java.util.Locale;
-import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
@@ -19,8 +16,10 @@ import mage.players.Player;
import mage.target.Target;
import mage.util.CardUtil;
+import java.util.Locale;
+import java.util.UUID;
+
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public class AddCountersTargetEffect extends OneShotEffect {
@@ -121,8 +120,8 @@ public class AddCountersTargetEffect extends OneShotEffect {
}
sb.append(" on ");
- if (!mode.getTargets().isEmpty()) {
- Target target = mode.getTargets().get(0);
+ Target target = mode.getTargets().getEffectTarget(this.targetPointer);
+ if (target != null) {
if (target.getNumberOfTargets() == 0) {
sb.append("up to ");
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/AfterlifeAbility.java b/Mage/src/main/java/mage/abilities/keyword/AfterlifeAbility.java
index ba71038869d..2fa1c7ecf36 100644
--- a/Mage/src/main/java/mage/abilities/keyword/AfterlifeAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/AfterlifeAbility.java
@@ -6,6 +6,7 @@ import mage.game.permanent.token.WhiteBlackSpiritToken;
import mage.util.CardUtil;
public class AfterlifeAbility extends DiesTriggeredAbility {
+
private final int tokenCount;
public AfterlifeAbility(int tokenCount) {
@@ -22,9 +23,9 @@ public class AfterlifeAbility extends DiesTriggeredAbility {
public String getRule() {
return "Afterlife " + tokenCount + " (When this creature dies, create "
+ CardUtil.numberToText(tokenCount, "a")
- + " white and black Spirit creature token"
+ + " 1/1 white and black Spirit creature token"
+ (tokenCount > 1 ? "s" : "")
- + " with flying)";
+ + " with flying.)";
}
@Override
diff --git a/Mage/src/main/java/mage/abilities/keyword/RiotAbility.java b/Mage/src/main/java/mage/abilities/keyword/RiotAbility.java
index 47ca943dcb7..8ce3e97bb51 100644
--- a/Mage/src/main/java/mage/abilities/keyword/RiotAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/RiotAbility.java
@@ -71,7 +71,7 @@ class RiotReplacementEffect extends ReplacementEffectImpl {
Permanent creature = ((EntersTheBattlefieldEvent) event).getTarget();
Player controller = game.getPlayer(source.getControllerId());
if (creature != null && controller != null) {
- if (controller.chooseUse(outcome, "Have " + creature.getLogName() + " enter the battlefield with a +1/+1 counter on it? (If you don't it has haste)", source, game)) {
+ if (controller.chooseUse(outcome, "Have " + creature.getLogName() + " enter the battlefield with a +1/+1 counter on it or with haste?",null, "+1/+1 counter", "Haste", source, game)) {
if (!game.isSimulation()) {
game.informPlayers(controller.getLogName() + " choose to put a +1/+1 counter on " + creature.getName());
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java b/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java
index aebf6928c8b..55e5823ea5a 100644
--- a/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/SplitSecondAbility.java
@@ -69,7 +69,7 @@ class SplitSecondEffect extends ContinuousRuleModifyingEffectImpl {
}
if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) {
Optional ability = game.getAbility(event.getTargetId(), event.getSourceId());
- if (ability != null && !(ability.get() instanceof ActivatedManaAbilityImpl)) {
+ if (ability.isPresent() && !(ability.get() instanceof ActivatedManaAbilityImpl)) {
return true;
}
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/StormAbility.java b/Mage/src/main/java/mage/abilities/keyword/StormAbility.java
index 4e1b33d6769..001c1add9b3 100644
--- a/Mage/src/main/java/mage/abilities/keyword/StormAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/StormAbility.java
@@ -89,7 +89,7 @@ class StormEffect extends OneShotEffect {
}
}
} else {
- Logger.getLogger(StormEffect.class).fatal("CastSpellLastTurnWatcher not found. game = " + game == null ? "NULL" : game.getGameType().toString());
+ Logger.getLogger(StormEffect.class).fatal("CastSpellLastTurnWatcher not found. game = " +game.getGameType().toString());
}
return true;
}
diff --git a/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java b/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java
index e5aabcfe010..434b57f96a2 100644
--- a/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java
+++ b/Mage/src/main/java/mage/abilities/keyword/SunburstAbility.java
@@ -50,7 +50,7 @@ public class SunburstAbility extends EntersBattlefieldAbility {
class SunburstEffect extends OneShotEffect {
- private static final DynamicValue amount = new SunburstCount();
+ private static final DynamicValue amount = SunburstCount.instance;
public SunburstEffect() {
super(Outcome.Benefit);
diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java
index c071091c92a..379cfd1e9ce 100644
--- a/Mage/src/main/java/mage/cards/repository/CardRepository.java
+++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java
@@ -36,7 +36,7 @@ public enum CardRepository {
// raise this if db structure was changed
private static final long CARD_DB_VERSION = 51;
// raise this if new cards were added to the server
- private static final long CARD_CONTENT_VERSION = 123;
+ private static final long CARD_CONTENT_VERSION = 214;
private Dao cardDao;
private Set classNames;
private RepositoryEventSource eventSource = new RepositoryEventSource();
diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java
index 7b17f8cdd11..25ec612248d 100644
--- a/Mage/src/main/java/mage/game/GameImpl.java
+++ b/Mage/src/main/java/mage/game/GameImpl.java
@@ -1063,7 +1063,7 @@ public abstract class GameImpl implements Game, Serializable {
}
- private void initGameDefaultWatchers() {
+ public void initGameDefaultWatchers() {
getState().addWatcher(new MorbidWatcher());
getState().addWatcher(new CastSpellLastTurnWatcher());
getState().addWatcher(new CastSpellYourLastTurnWatcher());
@@ -1075,7 +1075,7 @@ public abstract class GameImpl implements Game, Serializable {
getState().addWatcher(new PlayersAttackedThisTurnWatcher());
}
- private void initPlayerDefaultWatchers(UUID playerId) {
+ public void initPlayerDefaultWatchers(UUID playerId) {
getState().addWatcher(new PlayerDamagedBySourceWatcher(playerId));
getState().addWatcher(new BloodthirstWatcher(playerId));
}
diff --git a/Mage/src/main/java/mage/game/combat/Combat.java b/Mage/src/main/java/mage/game/combat/Combat.java
index 1f0e73e9509..c7ab29f73c8 100644
--- a/Mage/src/main/java/mage/game/combat/Combat.java
+++ b/Mage/src/main/java/mage/game/combat/Combat.java
@@ -463,7 +463,7 @@ public class Combat implements Serializable, Copyable {
target.setRequired(true);
target.setTargetName("planeswalker or player for " + creature.getLogName() + " to attack");
if (player.chooseTarget(Outcome.Damage, target, null, game)) {
- System.out.println("The player " + player.getName() + " declares an attacker here. " + creature.getName());
+ //System.out.println("The player " + player.getName() + " declares an attacker here. " + creature.getName());
player.declareAttacker(creature.getId(), target.getFirstTarget(), game, false);
}
}
diff --git a/Mage/src/main/java/mage/game/command/emblems/DomriChaosBringerEmblem.java b/Mage/src/main/java/mage/game/command/emblems/DomriChaosBringerEmblem.java
index 66bac035541..fc35e32c1a2 100644
--- a/Mage/src/main/java/mage/game/command/emblems/DomriChaosBringerEmblem.java
+++ b/Mage/src/main/java/mage/game/command/emblems/DomriChaosBringerEmblem.java
@@ -3,6 +3,7 @@ package mage.game.command.emblems;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.constants.TargetController;
+import mage.constants.Zone;
import mage.game.command.Emblem;
import mage.game.permanent.token.RedGreenBeastToken;
@@ -16,8 +17,8 @@ public final class DomriChaosBringerEmblem extends Emblem {
this.setName("Emblem Domri");
this.setExpansionSetCodeForImage("RNA");
this.getAbilities().add(new BeginningOfEndStepTriggeredAbility(
- new CreateTokenEffect(new RedGreenBeastToken()),
- TargetController.ANY, false
+ Zone.COMMAND, new CreateTokenEffect(new RedGreenBeastToken()),
+ TargetController.ANY, null, false
));
}
}
diff --git a/Mage/src/main/java/mage/game/command/emblems/ObNixilisOfTheBlackOathEmblem.java b/Mage/src/main/java/mage/game/command/emblems/ObNixilisOfTheBlackOathEmblem.java
index c324972d068..4131d1b3237 100644
--- a/Mage/src/main/java/mage/game/command/emblems/ObNixilisOfTheBlackOathEmblem.java
+++ b/Mage/src/main/java/mage/game/command/emblems/ObNixilisOfTheBlackOathEmblem.java
@@ -24,7 +24,7 @@ public final class ObNixilisOfTheBlackOathEmblem extends Emblem {
// You get an emblem with "{1}{B}, Sacrifice a creature: You gain X life and draw X cards, where X is the sacrificed creature's power."
public ObNixilisOfTheBlackOathEmblem() {
this.setName("Emblem Nixilis");
- DynamicValue xValue = new SacrificeCostCreaturesPower();
+ DynamicValue xValue = SacrificeCostCreaturesPower.instance;
Effect effect = new GainLifeEffect(xValue);
effect.setText("You gain X life");
Ability ability = new SimpleActivatedAbility(Zone.COMMAND, effect, new ManaCostsImpl("{1}{B}"));
diff --git a/Mage/src/main/java/mage/game/command/planes/FeedingGroundsPlane.java b/Mage/src/main/java/mage/game/command/planes/FeedingGroundsPlane.java
index bf125dadf41..04fb098a1fb 100644
--- a/Mage/src/main/java/mage/game/command/planes/FeedingGroundsPlane.java
+++ b/Mage/src/main/java/mage/game/command/planes/FeedingGroundsPlane.java
@@ -53,7 +53,7 @@ public class FeedingGroundsPlane extends Plane {
this.getAbilities().add(ability);
// Active player can roll the planar die: Whenever you roll {CHAOS}, target red or green creature gets X +1/+1 counters
- Effect chaosEffect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), new TargetConvertedManaCost());
+ Effect chaosEffect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(), TargetConvertedManaCost.instance);
Target chaosTarget = new TargetCreaturePermanent(1, 1, filter, false);
List chaosEffects = new ArrayList();
diff --git a/Mage/src/main/java/mage/game/events/CoinFlippedEvent.java b/Mage/src/main/java/mage/game/events/CoinFlippedEvent.java
new file mode 100644
index 00000000000..b7dad082256
--- /dev/null
+++ b/Mage/src/main/java/mage/game/events/CoinFlippedEvent.java
@@ -0,0 +1,41 @@
+package mage.game.events;
+
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ **/
+public class CoinFlippedEvent extends GameEvent {
+ private final boolean result;
+ private final boolean chosen;
+ private final boolean winnable;
+
+ CoinFlippedEvent(UUID playerId, UUID sourceId, boolean result, boolean chosen, boolean winnable) {
+ super(EventType.COIN_FLIPPED, playerId, sourceId, playerId);
+ this.result = result;
+ this.chosen = chosen;
+ this.winnable = winnable;
+ }
+
+ public boolean getResult() {
+ return result;
+ }
+
+ public String getResultName() {
+ return CardUtil.booleanToFlipName(result);
+ }
+
+ public boolean getChosen() {
+ return chosen;
+ }
+
+ public String getChosenName() {
+ return CardUtil.booleanToFlipName(chosen);
+ }
+
+ public boolean isWinnable() {
+ return winnable;
+ }
+}
diff --git a/Mage/src/main/java/mage/game/events/FlipCoinEvent.java b/Mage/src/main/java/mage/game/events/FlipCoinEvent.java
new file mode 100644
index 00000000000..3dc799ad4ec
--- /dev/null
+++ b/Mage/src/main/java/mage/game/events/FlipCoinEvent.java
@@ -0,0 +1,58 @@
+package mage.game.events;
+
+import mage.util.CardUtil;
+
+import java.util.UUID;
+
+/**
+ * @author TheElk801
+ **/
+public class FlipCoinEvent extends GameEvent {
+ private boolean result;
+ private final boolean chosen;
+ private final boolean winnable;
+ private int flipCount = 1;
+
+ public FlipCoinEvent(UUID playerId, UUID sourceId, boolean result, boolean chosen, boolean winnable) {
+ super(EventType.FLIP_COIN, playerId, sourceId, playerId);
+ this.result = result;
+ this.chosen = chosen;
+ this.winnable = winnable;
+ }
+
+ public boolean getResult() {
+ return result;
+ }
+
+ public String getResultName() {
+ return CardUtil.booleanToFlipName(result);
+ }
+
+ public void setResult(boolean result) {
+ this.result = result;
+ }
+
+ public boolean getChosen() {
+ return chosen;
+ }
+
+ public String getChosenName() {
+ return CardUtil.booleanToFlipName(chosen);
+ }
+
+ public boolean isWinnable() {
+ return winnable;
+ }
+
+ public int getFlipCount() {
+ return flipCount;
+ }
+
+ public void setFlipCount(int flipCount) {
+ this.flipCount = flipCount;
+ }
+
+ public CoinFlippedEvent getFlippedEvent() {
+ return new CoinFlippedEvent(playerId, sourceId, result, chosen, winnable);
+ }
+}
diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java
index 7c97be707a3..286b98f5acc 100644
--- a/Mage/src/main/java/mage/players/Player.java
+++ b/Mage/src/main/java/mage/players/Player.java
@@ -74,7 +74,7 @@ public interface Player extends MageItem, Copyable {
void setLife(int life, Game game, UUID sourceId);
/**
- * @param amount amount of life loss
+ * @param amount amount of life loss
* @param game
* @param atCombat was the source combat damage
* @return
@@ -347,7 +347,7 @@ public interface Player extends MageItem, Copyable {
* @param target
* @param game
* @param targetPlayerId player whose library will be searched
- * @param triggerEvents whether searching will trigger any game events
+ * @param triggerEvents whether searching will trigger any game events
* @return true if search was successful
*/
boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId, boolean triggerEvents);
@@ -355,6 +355,7 @@ public interface Player extends MageItem, Copyable {
/**
* Reveals all players' libraries. Useful for abilities like Jace, Architect of Thought's -8
* that have effects that require information from all libraries.
+ *
* @param source
* @param game
* @return
@@ -366,23 +367,23 @@ public interface Player extends MageItem, Copyable {
/**
* Plays a card if possible
*
- * @param card the card that can be cast
+ * @param card the card that can be cast
* @param game
- * @param noMana if it's a spell i can be cast without paying mana
+ * @param noMana if it's a spell i can be cast without paying mana
* @param ignoreTiming if it's cast during the resolution of another spell
- * no sorcery or play land timing restriction are checked. For a land it has
- * to be the turn of the player playing that card.
- * @param reference mage object that allows to play the card
+ * no sorcery or play land timing restriction are checked. For a land it has
+ * to be the turn of the player playing that card.
+ * @param reference mage object that allows to play the card
* @return
*/
boolean playCard(Card card, Game game, boolean noMana, boolean ignoreTiming, MageObjectReference reference);
/**
- * @param card the land card to play
+ * @param card the land card to play
* @param game
* @param ignoreTiming false - it won't be checked if the stack is empty and
- * you are able to play a Sorcery. It's still checked, if you are able to
- * play a land concerning the number of lands you already played.
+ * you are able to play a Sorcery. It's still checked, if you are able to
+ * play a land concerning the number of lands you already played.
* @return
*/
boolean playLand(Card card, Game game, boolean ignoreTiming);
@@ -395,9 +396,9 @@ public interface Player extends MageItem, Copyable {
boolean hasProtectionFrom(MageObject source, Game game);
- boolean flipCoin(Game game);
+ boolean flipCoin(Ability source, Game game, boolean winnable);
- boolean flipCoin(Game game, ArrayList appliedEffects);
+ boolean flipCoin(Ability source, Game game, boolean winnable, ArrayList appliedEffects);
int rollDice(Game game, int numSides);
@@ -528,11 +529,11 @@ public interface Player extends MageItem, Copyable {
/**
* Moves the cards from cards to the bottom of the players library.
*
- * @param cards - list of cards that have to be moved
- * @param game - game
+ * @param cards - list of cards that have to be moved
+ * @param game - game
* @param anyOrder - true if player can determine the order of the cards
- * else random order
- * @param source - source ability
+ * else random order
+ * @param source - source ability
* @return
*/
boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder);
@@ -553,10 +554,10 @@ public interface Player extends MageItem, Copyable {
/**
* Moves the cards from cards to the top of players library.
*
- * @param cards - list of cards that have to be moved
- * @param game - game
+ * @param cards - list of cards that have to be moved
+ * @param game - game
* @param anyOrder - true if player can determine the order of the cards
- * @param source - source ability
+ * @param source - source ability
* @return
*/
boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder);
@@ -582,8 +583,8 @@ public interface Player extends MageItem, Copyable {
/**
* Choose the order in which blockers get damage assigned to
*
- * @param blockers list of blockers where to choose the next one from
- * @param combatGroup the concerning combat group
+ * @param blockers list of blockers where to choose the next one from
+ * @param combatGroup the concerning combat group
* @param blockerOrder the already set order of blockers
* @param game
* @return blocker next to add to the blocker order
@@ -722,11 +723,11 @@ public interface Player extends MageItem, Copyable {
* @param toZone
* @param source
* @param game
- * @param tapped the cards are tapped on the battlefield
- * @param faceDown the cards are face down in the to zone
- * @param byOwner the card is moved (or put onto battlefield) by the owner
- * of the card and if target zone is battlefield controls the permanent
- * (instead of the controller of the source)
+ * @param tapped the cards are tapped on the battlefield
+ * @param faceDown the cards are face down in the to zone
+ * @param byOwner the card is moved (or put onto battlefield) by the owner
+ * of the card and if target zone is battlefield controls the permanent
+ * (instead of the controller of the source)
* @param appliedEffects
* @return
*/
@@ -762,7 +763,7 @@ public interface Player extends MageItem, Copyable {
* list of applied effects is not saved
*
* @param card
- * @param exileId exile zone id (optional)
+ * @param exileId exile zone id (optional)
* @param exileName name of exile zone (optional)
* @param sourceId
* @param game
@@ -804,7 +805,7 @@ public interface Player extends MageItem, Copyable {
* @param sourceId
* @param game
* @param fromZone if null, this info isn't postet
- * @param toTop to the top of the library else to the bottom
+ * @param toTop to the top of the library else to the bottom
* @param withName show the card name in the log
* @return
*/
@@ -829,10 +830,10 @@ public interface Player extends MageItem, Copyable {
* without mana (null) or the mana set to manaCosts instead of its normal
* mana costs.
*
- * @param sourceId the source that can be cast without mana
+ * @param sourceId the source that can be cast without mana
* @param manaCosts alternate ManaCost, null if it can be cast without mana
- * cost
- * @param costs alternate other costs you need to pay
+ * cost
+ * @param costs alternate other costs you need to pay
*/
void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, Costs costs);
diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java
index 6ff3332301a..155f74ceccc 100644
--- a/Mage/src/main/java/mage/players/PlayerImpl.java
+++ b/Mage/src/main/java/mage/players/PlayerImpl.java
@@ -42,11 +42,8 @@ import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.*;
import mage.game.combat.CombatGroup;
import mage.game.command.CommandObject;
-import mage.game.events.DamagePlayerEvent;
-import mage.game.events.DamagedPlayerEvent;
-import mage.game.events.GameEvent;
+import mage.game.events.*;
import mage.game.events.GameEvent.EventType;
-import mage.game.events.ZoneChangeEvent;
import mage.game.match.MatchPlayer;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard;
@@ -2560,27 +2557,59 @@ public abstract class PlayerImpl implements Player, Serializable {
}
@Override
- public boolean flipCoin(Game game) {
- return this.flipCoin(game, null);
+ public boolean flipCoin(Ability source, Game game, boolean winnable) {
+ return this.flipCoin(source, game, winnable, null);
}
/**
+ * @param source
* @param game
+ * @param winnable
* @param appliedEffects
- * @return true if player won the toss
+ * @return if winnable, true if player won the toss, if not winnable, true for heads and false for tails
*/
@Override
- public boolean flipCoin(Game game, ArrayList appliedEffects) {
+ public boolean flipCoin(Ability source, Game game, boolean winnable, ArrayList appliedEffects) {
+ boolean chosen = false;
+ if (winnable) {
+ chosen = this.chooseUse(Outcome.Benefit, "Heads or tails?", "", "Heads", "Tails", source, game);
+ game.informPlayers(getLogName() + " chose " + CardUtil.booleanToFlipName(chosen));
+ }
boolean result = RandomUtil.nextBoolean();
- if (!game.isSimulation()) {
- game.informPlayers("[Flip a coin] " + getLogName() + (result ? " won (head)." : " lost (tail)."));
+ FlipCoinEvent event = new FlipCoinEvent(playerId, source.getSourceId(), result, chosen, winnable);
+ event.addAppliedEffects(appliedEffects);
+ game.replaceEvent(event);
+ game.informPlayers(getLogName() + " flipped " + CardUtil.booleanToFlipName(event.getResult()));
+ if (event.getFlipCount() > 1) {
+ boolean canChooseHeads = event.getResult();
+ boolean canChooseTails = !event.getResult();
+ for (int i = 1; i < event.getFlipCount(); i++) {
+ boolean tempFlip = RandomUtil.nextBoolean();
+ canChooseHeads = canChooseHeads || tempFlip;
+ canChooseTails = canChooseTails || !tempFlip;
+ game.informPlayers(getLogName() + " flipped " + CardUtil.booleanToFlipName(tempFlip));
+ }
+ if (canChooseHeads && canChooseTails) {
+ event.setResult(chooseUse(Outcome.Benefit, "Choose which flip to keep",
+ (event.isWinnable() ? "(You called " + event.getChosenName() + ")" : null),
+ "Heads", "Tails", source, game
+ ));
+ } else if (canChooseHeads) {
+ event.setResult(true);
+ } else {
+ event.setResult(false);
+ }
+ game.informPlayers(getLogName() + " chose to keep " + CardUtil.booleanToFlipName(event.getResult()));
+ }
+ if (event.isWinnable()) {
+ game.informPlayers(getLogName() + " " + (event.getResult() == event.getChosen() ? "won" : "lost") + " the flip");
}
- GameEvent event = new GameEvent(GameEvent.EventType.FLIP_COIN, playerId, null, playerId, 0, result);
event.setAppliedEffects(appliedEffects);
- if (!game.replaceEvent(event)) {
- game.fireEvent(new GameEvent(GameEvent.EventType.COIN_FLIPPED, playerId, null, playerId, 0, event.getFlag()));
+ game.fireEvent(event.getFlippedEvent());
+ if (event.isWinnable()) {
+ return event.getResult() == event.getChosen();
}
- return event.getFlag();
+ return event.getResult();
}
@Override
@@ -2598,7 +2627,7 @@ public abstract class PlayerImpl implements Player, Serializable {
public int rollDice(Game game, ArrayList appliedEffects, int numSides) {
int result = RandomUtil.nextInt(numSides) + 1;
if (!game.isSimulation()) {
- game.informPlayers("[Roll a die] " + getLogName() + " rolled a " + result + " on a " + numSides + " sided dice");
+ game.informPlayers("[Roll a die] " + getLogName() + " rolled a " + result + " on a " + numSides + " sided die");
}
GameEvent event = new GameEvent(GameEvent.EventType.ROLL_DICE, playerId, null, playerId, result, true);
event.setAppliedEffects(appliedEffects);
diff --git a/Mage/src/main/java/mage/target/Targets.java b/Mage/src/main/java/mage/target/Targets.java
index a1645e12d44..112a4093165 100644
--- a/Mage/src/main/java/mage/target/Targets.java
+++ b/Mage/src/main/java/mage/target/Targets.java
@@ -1,10 +1,14 @@
-
package mage.target;
import mage.abilities.Ability;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
+import mage.target.targetpointer.FirstTargetPointer;
+import mage.target.targetpointer.SecondTargetPointer;
+import mage.target.targetpointer.TargetPointer;
+import mage.target.targetpointer.ThirdTargetPointer;
+import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
@@ -12,11 +16,12 @@ import java.util.UUID;
import java.util.stream.Collectors;
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public class Targets extends ArrayList {
+ private static final Logger logger = Logger.getLogger(Targets.class);
+
public Targets() {
}
@@ -101,7 +106,7 @@ public class Targets extends ArrayList {
* Checks if there are enough targets that can be chosen. Should only be
* used for Ability targets since this checks for protection, shroud etc.
*
- * @param sourceId - the target event source
+ * @param sourceId - the target event source
* @param sourceControllerId - controller of the target event source
* @param game
* @return - true if enough valid targets exist
@@ -130,6 +135,38 @@ public class Targets extends ArrayList {
return null;
}
+ public Target getEffectTarget(TargetPointer targetPointer) {
+ boolean proccessed = false;
+
+ if (targetPointer instanceof FirstTargetPointer) {
+ proccessed = true;
+ if (this.size() > 0) {
+ return this.get(0);
+ }
+ }
+
+ if (targetPointer instanceof SecondTargetPointer) {
+ proccessed = true;
+ if (this.size() > 1) {
+ return this.get(1);
+ }
+ }
+
+ if (targetPointer instanceof ThirdTargetPointer) {
+ proccessed = true;
+ if (this.size() > 2) {
+ return this.get(2);
+ }
+ }
+
+ if (!proccessed) {
+ logger.error("Unknown target pointer " + (targetPointer != null ? targetPointer : "null"), new Throwable());
+ // TODO: add other target types?
+ }
+
+ return null;
+ }
+
public Targets copy() {
return new Targets(this);
}
diff --git a/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java b/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java
index 64bbbe36112..5e1ca2be78f 100644
--- a/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java
+++ b/Mage/src/main/java/mage/target/common/TargetActivatedAbility.java
@@ -50,6 +50,7 @@ public class TargetActivatedAbility extends TargetObject {
return stackObject != null
&& stackObject.getStackAbility() != null
&& stackObject.getStackAbility().getAbilityType() == AbilityType.ACTIVATED
+ && source != null
&& filter.match(stackObject, source.getSourceId(), source.getControllerId(), game);
}
diff --git a/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java b/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java
index a348ad4122e..6552c4bba01 100644
--- a/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java
+++ b/Mage/src/main/java/mage/target/common/TargetActivatedOrTriggeredAbility.java
@@ -42,7 +42,7 @@ public class TargetActivatedOrTriggeredAbility extends TargetObject {
}
StackObject stackObject = game.getStack().getStackObject(id);
- return isActivatedOrTriggeredAbility(stackObject) && filter.match(stackObject, source.getSourceId(), source.getControllerId(), game);
+ return isActivatedOrTriggeredAbility(stackObject) && source != null && filter.match(stackObject, source.getSourceId(), source.getControllerId(), game);
}
@Override
diff --git a/Mage/src/main/java/mage/util/CardUtil.java b/Mage/src/main/java/mage/util/CardUtil.java
index 9b3cfe75ca1..c81981296e7 100644
--- a/Mage/src/main/java/mage/util/CardUtil.java
+++ b/Mage/src/main/java/mage/util/CardUtil.java
@@ -354,6 +354,13 @@ public final class CardUtil {
return message;
}
+ public static String booleanToFlipName(boolean flip) {
+ if (flip) {
+ return "Heads";
+ }
+ return "Tails";
+ }
+
public static boolean checkNumeric(String s) {
return s.chars().allMatch(Character::isDigit);
diff --git a/Utils/find_new_cards.pl b/Utils/find_new_cards.pl
index db6a7db5f3f..79d50ff9581 100644
--- a/Utils/find_new_cards.pl
+++ b/Utils/find_new_cards.pl
@@ -5,7 +5,7 @@
use strict;
my $addedCards;
-my $GIT_CMD = "C:\\Program Files (x86)\\Git\\bin\\git.exe";
+my $GIT_CMD = "git.exe";
my $text = `\"$GIT_CMD\" tag`;
print "Assuming the tag command is on: \"$GIT_CMD\" tag\n";
diff --git a/pom.xml b/pom.xml
index c29fc8e2e1e..bc1f3ad553c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.mage
mage-root
- 1.4.32
+ 1.4.33
pom
Mage Root
Mage Root POM
@@ -88,7 +88,7 @@
- 1.4.32
+ 1.4.33
UTF-8
yyyy-MM-dd'T'HH:mm:ss'Z'