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 @@
- - - @@ -26,30 +23,26 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + - + + + + + + + + + + + @@ -57,82 +50,58 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + - + + + + + + + + + + + + + + + + + + + + + - + - - + + @@ -152,49 +121,27 @@ + - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + + @@ -205,10 +152,11 @@ + - + @@ -289,86 +237,23 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + - - + + @@ -420,5 +305,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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'