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/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 9f2258a31ad..7d932d99e50 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
@@ -105,10 +105,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();
@@ -122,47 +118,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.");
@@ -223,55 +213,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);
@@ -293,28 +240,171 @@ 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()
+ .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.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)
+ .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)
@@ -323,67 +413,45 @@ public class ConnectDialog extends MageDialog {
.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)
- .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)))
+ .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(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))
+ .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.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))
+ .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.BASELINE)
- .addComponent(txtUserName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(lblUserName))
+ .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.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)
+ .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.UNRELATED)
- .addComponent(jProxySettingsButton)
.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)
@@ -396,6 +464,8 @@ public class ConnectDialog extends MageDialog {
.addGap(23, 23, 23))
);
+ lblFastConnect.getAccessibleContext().setAccessibleName("Fast connect to:");
+
pack();
}// //GEN-END:initComponents
@@ -659,8 +729,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
@@ -682,10 +751,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);
@@ -731,11 +823,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;
@@ -743,6 +837,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;
@@ -751,7 +846,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.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/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java
index e4550bddf11..284ea65ef18 100644
--- a/Mage.Common/src/main/java/mage/utils/MageVersion.java
+++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java
@@ -14,7 +14,7 @@ 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";
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.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.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/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/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/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/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/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/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/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/DomriChaosBringer.java b/Mage.Sets/src/mage/cards/d/DomriChaosBringer.java
index e0e55c44716..d05415185a7 100644
--- a/Mage.Sets/src/mage/cards/d/DomriChaosBringer.java
+++ b/Mage.Sets/src/mage/cards/d/DomriChaosBringer.java
@@ -106,7 +106,7 @@ class DomriChaosBringerTriggeredAbility extends DelayedTriggeredAbility {
private final UUID spellId;
DomriChaosBringerTriggeredAbility(UUID spellId) {
- super(null, Duration.Custom, true);
+ super(null, Duration.EndOfStep, true);
this.spellId = spellId;
this.usesStack = false;
}
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/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/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/KrarksThumb.java b/Mage.Sets/src/mage/cards/k/KrarksThumb.java
index 66f31eb3861..d5698826939 100644
--- a/Mage.Sets/src/mage/cards/k/KrarksThumb.java
+++ b/Mage.Sets/src/mage/cards/k/KrarksThumb.java
@@ -63,7 +63,7 @@ class KrarksThumbEffect extends ReplacementEffectImpl {
);
boolean chosenFlip = player.chooseUse(
Outcome.Benefit, "Choose which coin you want",
- "(You chose " + flipEvent.getChosenName() + ")",
+ (flipEvent.isWinnable() ? "(You chose " + flipEvent.getChosenName() + ")" : null),
flipEvent.getResultName(), CardUtil.booleanToFlipName(secondFlip), source, game
);
if (!chosenFlip) {
diff --git a/Mage.Sets/src/mage/cards/l/LumberingBattlement.java b/Mage.Sets/src/mage/cards/l/LumberingBattlement.java
index 8db020a7dc9..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;
@@ -29,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;
@@ -106,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) {
@@ -114,10 +118,8 @@ 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()
);
}
}
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/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/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/PriestOfForgottenGods.java b/Mage.Sets/src/mage/cards/p/PriestOfForgottenGods.java
index 49f57a4df1e..801350a032c 100644
--- a/Mage.Sets/src/mage/cards/p/PriestOfForgottenGods.java
+++ b/Mage.Sets/src/mage/cards/p/PriestOfForgottenGods.java
@@ -29,7 +29,7 @@ import java.util.UUID;
public final class PriestOfForgottenGods extends CardImpl {
private static final FilterControlledPermanent filter
- = new FilterControlledCreaturePermanent("two other creatures");
+ = new FilterControlledCreaturePermanent("other creatures");
static {
filter.add(AnotherPredicate.instance);
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/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/s/ScholarOfAthreos.java b/Mage.Sets/src/mage/cards/s/ScholarOfAthreos.java
index bf19ce283a7..aebf8005de6 100644
--- a/Mage.Sets/src/mage/cards/s/ScholarOfAthreos.java
+++ b/Mage.Sets/src/mage/cards/s/ScholarOfAthreos.java
@@ -13,6 +13,7 @@ import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
+import mage.players.Player;
/**
*
@@ -32,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);
}
@@ -49,7 +50,7 @@ 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);
}
@@ -57,7 +58,10 @@ class ScholarOfAthreosEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
int lifeLost = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
- lifeLost += game.getPlayer(opponentId).loseLife(1, game, false);
+ Player opponent = game.getPlayer(opponentId);
+ if(opponent != null) {
+ lifeLost += opponent.loseLife(1, game, false);
+ }
}
game.getPlayer(source.getControllerId()).gainLife(lifeLost, game, source);
return true;
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/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/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/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/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/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/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.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.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.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/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/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/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/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'