Merge pull request #54 from magefree/master

Merge https://github.com/magefree/mage
This commit is contained in:
L_J 2018-05-01 01:12:38 +02:00 committed by GitHub
commit 196e428f7b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 1161 additions and 1878 deletions

View file

@ -0,0 +1,77 @@
NAME:FastRedHaste
16 [DOM:262] Mountain
1 [8ED:200] Lightning Blast
1 [M15:35] Soulmender
1 [M11:149] Lightning Bolt
1 [ZEN:142] Punishing Fire
1 [C16:16] Charging Cinderhorn
1 [M13:200] Akroma's Memorial
1 [RAV:193] Boros Swiftblade
1 [3ED:296] Plateau
1 [EMN:149] Weaver of Lightning
1 [BNG:108] Satyr Firedancer
1 [WTH:93] Cinder Giant
1 [DGM:56] Blaze Commando
1 [TSP:180] Sulfurous Blast
1 [BFZ:150] Outnumber
1 [M14:139] Flames of the Firebrand
1 [INV:11] Crimson Acolyte
1 [LEG:247] Hammerheim
1 [KLD:246] Inspiring Vantage
1 [DGM:107] Tajic, Blade of the Legion
1 [GTC:97] Legion Loyalist
1 [USG:11] Disciple of Law
1 [ORI:143] Exquisite Firecraft
1 [KLD:130] Skyship Stalker
1 [XLN:145] Firecannon Blast
1 [AKH:21] Oketra the True
1 [OGW:175] Needle Spires
1 [ISD:23] Mikaeus, the Lunarch
1 [WWK:90] Searing Blaze
1 [ZEN:119] Burst Lightning
1 [ISD:4] Avacynian Priest
1 [ODY:200] Lava Blister
1 [EVE:139] Figure of Destiny
1 [LEG:175] Clergy of the Holy Nimbus
1 [LEG:133] Beasts of Bogardan
1 [DTK:151] Roast
1 [ME4:113] Fire Imp
1 [RAV:255] Boros Signet
1 [RAV:213] Lightning Helix
1 [M11:129] Chandra's Spitfire
1 [SOI:28] Nahiri's Machinations
1 [GTC:215] Boros Reckoner
1 [OGW:105] Cinder Hellion
1 [M13:148] Slumbering Dragon
1 [M12:133] Flameblast Dragon
1 [CHK:40] Reciprocate
2 [ODY:193] Firebolt
1 [DKA:93] Hellrider
1 [ZEN:127] Goblin Ruinblaster
1 [FUT:115] Ghostfire
1 [M10:34] Soul Warden
1 [HOU:104] Neheb, the Eternal
1 [HOU:103] Manticore Eternal
1 [HOU:92] Firebrand Archer
1 [AVR:141] Hound of Griselbrand
1 [ONS:189] Blistering Firecat
1 [VIS:125] Zhalfirin Crusader
1 [RAV:243] Boros Recruit
1 [ROE:15] Caravan Escort
1 [C14:40] Volcanic Offering
1 [SOI:190] Village Messenger
1 [KTK:118] Monastery Swiftspear
1 [C15:28] Meteor Blast
1 [KTK:11] Firehoof Cavalry
12 [DOM:250] Plains
1 [DIS:10] Guardian of the Guildpact
1 [MMQ:53] Thermal Glider
1 [HOU:20] Sandblast
1 [DKA:84] Burning Oil
1 [TSB:72] Wildfire Emissary
1 [KLD:236] Snare Thopter
1 [DTK:134] Draconic Roar
1 [2ED:245] Gauntlet of Might
1 [ONS:199] Dwarven Blastminer
LAYOUT MAIN:(1,8)(CARD_TYPE,false,50)|([KLD:236])([M13:200],[RAV:255],[2ED:245])([BNG:108])([M15:35],[C16:16],[EMN:149],[KLD:130],[TSB:72],[ISD:23],[ISD:4],[LEG:133],[ZEN:127],[HOU:104],[HOU:103],[AVR:141],[ONS:189],[RAV:243],[ROE:15],[SOI:190],[KTK:118],[MMQ:53],[ONS:199],[DKA:93],[WTH:93],[DGM:56],[INV:11],[DGM:107],[GTC:97],[USG:11],[AKH:21],[M12:133],[LEG:175],[ME4:113],[M11:129],[OGW:105],[M13:148],[M10:34],[HOU:92],[VIS:125],[EVE:139],[KTK:11],[DIS:10],[RAV:193],[GTC:215])([SOI:28])([ZEN:119],[CHK:40],[C14:40],[M11:149],[DTK:134],[8ED:200],[ZEN:142],[WWK:90],[TSP:180],[BFZ:150],[HOU:20],[FUT:115],[RAV:213],[DKA:84])([DOM:262],[DOM:250],[DOM:250],[DOM:250],[DOM:250],[KLD:246],[OGW:175],[DOM:262],[DOM:262],[DOM:262],[DOM:262],[DOM:250],[LEG:247],[DOM:262],[DOM:262],[DOM:262],[DOM:262],[DOM:250],[DOM:250],[DOM:262],[DOM:262],[3ED:296],[DOM:250],[DOM:262],[DOM:262],[DOM:262],[DOM:262],[DOM:250],[DOM:250],[DOM:250],[DOM:250],[DOM:262])([ODY:193],[XLN:145],[DTK:151],[ODY:193],[ORI:143],[ODY:200],[C15:28],[M14:139])
LAYOUT SIDEBOARD:(0,0)(CMC,true,50)|

View file

@ -0,0 +1,98 @@
1 [RAV:231] Sisters of Stone Death
1 [THS:201] Reaper of the Wilds
1 [FUT:171] Llanowar Reborn
1 [KLD:243] Blooming Marsh
1 [ALA:225] Jund Panorama
1 [MIR:12] Crypt Cobra
1 [ZEN:221] Oran-Rief, the Vastwood
1 [STH:132] Mox Diamond
1 [M15:194] Reclamation Sage
NAME:Poison
1 [M13:168] Elvish Archdruid
1 [STH:137] Volrath's Stronghold
1 [FUT:174] Dryad Arbor
1 [M15:101] Indulgent Tormentor
1 [DKA:125] Scorned Villager
9 [DOM:266] Forest
1 [USG:321] Gaea's Cradle
1 [ORI:101] Graveblade Marauder
1 [MOR:140] Wolf-Skull Shaman
1 [RTR:229] Golgari Keyrune
1 [GTC:123] Gyre Sage
1 [CON:144] Rupture Spire
1 [LRW:268] Gilt-Leaf Palace
1 [ORI:100] Gnarlroot Trapper
1 [CHK:236] Orochi Sustainer
1 [THS:153] Bow of Nylea
1 [SOM:79] Skithiryx, the Blight Dragon
1 [MBS:94] Viridian Corrupter
1 [SOM:170] Leaden Myr
1 [C13:84] Ophiomancer
1 [M13:118] Xathrid Gorgon
1 [JOU:154] Pharika, God of Affliction
1 [MBS:96] Glissa, the Traitor
1 [NPH:111] Glistener Elf
1 [MBS:90] Rot Wolf
1 [M15:183] Life's Legacy
1 [RAV:262] Golgari Signet
1 [EMN:159] Gnarlwood Dryad
1 [M12:195] Skinshifter
1 [NPH:119] Phyrexian Swarmlord
1 [DGM:26] Maze Abomination
1 [OGW:172] Holdout Settlement
1 [M14:168] Deadly Recluse
1 [OGW:171] Hissing Quagmire
1 [AER:70] Resourceful Return
1 [SOI:203] Duskwatch Recruiter
1 [M14:207] Darksteel Ingot
1 [SOI:202] Deathcap Cultivator
1 [MBS:125] Plague Myr
1 [BNG:68] Fate Unraveler
1 [BFZ:225] Pathway Arrows
1 [ODY:282] Werebear
1 [VMA:250] Deathreap Ritual
1 [MBS:121] Phyrexian Juggernaut
1 [SOM:166] Ichorclaw Myr
1 [CHK:238] Sachi, Daughter of Seshiro
1 [LRW:250] Nath of the Gilt-Leaf
1 [WWK:140] Quicksand
1 [SOM:185] Necropede
1 [SOM:140] Bladed Pinions
1 [SOM:66] Hand of the Praetors
1 [CMA:186] Meren of Clan Nel Toth
1 [SHM:273] Leechridden Swamp
1 [NPH:72] Reaper of Sheoldred
1 [MIR:136] Sabertooth Cobra
1 [RTR:243] Overgrown Tomb
1 [AER:106] Druid of the Cowl
1 [AKH:237] Throne of the God-Pharaoh
1 [AVR:107] Harvester of Souls
1 [DTK:204] Shaman of Forgotten Ways
1 [BFZ:170] Beastcaller Savant
1 [BNG:122] Graverobber Spider
1 [DTK:123] Ukud Cobra
1 [MBS:57] Virulent Wound
1 [EVE:79] Twinblade Slasher
1 [MBS:77] Blightwidow
1 [MRD:270] Viridian Longbow
1 [EVE:124] Noxious Hatchling
1 [MOR:145] Thornbite Staff
1 [ALA:71] Deathgreeter
1 [FRF:169] Jungle Hollow
1 [BOK:136] Matsu-Tribe Sniper
1 [RAV:283] Svogthos, the Restless Tomb
1 [KTK:152] Sultai Flayer
1 [RTR:198] Sluiceway Scorpion
1 [M12:81] Blood Seeker
1 [AER:117] Narnam Renegade
6 [DOM:258] Swamp
1 [LRW:219] Immaculate Magistrate
1 [EMN:175] Ulvenwald Captive
1 [THS:91] Hythonia the Cruel
1 [APC:109] Llanowar Dead
1 [MBS:145] Inkmoth Nexus
1 [BFZ:240] Mortuary Mire
1 [SOM:223] Wurmcoil Engine
1 [AKH:187] Sixth Sense
LAYOUT MAIN:(1,11)(CARD_TYPE,false,50)|([SOM:170],[MBS:121],[MBS:125],[SOM:166],[SOM:185],[SOM:223])([THS:153])([MOR:145])([RTR:229],[BFZ:225],[SOM:140],[M14:207],[STH:132],[RAV:262],[AKH:237],[MRD:270])([JOU:154],[BNG:68])([FUT:174])([RAV:231],[M15:194],[M14:168],[M15:101],[DKA:125],[ORI:101],[ORI:100],[EMN:159],[M12:195],[NPH:119],[DGM:26],[SOI:203],[SOI:202],[LRW:250],[SOM:66],[NPH:72],[NPH:111],[AER:106],[DTK:123],[EVE:79],[EVE:124],[RTR:198],[AER:117],[EMN:175],[THS:91],[AVR:107],[THS:201],[ALA:71],[MIR:12],[MOR:140],[GTC:123],[CHK:236],[SOM:79],[MBS:94],[C13:84],[M13:118],[MBS:96],[MBS:90],[CMA:186],[M13:168],[CHK:238],[ODY:282],[MIR:136],[DTK:204],[BFZ:170],[BNG:122],[MBS:77],[BOK:136],[KTK:152],[M12:81],[LRW:219],[APC:109])([VMA:250],[AKH:187])([MBS:57])([KLD:243],[ZEN:221],[DOM:266],[DOM:266],[DOM:258],[DOM:258],[USG:321],[LRW:268],[RTR:243],[OGW:172],[OGW:171],[FUT:171],[DOM:266],[DOM:266],[DOM:266],[DOM:266],[DOM:266],[DOM:258],[WWK:140],[FRF:169],[MBS:145],[BFZ:240],[ALA:225],[DOM:258],[DOM:266],[STH:137],[SHM:273],[DOM:258],[DOM:258],[CON:144],[DOM:266],[RAV:283])([M15:183],[AER:70])
LAYOUT SIDEBOARD:(0,0)(CMC,true,50)|

View file

@ -0,0 +1,118 @@
NAME:Zombi & Skeleton
1 [FUT:171] Llanowar Reborn
1 [LGN:77] Noxious Ghoul
1 [M12:116] Vengeful Pharaoh
1 [E01:36] Overseer of the Damned
1 [TSP:135] Sudden Spoiling
1 [DKA:70] Mikaeus, the Unhallowed
1 [ZEN:108] Quest for the Gravelord
1 [KTK:73] Grim Haruspex
1 [MRD:285] Tree of Tales
1 [RAV:238] Vulturous Zombie
1 [LRW:265] Wanderer's Twig
1 [7ED:166] Stronghold Assassin
1 [BFZ:234] Canopy Vista
1 [C16:21] Benefactor's Draught
1 [MMQ:129] Dark Ritual
1 [MBS:50] Phyrexian Crusader
1 [6ED:162] Zombie Master
1 [CMD:227] Skullbriar, the Walking Grave
1 [EVE:180] Twilight Mire
1 [ISD:26] Paraselene
1 [DKA:63] Geralf's Messenger
1 [RTR:213] Deathrite Shaman
1 [DKA:64] Gravecrawler
1 [AKH:247] Scattered Groves
1 [LGN:80] Skinthinner
1 [SHM:279] Sapseep Forest
1 [AKH:91] Festering Mummy
1 [SCG:62] Consumptive Goo
1 [TSB:52] Undead Warchief
1 [AKH:99] Lord of the Accursed
1 [KTK:248] Windswept Heath
1 [SHM:273] Leechridden Swamp
1 [APC:86] Strength of Night
1 [DOM:241] Isolated Chapel
1 [AER:109] Heroic Intervention
2 [DOM:248] Woodland Cemetery
1 [MIR:296] Grasslands
1 [SOI:216] Loam Dryad
1 [SOM:63] Fume Spitter
1 [SOI:212] Inexorable Blob
1 [AKH:81] Bone Picker
1 [THS:89] Gray Merchant of Asphodel
1 [JUD:141] Krosan Verge
1 [TSP:206] Molder
1 [CSP:71] Stromgald Crusader
1 [CMD:98] Sewer Nemesis
1 [DOM:250] Plains
1 [M15:121] Wall of Limbs
1 [M15:111] Paragon of Open Graves
1 [ISD:170] Avacyn's Pilgrim
7 [DOM:258] Swamp
1 [SOI:107] Diregraf Colossus
1 [ROE:207] Snake Umbra
1 [ALA:70] Death Baron
1 [NPH:68] Phyrexian Obliterator
1 [OGW:26] Make a Stand
1 [EVE:117] Creakwood Liege
1 [EVE:119] Desecrator Hag
1 [ONS:312] Barren Moor
1 [HOU:171] Desert of the Glorified
1 [M11:229] Terramorphic Expanse
1 [AER:173] Renegade Map
1 [ALA:221] Bant Panorama
1 [CHK:122] Kokusho, the Evening Star
1 [AKH:6] Binding Mummy
1 [MIR:11] Choking Sands
1 [3ED:298] Scrubland
1 [WTH:152] Mana Web
4 [DOM:266] Forest
1 [PLC:145] Essence Warden
1 [ONS:164] Rotlung Reanimator
1 [TOR:78] Rancid Earth
1 [GTC:242] Godless Shrine
1 [ONS:324] Secluded Steppe
1 [ONS:326] Tranquil Thicket
1 [SOM:78] Skinrender
1 [ONS:327] Unholy Grotto
1 [MBS:96] Glissa, the Traitor
1 [3ED:283] Bayou
1 [10E:155] Lord of the Undead
1 [SHM:281] Wooded Bastion
1 [AKH:208] Wayward Servant
1 [4ED:299] Black Vise
1 [DTK:116] Risen Executioner
1 [JOU:120] Desecration Plague
1 [ODY:282] Werebear
1 [ROE:131] Virulent Swipe
1 [CMA:66] Scourge of Nel Toth
1 [SOK:69] Ghost-Lit Stalker
1 [RTR:174] Jarad, Golgari Lich Lord
1 [EMN:90] Graf Harvest
1 [JUD:72] Stitch Together
1 [3ED:274] Sol Ring
1 [GTC:182] Obzedat, Ghost Council
1 [TOR:51] Cabal Ritual
1 [EMN:89] Gavony Unhallowed
1 [BFZ:210] Drana's Emissary
1 [ISD:124] Victim of Night
1 [M13:92] Duty-Bound Dead
1 [SHM:229] Kitchen Finks
1 [TOR:57] Chainer's Edict
1 [PLC:127] Evolution Charm
1 [M14:195] Scavenging Ooze
1 [DKA:158] Vault of the Archangel
1 [M12:81] Blood Seeker
1 [DKA:80] Zombie Apocalypse
1 [DGM:132] Ready // Willing
1 [M14:103] Liliana's Reaver
1 [RTR:158] Dreg Mangler
1 [APC:109] Llanowar Dead
1 [M12:86] Cemetery Reaper
1 [NPH:25] Suture Priest
1 [AKH:104] Plague Belcher
1 [MRD:278] Ancient Den
1 [DTK:172] Ainok Survivalist
LAYOUT MAIN:(1,7)(CARD_TYPE,false,50)|([MRD:278],[MRD:285])([LRW:265],[4ED:299],[AER:173],[WTH:152],[3ED:274])([EVE:119],[LGN:77],[M12:116],[SHM:229],[M14:103],[THS:89],[DKA:70],[RTR:174],[RAV:238],[10E:155],[MBS:50],[CMD:227],[RTR:158],[DKA:63],[RTR:213],[DKA:64],[LGN:80],[7ED:166],[AKH:91],[SCG:62],[KTK:73],[TSB:52],[AKH:99],[SOI:216],[SOM:63],[SOI:212],[AKH:81],[M14:195],[CSP:71],[CMD:98],[M15:121],[M15:111],[6ED:162],[ISD:170],[SOI:107],[ALA:70],[NPH:68],[SOM:78],[SOK:69],[CHK:122],[AKH:6],[EVE:117],[ONS:164],[MBS:96],[E01:36],[M12:81],[AKH:208],[DTK:116],[PLC:145],[ODY:282],[EMN:89],[BFZ:210],[M13:92],[CMA:66],[GTC:182],[APC:109],[M12:86],[NPH:25],[AKH:104],[DTK:172])([ZEN:108],[ROE:207],[EMN:90])([C16:21],[MMQ:129],[TSP:135],[APC:86],[TOR:51],[AER:109],[TSP:206],[OGW:26],[ROE:131],[ISD:124],[PLC:127],[DGM:132])([M11:229],[DOM:258],[DOM:258],[DOM:258],[BFZ:234],[DOM:266],[AKH:247],[SHM:279],[DOM:266],[KTK:248],[FUT:171],[DOM:258],[MIR:296],[DOM:266],[JUD:141],[ONS:312],[HOU:171],[DOM:250],[DOM:258],[GTC:242],[ONS:324],[ONS:326],[ONS:327],[3ED:283],[SHM:273],[DOM:258],[ALA:221],[DOM:241],[DOM:258],[DOM:248],[DOM:248],[3ED:298],[EVE:180],[DOM:266],[SHM:281],[DKA:158])([JUD:72],[ISD:26],[TOR:57],[MIR:11],[TOR:78],[JOU:120],[DKA:80])
LAYOUT SIDEBOARD:(0,0)(CMC,true,50)|

View file

@ -6,12 +6,7 @@ import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@ -400,10 +395,10 @@ public class MageActionCallback implements ActionCallback {
private void handlePopup(TransferData transferData) {
MageCard mageCard = (MageCard) transferData.component;
if (!popupTextWindowOpen
|| mageCard.getOriginal().getId() != bigCard.getCardId()) {
|| !Objects.equals(mageCard.getOriginal().getId(), bigCard.getCardId())) {
if (bigCard.getWidth() > 0) {
synchronized (MageActionCallback.class) {
if (!popupTextWindowOpen || mageCard.getOriginal().getId() != bigCard.getCardId()) {
if (!popupTextWindowOpen || !Objects.equals(mageCard.getOriginal().getId(), bigCard.getCardId())) {
if (!popupTextWindowOpen) {
bigCard.resetCardId();
}

View file

@ -195,7 +195,6 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("DDS");
supportedSets.add("W17");
supportedSets.add("AKH");
supportedSets.add("MPS");
supportedSets.add("CMA");
supportedSets.add("E01");
supportedSets.add("HOU");

View file

@ -84,7 +84,7 @@ public class CardDownloadData {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
if (!getClass().equals(obj.getClass())) {
return false;
}
final CardDownloadData other = (CardDownloadData) obj;
@ -134,6 +134,10 @@ public class CardDownloadData {
return CardUtil.parseCardNumberAsInt(collectorId);
}
public String getCollectorIdPostfix() {
return getCollectorId().replaceAll(getCollectorIdAsInt().toString(), "");
}
public boolean isCollectorIdWithStr() {
// card have special numbers like "103a", "180b" (scryfall style)
return !getCollectorId().equals(getCollectorIdAsInt().toString());

View file

@ -84,6 +84,7 @@
|Generate|EMBLEM:M14|Garruk, Caller of Beasts||Emblem Garruk|GarrukCallerOfBeastsEmblem|
|Generate|EMBLEM:M14|Liliana of the Dark Realms||Emblem Liliana|LilianaOfTheDarkRealmsEmblem|
|Generate|EMBLEM:MMA|Elspeth, Knight Errant||Emblem Elspeth|ElspethKnightErrantEmblem|
|Generate|EMBLEM:SWS|Obi-Wan Kenobi||Emblem Obi-Wan Kenobi|ObiWanKenobiEmblem|
|Generate|EMBLEM:RIX|Huatli, Radiant Champion||Emblem Huatli|HuatliRadiantChampionEmblem|
|Generate|PLANE:PCA|Plane - Academy At Tolaria West|||AcademyAtTolariaWestPlane|
|Generate|PLANE:PCA|Plane - Agyrem|||AgyremPlane|
@ -1031,6 +1032,16 @@
|Generate|TOK:STH|Rat|||RatToken|
|Generate|TOK:STH|Sliver|||SliversmithToken|
|Generate|TOK:STH|Spike|||SpikeToken|
|Generate|TOK:SWS|Ewok|||EwokToken|
|Generate|TOK:SWS|B-Wing|||RebelStarshipToken|
|Generate|TOK:SWS|Hunter|||HunterToken|
|Generate|TOK:SWS|TIE Fighter|||TIEFighterToken|
|Generate|TOK:SWS|Trooper|||TrooperToken|
|Generate|TOK:SWS|AT-AT|||ATATToken|
|Generate|TOK:SWS|Rebel|||RebelToken|
|Generate|TOK:SWS|Royal Guard|||RoyalGuardToken|
|Generate|TOK:SWS|Tusken Raider|||TuskenRaiderToken|
|Generate|TOK:SWS|Droid|||DroidToken|
|Generate|TOK:THS|Bird|||SwanSongBirdToken|
|Generate|TOK:THS|Boar|||CurseOfTheSwineBoarToken|
|Generate|TOK:THS|Cleric|||HeliodGodOfTheSunToken|

View file

@ -37,10 +37,8 @@ import java.awt.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.*;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
@ -84,15 +82,15 @@ public class ConnectDialog extends JDialog {
}
private void showProxySettings() {
if (cbProxyType.getSelectedItem() == Connection.ProxyType.SOCKS) {
if (Objects.equals(cbProxyType.getSelectedItem(), ProxyType.SOCKS)) {
this.pnlProxy.setVisible(true);
this.pnlProxyAuth.setVisible(false);
this.pnlProxySettings.setVisible(true);
} else if (cbProxyType.getSelectedItem() == Connection.ProxyType.HTTP) {
} else if (Objects.equals(cbProxyType.getSelectedItem(), ProxyType.HTTP)) {
this.pnlProxy.setVisible(true);
this.pnlProxyAuth.setVisible(true);
this.pnlProxySettings.setVisible(true);
} else if (cbProxyType.getSelectedItem() == Connection.ProxyType.NONE) {
} else if (Objects.equals(cbProxyType.getSelectedItem(), ProxyType.NONE)) {
this.pnlProxy.setVisible(false);
this.pnlProxyAuth.setVisible(false);
this.pnlProxySettings.setVisible(false);

View file

@ -74,12 +74,12 @@ public class Brawl extends Constructed {
}
}
}
banned.add("Attune with Aether"); // since 2008-01-15
banned.add("Attune with Aether"); // since 2018-01-15
banned.add("Aetherworks Marvel");
banned.add("Felidar Guardian");
banned.add("Rampaging Ferocidon"); // since 2008-01-15
banned.add("Ramunap Ruins"); // since 2008-01-15
banned.add("Rogue Refiner"); // since 2008-01-15
banned.add("Rampaging Ferocidon"); // since 2018-01-15
banned.add("Ramunap Ruins"); // since 2018-01-15
banned.add("Rogue Refiner"); // since 2018-01-15
banned.add("Smuggler's Copter");
}

View file

@ -72,12 +72,12 @@ public class Standard extends Constructed {
}
}
}
banned.add("Attune with Aether"); // since 2008-01-15
banned.add("Attune with Aether"); // since 2018-01-15
banned.add("Aetherworks Marvel");
banned.add("Felidar Guardian");
banned.add("Rampaging Ferocidon"); // since 2008-01-15
banned.add("Ramunap Ruins"); // since 2008-01-15
banned.add("Rogue Refiner"); // since 2008-01-15
banned.add("Rampaging Ferocidon"); // since 2018-01-15
banned.add("Ramunap Ruins"); // since 2018-01-15
banned.add("Rogue Refiner"); // since 2018-01-15
banned.add("Smuggler's Copter");
}

View file

@ -28,17 +28,7 @@
package mage.player.ai;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@ -528,7 +518,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
do {
sim.getPlayer(nextPlayerId).pass(game);
nextPlayerId = sim.getPlayerList().getNext();
} while (nextPlayerId != this.getId());
} while (!Objects.equals(nextPlayerId, this.getId()));
}
SimulationNode2 newNode = new SimulationNode2(node, sim, action, depth, currentPlayer.getId());
sim.checkStateAndTriggered();

View file

@ -148,13 +148,23 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (log.isDebugEnabled()) {
log.debug("chooseTarget: " + outcome.toString() + ':' + target.toString());
}
// sometimes a target selection can be made from a player that does not control the ability
UUID abilityControllerId = playerId;
if (target.getTargetController() != null
&& target.getAbilityController() != null) {
abilityControllerId = target.getAbilityController();
}
UUID randomOpponentId = getRandomOpponent(abilityControllerId, game);
UUID randomOpponentId;
if (target.getTargetController() != null) {
randomOpponentId = getRandomOpponent(target.getTargetController(), game);;
} else if (abilityControllerId != null) {
randomOpponentId = getRandomOpponent(abilityControllerId, game);
} else {
randomOpponentId = getRandomOpponent(playerId, game);
}
if (target.getOriginalTarget() instanceof TargetPlayer) {
return setTargetPlayer(outcome, target, null, sourceId, abilityControllerId, randomOpponentId, game);
}
@ -438,7 +448,16 @@ public class ComputerPlayer extends PlayerImpl implements Player {
if (target.getAbilityController() != null) {
abilityControllerId = target.getAbilityController();
}
UUID randomOpponentId = getRandomOpponent(abilityControllerId, game);
UUID randomOpponentId;
if (target.getTargetController() != null) {
randomOpponentId = getRandomOpponent(target.getTargetController(), game);;
} else if (source != null && source.getControllerId() != null) {
randomOpponentId = getRandomOpponent(source.getControllerId(), game);
} else {
randomOpponentId = getRandomOpponent(playerId, game);
}
if (target.getOriginalTarget() instanceof TargetPlayer) {
return setTargetPlayer(outcome, target, source, source.getSourceId(), abilityControllerId, randomOpponentId, game);
}
@ -2482,4 +2501,22 @@ public class ComputerPlayer extends PlayerImpl implements Player {
}
return randomOpponentId;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Player obj = (Player) o;
if (this.getId() == null || obj.getId() == null) {
return false;
}
return this.getId().equals(obj.getId());
}
}

View file

@ -823,7 +823,7 @@ public class HumanPlayer extends PlayerImpl {
}
}
} else if (passedUntilStackResolved) {
if (dateLastAddedToStack == game.getStack().getDateLastAdded()) {
if (Objects.equals(dateLastAddedToStack, game.getStack().getDateLastAdded())) {
dateLastAddedToStack = game.getStack().getDateLastAdded();
if (passWithManaPoolCheck(game)) {
return false;

View file

@ -106,17 +106,12 @@ class AliFromCairoReplacementEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
// 10/1/2008: The ability doesn't change how much damage is dealt;
// it just changes how much life that damage makes you lose.
// An effect such as Spirit Link will see the full amount of damage being dealt.
game.fireEvent(event);
if (controller != null) {
controller.setLife(1, game, source);
// 10/1/2008: The ability doesn't change how much damage is dealt;
// it just changes how much life that damage makes you lose.
// An effect such as Spirit Link will see the full amount of damage being dealt.
event.setAmount(controller.getLife() - 1);
}
return true;
return false;
}
}

View file

@ -112,7 +112,7 @@ class BatheInLightEffect extends OneShotEffect {
game.addEffect(effect, source);
ObjectColor color = target.getColor(game);
for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
if (permanent != target && permanent.getColor(game).shares(color)) {
if (!permanent.getId().equals(target.getId()) && permanent.getColor(game).shares(color)) {
game.getState().setValue(permanent.getId() + "_color", colorChoice.getColor());
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);

View file

@ -44,6 +44,7 @@ import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.Objects;
import java.util.UUID;
/**
@ -122,7 +123,7 @@ class BrandOfIllOmenEffect extends ContinuousRuleModifyingEffectImpl {
Permanent brand = game.getPermanent(source.getSourceId());
if (brand != null && brand.getAttachedTo() != null) {
UUID enchantedController = game.getPermanent(brand.getAttachedTo()).getControllerId();
if(enchantedController == event.getPlayerId() && game.getObject(event.getSourceId()).isCreature()) {
if(Objects.equals(enchantedController, event.getPlayerId()) && game.getObject(event.getSourceId()).isCreature()) {
return true;
}
}

View file

@ -28,6 +28,7 @@
package mage.cards.d;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
@ -158,7 +159,7 @@ class TargetControlledSource extends TargetSource {
int count = 0;
for (StackObject stackObject: game.getStack()) {
if (game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
&& stackObject.getControllerId() == sourceControllerId) {
&& Objects.equals(stackObject.getControllerId(), sourceControllerId)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
@ -166,7 +167,7 @@ class TargetControlledSource extends TargetSource {
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(sourceControllerId, game)) {
if (permanent.getControllerId() == sourceControllerId) {
if (Objects.equals(permanent.getControllerId(), sourceControllerId)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
@ -174,7 +175,7 @@ class TargetControlledSource extends TargetSource {
}
}
for (Player player : game.getPlayers().values()) {
if (player == game.getPlayer(sourceControllerId)) {
if (Objects.equals(player, game.getPlayer(sourceControllerId))) {
for (Card card : player.getGraveyard().getCards(game)) {
count++;
if (count >= this.minNumberOfTargets) {
@ -183,7 +184,7 @@ class TargetControlledSource extends TargetSource {
}
// 108.4a If anything asks for the controller of a card that doesnt have one (because its not a permanent or spell), use its owner instead.
for (Card card : game.getExile().getAllCards(game)) {
if (card.getOwnerId() == sourceControllerId) {
if (Objects.equals(card.getOwnerId(), sourceControllerId)) {
count++;
if (count >= this.minNumberOfTargets) {
return true;
@ -200,23 +201,23 @@ class TargetControlledSource extends TargetSource {
Set<UUID> possibleTargets = new HashSet<>();
for (StackObject stackObject: game.getStack()) {
if (game.getState().getPlayersInRange(sourceControllerId, game).contains(stackObject.getControllerId())
&& stackObject.getControllerId() == sourceControllerId) {
&& Objects.equals(stackObject.getControllerId(), sourceControllerId)) {
possibleTargets.add(stackObject.getId());
}
}
for (Permanent permanent: game.getBattlefield().getActivePermanents(sourceControllerId, game)) {
if (permanent.getControllerId() == sourceControllerId) {
if (Objects.equals(permanent.getControllerId(), sourceControllerId)) {
possibleTargets.add(permanent.getId());
}
}
for (Player player : game.getPlayers().values()) {
if (player == game.getPlayer(sourceControllerId)) {
if (Objects.equals(player, game.getPlayer(sourceControllerId))) {
for (Card card : player.getGraveyard().getCards(game)) {
possibleTargets.add(card.getId());
}
// 108.4a If anything asks for the controller of a card that doesnt have one (because its not a permanent or spell), use its owner instead.
for (Card card : game.getExile().getAllCards(game)) {
if (card.getOwnerId() == sourceControllerId) {
if (Objects.equals(card.getOwnerId(), sourceControllerId)) {
possibleTargets.add(card.getId());
}
}

View file

@ -0,0 +1,183 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.d;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbility;
import mage.abilities.costs.mana.ManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AbilityType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.permanent.PermanentInListPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.ManaPoolItem;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
/**
*
* @author L_J
*/
public class DrainPower extends CardImpl {
public DrainPower(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{U}");
// Target player activates a mana ability of each land they control. Then that player loses all unspent mana and you add the mana lost this way.
this.getSpellAbility().addEffect(new DrainPowerEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
public DrainPower(final DrainPower card) {
super(card);
}
@Override
public DrainPower copy() {
return new DrainPower(this);
}
}
class DrainPowerEffect extends OneShotEffect {
private static final FilterLandPermanent filter = new FilterLandPermanent();
public DrainPowerEffect() {
super(Outcome.PutManaInPool);
this.staticText = "Target player activates a mana ability of each land they control. Then that player loses all unspent mana and you add the mana lost this way";
}
public DrainPowerEffect(final DrainPowerEffect effect) {
super(effect);
}
@Override
public DrainPowerEffect copy() {
return new DrainPowerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) {
List<Permanent> ignorePermanents = new ArrayList<>();
TargetPermanent target = null;
while (true) {
Map<Permanent, List<ActivatedManaAbilityImpl>> manaAbilitiesMap = new HashMap<>();
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, targetPlayer.getId(), game)) {
if (!ignorePermanents.contains(permanent)) {
List<ActivatedManaAbilityImpl> manaAbilities = new ArrayList<>();
abilitySearch:
for (Ability ability : permanent.getAbilities()) {
if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) {
ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability;
// TODO: make Rhystic Cave untappable due to its instant speed limitation (this is a Rhystic Cave canActivate bug)
if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game)) {
// canActivate can't check for mana abilities that require a mana cost, if the payment isn't possible (Cabal Coffers etc)
// so it's necessary to filter them out manually - might be buggy in some fringe cases
for (ManaCost manaCost : manaAbility.getManaCosts()) {
if (!targetPlayer.getManaPool().getMana().includesMana(manaCost.getMana())) {
continue abilitySearch;
}
}
manaAbilities.add(manaAbility);
}
}
}
if (!manaAbilities.isEmpty()) {
manaAbilitiesMap.put(permanent, manaAbilities);
}
}
}
if (manaAbilitiesMap.isEmpty()) {
break;
}
List<Permanent> permList = new ArrayList<>(manaAbilitiesMap.keySet());
Permanent permanent;
if (permList.size() > 1 || target != null) {
FilterLandPermanent filter2 = new FilterLandPermanent("land you control to tap for mana (remaining: " + permList.size() + ')');
filter2.add(new PermanentInListPredicate(permList));
target = new TargetPermanent(1, 1, filter2, true);
while (!target.isChosen() && target.canChoose(targetPlayer.getId(), game) && targetPlayer.canRespond()) {
targetPlayer.chooseTarget(Outcome.Neutral, target, source, game);
}
permanent = game.getPermanent(target.getFirstTarget());
} else {
permanent = permList.get(0);
}
if (permanent != null) {
int i = 0;
for (ActivatedManaAbilityImpl manaAbility : manaAbilitiesMap.get(permanent)) {
i++;
if (manaAbilitiesMap.get(permanent).size() <= i
|| targetPlayer.chooseUse(Outcome.Neutral, "Activate mana ability \"" + manaAbility.getRule() + "\" of " + permanent.getLogName()
+ "? (Choose \"no\" to activate next mana ability)", source, game)) {
boolean originalCanUndo = manaAbility.isUndoPossible();
manaAbility.setUndoPossible(false); // prevents being able to undo Drain Power
if (targetPlayer.activateAbility(manaAbility, game)) {
ignorePermanents.add(permanent);
}
manaAbility.setUndoPossible(originalCanUndo); // resets undoPossible to its original state
break;
}
}
}
}
// 106.12. One card (Drain Power) causes one player to lose unspent mana and another to add the mana lost this way. (Note that these may be the same player.)
// This empties the former players mana pool and causes the mana emptied this way to be put into the latter players mana pool. Which permanents, spells, and/or
// abilities produced that mana are unchanged, as are any restrictions or additional effects associated with any of that mana.
// TODO: retain riders associated with drained mana
List<ManaPoolItem> manaItems = targetPlayer.getManaPool().getManaItems();
targetPlayer.getManaPool().emptyPool(game);
for (ManaPoolItem manaPoolItem : manaItems) {
controller.getManaPool().addMana(
manaPoolItem.isConditional() ? manaPoolItem.getConditionalMana() : manaPoolItem.getMana(),
game, source, Duration.EndOfTurn.equals(manaPoolItem.getDuration()));
}
return true;
}
return false;
}
}

View file

@ -34,7 +34,6 @@ import mage.abilities.Mode;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.keyword.FlashbackAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
@ -99,7 +98,7 @@ class ElderwoodScionCostReductionEffect extends CostModificationEffectImpl {
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (abilityToModify instanceof SpellAbility || abilityToModify instanceof FlashbackAbility) {
if (abilityToModify instanceof SpellAbility) {
if (abilityToModify.getControllerId().equals(source.getControllerId())) {
for (UUID modeId : abilityToModify.getModes().getSelectedModes()) {
Mode mode = abilityToModify.getModes().get(modeId);
@ -125,7 +124,7 @@ class ElderwoodScionCostReductionEffect extends CostModificationEffectImpl {
class ElderwoodScionCostReductionEffect2 extends CostModificationEffectImpl {
private static final String effectText = "Spells your opponents cast that target Elderwood Scion cost {2} more to cast";
private static final String effectText = "Spells your opponents cast that target {this} cost {2} more to cast";
ElderwoodScionCostReductionEffect2() {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.INCREASE_COST);
@ -145,7 +144,7 @@ class ElderwoodScionCostReductionEffect2 extends CostModificationEffectImpl {
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (abilityToModify.getAbilityType() == AbilityType.ACTIVATED) {
if (abilityToModify instanceof SpellAbility) {
if (game.getOpponents(source.getControllerId()).contains(abilityToModify.getControllerId())) {
for (Target target : abilityToModify.getTargets()) {
for (UUID targetUUID : target.getTargets()) {

View file

@ -123,7 +123,7 @@ class EyeForAnEyeEffect extends ReplacementEffectImpl {
Player controller = game.getPlayer(source.getControllerId());
DamageEvent damageEvent = (DamageEvent) event;
if (controller != null) {
if (controller.getId() == damageEvent.getTargetId() && damageEvent.getSourceId().equals(damageSource.getFirstTarget())) {
if (controller.getId().equals(damageEvent.getTargetId()) && damageEvent.getSourceId().equals(damageSource.getFirstTarget())) {
this.discard();
return true;
}

View file

@ -92,7 +92,7 @@ enum ActivePlayerMostLandsCondition implements Condition {
return false;
}
for (UUID playerId : game.getPlayerList()) {
if (playerId != activePlayer.getId()) {
if (!playerId.equals(activePlayer.getId())) {
if (game.getBattlefield().getAllActivePermanents(filter, playerId, game).size() >= landCount) {
return false;
}

View file

@ -27,6 +27,7 @@
*/
package mage.cards.h;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
@ -45,8 +46,6 @@ import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author Saga
@ -54,14 +53,14 @@ import java.util.UUID;
public class HeraldsHorn extends CardImpl {
public HeraldsHorn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// As Herald's Horn enters the battlefield, choose a creature type.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature)));
// Creature spells you cast of the chosen type cost {1} less to cast.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new SpellsCostReductionAllOfChosenSubtypeEffect(new FilterCreatureCard("Creature spells you cast of the chosen type"), 1)));
new SpellsCostReductionAllOfChosenSubtypeEffect(new FilterCreatureCard("Creature spells you cast of the chosen type"), 1, true)));
// At the beginning of your upkeep, look at the top card of your library. If it's a creature card of the chosen type, you may reveal it and put it into your hand.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new HeraldsHornEffect(), TargetController.YOU, false));
@ -110,8 +109,8 @@ class HeraldsHornEffect extends OneShotEffect {
String message = "Reveal the top card of your library and put that card into your hand?";
if (card != null) {
if (filter.match(card, game) && controller.chooseUse(Outcome.Benefit, message, source, game)) {
controller.moveCards(card, Zone.HAND, source, game);
controller.revealCards(sourceObject.getIdName() + " put into hand", cards, game);
controller.moveCards(card, Zone.HAND, source, game);
controller.revealCards(sourceObject.getIdName() + " put into hand", cards, game);
}
}
}

View file

@ -94,7 +94,7 @@ class HiredGiantEffect extends OneShotEffect {
if (controller != null) {
Set<Player> playersThatSearched = new HashSet<>(1);
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
if (playerId != controller.getId()) {
if (!playerId.equals(controller.getId())) {
Player player = game.getPlayer(playerId);
if (player != null && player.chooseUse(Outcome.PutCreatureInPlay, "Search your library for a land card and put it onto the battlefield?", source, game)) {
TargetCardInLibrary target = new TargetCardInLibrary(new FilterLandCard());

View file

@ -0,0 +1,296 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.i;
import java.util.UUID;
import mage.ConditionalMana;
import mage.Mana;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.AsThoughEffect;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
*
* @author L_J (based on jeffwadsworth)
*/
public class IceCauldron extends CardImpl {
public IceCauldron(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// {X}, {T}: Put a charge counter on Ice Cauldron and exile a nonland card from your hand. You may cast that card for as long as it remains exiled. Note the type and amount of mana spent to pay this activation cost. Activate this ability only if there are no charge counters on Ice Cauldron.
ConditionalActivatedAbility ability = new ConditionalActivatedAbility(
Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.CHARGE.createInstance(), true), new ManaCostsImpl("{X}"), new SourceHasCounterCondition(CounterType.CHARGE, 0, 0));
ability.addEffect(new IceCauldronExileEffect());
ability.addEffect(new IceCauldronNoteManaEffect());
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {T}, Remove a charge counter from Ice Cauldron: Add Ice Cauldron's last noted type and amount of mana to your mana pool. Spend this mana only to cast the last card exiled with Ice Cauldron.
Ability ability2 = new SimpleManaAbility(Zone.BATTLEFIELD, new IceCauldronAddManaEffect(), new TapSourceCost());
ability2.addCost(new RemoveCountersSourceCost(CounterType.CHARGE.createInstance()));
this.addAbility(ability2);
}
public IceCauldron(final IceCauldron card) {
super(card);
}
@Override
public IceCauldron copy() {
return new IceCauldron(this);
}
}
class IceCauldronExileEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("nonland card");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
}
public IceCauldronExileEffect() {
super(Outcome.Benefit);
this.staticText = "and exile a nonland card from your hand. You may cast that card for as long as it remains exiled";
}
public IceCauldronExileEffect(final IceCauldronExileEffect effect) {
super(effect);
}
@Override
public IceCauldronExileEffect copy() {
return new IceCauldronExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && sourcePermanent != null) {
if (controller.getHand().isEmpty()) {
return true;
}
TargetCard target = new TargetCard(Zone.HAND, filter);
target.setNotTarget(true);
Card chosenCard = null;
if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) {
chosenCard = controller.getHand().get(target.getFirstTarget(), game);
}
if (chosenCard != null) {
controller.moveCardToExileWithInfo(chosenCard, source.getSourceId(), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.HAND, true);
AsThoughEffect effect = new IceCauldronCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(chosenCard.getId()));
game.addEffect(effect, source);
game.getState().setValue("IceCauldronCard" + source.getSourceId().toString(), new MageObjectReference(chosenCard.getId(), game)); //store the exiled card
return true;
}
}
return false;
}
}
class IceCauldronCastFromExileEffect extends AsThoughEffectImpl {
IceCauldronCastFromExileEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.Custom, Outcome.Benefit);
staticText = "You may cast that card for as long as it remains exiled";
}
IceCauldronCastFromExileEffect(final IceCauldronCastFromExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public IceCauldronCastFromExileEffect copy() {
return new IceCauldronCastFromExileEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (targetPointer.getTargets(game, source).contains(objectId)
&& game.getState().getZone(objectId) == Zone.EXILED) {
Player player = game.getPlayer(source.getControllerId());
Card card = game.getCard(objectId);
if (player != null
&& card != null) {
return true;
}
}
return false;
}
}
class IceCauldronNoteManaEffect extends OneShotEffect {
private static String manaUsedString;
public IceCauldronNoteManaEffect() {
super(Outcome.Benefit);
this.staticText = "Note the type and amount of mana spent to pay this activation cost";
}
public IceCauldronNoteManaEffect(final IceCauldronNoteManaEffect effect) {
super(effect);
}
@Override
public IceCauldronNoteManaEffect copy() {
return new IceCauldronNoteManaEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent iceCauldron = game.getPermanent(source.getSourceId());
if (controller != null && iceCauldron != null) {
game.getState().setValue("IceCauldronMana" + source.getSourceId().toString(), source.getManaCostsToPay().getUsedManaToPay()); //store the mana used to pay
manaUsedString = source.getManaCostsToPay().getUsedManaToPay().toString();
iceCauldron.addInfo("MANA USED", CardUtil.addToolTipMarkTags("Mana used last: " + manaUsedString), game);
return true;
}
return false;
}
}
class IceCauldronAddManaEffect extends ManaEffect {
private static Mana storedMana;
private static MageObjectReference exiledCardMor;
IceCauldronAddManaEffect() {
super();
staticText = "Add {this}'s last noted type and amount of mana to your mana pool. Spend this mana only to cast the last card exiled with {this}";
}
IceCauldronAddManaEffect(IceCauldronAddManaEffect effect) {
super(effect);
}
@Override
public IceCauldronAddManaEffect copy() {
return new IceCauldronAddManaEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent iceCauldron = game.getPermanent(source.getSourceId());
Player controller = game.getPlayer(source.getControllerId());
if (iceCauldron != null && controller != null) {
storedMana = (Mana) game.getState().getValue("IceCauldronMana" + source.getSourceId().toString());
exiledCardMor = (MageObjectReference) game.getState().getValue("IceCauldronCard" + source.getSourceId().toString());
if (storedMana != null) { // should be adding the mana even if exiled card is null
checkToFirePossibleEvents(storedMana, game, source);
Card card = exiledCardMor.getCard(game);
if (card == null) {
card = game.getCard(exiledCardMor.getSourceId());
if (card != null && !(card.getZoneChangeCounter(game) == exiledCardMor.getZoneChangeCounter() + 1 && game.getState().getZone(card.getId()) == Zone.STACK)) {
card = null;
}
}
IceCauldronConditionalMana iceCauldronMana = new IceCauldronConditionalMana(storedMana, card);
if (iceCauldronMana != null) {
controller.getManaPool().addMana(iceCauldronMana, game, source);
return true;
}
}
}
return false;
}
@Override
public Mana getMana(Game game, Ability source) {
return null;
}
}
class IceCauldronConditionalMana extends ConditionalMana {
public IceCauldronConditionalMana(Mana mana, Card exiledCard) {
super(mana);
staticText = "Spend this mana only to cast the last card exiled with {this}";
addCondition(new IceCauldronManaCondition(exiledCard));
}
}
class IceCauldronManaCondition implements Condition {
private static Card exiledCard;
public IceCauldronManaCondition(Card exiledCard) {
this.exiledCard = exiledCard;
}
@Override
public boolean apply(Game game, Ability source) {
if (source instanceof SpellAbility) {
Card card = game.getCard(source.getSourceId());
if (card != null && exiledCard != null && card.equals(exiledCard)) {
return true;
}
}
return false;
}
}

View file

@ -95,7 +95,7 @@ class IceCaveEffect extends OneShotEffect {
if (spellController != null) {
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null && player != spellController) {
if (player != null && !player.equals(spellController)) {
cost.clearPaid();
if (cost.canPay(source, source.getSourceId(), player.getId(), game)
&& player.chooseUse(outcome, "Pay " + cost.getText() + " to counter " + spell.getIdName() + '?', source, game)) {

View file

@ -113,7 +113,7 @@ class KazarovSengirPurebloodTriggeredAbility extends TriggeredAbilityImpl {
if (permanent == null) {
return false;
}
if (permanent.getControllerId() == this.getControllerId()) {
if (permanent.getControllerId().equals(this.getControllerId())) {
return false;
}
return true;

View file

@ -27,6 +27,7 @@
*/
package mage.cards.m;
import java.util.Objects;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
@ -165,7 +166,7 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl {
return false;
}
for (Card card : game.getExile().getAllCards(game)) {
if (filter.match(card, game) && card.getOwnerId() == perm.getControllerId()) {
if (filter.match(card, game) && Objects.equals(card.getOwnerId(), perm.getControllerId())) {
for (Ability ability : card.getAbilities()) {
if (ability instanceof ActivatedAbility) {
ActivatedAbilityImpl copyAbility = (ActivatedAbilityImpl) ability.copy();

View file

@ -33,7 +33,7 @@ import mage.abilities.effects.common.TapAllTargetPlayerControlsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.StaticFilters;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
@ -65,7 +65,7 @@ public class ManaShort extends CardImpl {
class ManaShortEffect extends TapAllTargetPlayerControlsEffect {
public ManaShortEffect() {
super(StaticFilters.FILTER_LANDS);
super(new FilterLandPermanent());
staticText = "Tap all lands target player controls and empty their mana pool";
}

View file

@ -27,6 +27,7 @@
*/
package mage.cards.m;
import java.util.Objects;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.ReplacementEffectImpl;
@ -124,7 +125,9 @@ class MirrorStrikeEffect extends ReplacementEffectImpl {
DamageEvent damageEvent = (DamageEvent) event;
Permanent targetPermanent = game.getPermanent(source.getFirstTarget());
if (controller != null && targetPermanent != null) {
return (damageEvent.isCombatDamage() && controller.getId() == damageEvent.getTargetId() && targetPermanent.getId() == damageEvent.getSourceId());
return (damageEvent.isCombatDamage()
&& Objects.equals(controller.getId(), damageEvent.getTargetId())
&& Objects.equals(targetPermanent.getId(), damageEvent.getSourceId()));
}
return false;
}

View file

@ -112,7 +112,7 @@ class MyrBattlesphereTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent source = game.getPermanent(event.getSourceId());
if (source != null && source.getId() == this.getSourceId()) {
if (source != null && source.getId().equals(this.getSourceId())) {
UUID defenderId = game.getCombat().getDefenderId(event.getSourceId());
this.getEffects().get(0).setTargetPointer(new FixedTarget(defenderId));
return true;

View file

@ -37,16 +37,13 @@ import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardsImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
@ -58,7 +55,7 @@ import mage.target.targetpointer.FixedTarget;
public class PsychicBattle extends CardImpl {
public PsychicBattle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}{U}");
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.
this.addAbility(new PsychicBattleTriggeredAbility());
@ -76,11 +73,6 @@ public class PsychicBattle extends CardImpl {
class PsychicBattleTriggeredAbility extends TriggeredAbilityImpl {
private static final FilterPermanent filter = new FilterPermanent();
static {
filter.add(new NamePredicate("Psychic Battle"));
}
public PsychicBattleTriggeredAbility() {
super(Zone.BATTLEFIELD, new PsychicBattleEffect(), false);
}
@ -103,8 +95,7 @@ class PsychicBattleTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
if (stackObject != null) {
Permanent psychicBattle = game.getPermanentOrLKIBattlefield(getSourceId());
if (psychicBattle != null && !(stackObject.isTargetChanged() && filter.match(psychicBattle, game))) {
if (!stackObject.isTargetChanged() && !stackObject.getName().equals("Psychic Battle")) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getSourceId()));
stackObject.setTargetChanged(false); // resets the targetChanged flag
return true;
@ -122,7 +113,7 @@ class PsychicBattleTriggeredAbility extends TriggeredAbilityImpl {
class PsychicBattleEffect extends OneShotEffect {
public PsychicBattleEffect() {
super(Outcome.Neutral);
super(Outcome.Benefit);
this.staticText = "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";
}

View file

@ -54,6 +54,7 @@ import mage.target.targetpointer.FixedTarget;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
@ -141,7 +142,7 @@ class RagingRiverEffect extends OneShotEffect {
for (UUID attackers : game.getCombat().getAttackers()) {
Permanent attacker = game.getPermanent(attackers);
if (attacker != null && attacker.getControllerId() == controller.getId()) {
if (attacker != null && Objects.equals(attacker.getControllerId(), controller.getId())) {
CombatGroup combatGroup = game.getCombat().findGroup(attacker.getId());
if (combatGroup != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent();

View file

@ -143,7 +143,7 @@ class DoUnlessAnyOpponentPaysEffect extends OneShotEffect {
// check if any opponent is willing to pay
for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player player = game.getPlayer(playerId);
if (player != null && player != controller && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) {
if (player != null && !player.equals(controller) && cost.canPay(source, source.getSourceId(), player.getId(), game) && player.chooseUse(Outcome.Detriment, message, source, game)) {
cost.clearPaid();
if (cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) {
if (!game.isSimulation()) {

View file

@ -33,20 +33,22 @@ import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetAnyTarget;
/**
@ -56,17 +58,15 @@ import mage.target.common.TargetAnyTarget;
public class ScourgeOfValkas extends CardImpl {
private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("{this} or another Dragon");
private final static FilterControlledCreaturePermanent filter2 = new FilterControlledCreaturePermanent("Dragons you control");
static {
filter.add(new SubtypePredicate(SubType.DRAGON));
filter2.add(new SubtypePredicate(SubType.DRAGON));
}
private static final String rule = "Whenever {this} or another Dragon enters the battlefield under your control, it deals X damage to any target, where X is the number of Dragons you control.";
public ScourgeOfValkas(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}{R}");
this.subtype.add(SubType.DRAGON);
this.color.setRed(true);
@ -77,8 +77,7 @@ public class ScourgeOfValkas extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever Scourge of Valkas or another Dragon enters the battlefield under your control, it deals X damage to any target, where X is the number of Dragons you control.
DynamicValue dragons = new PermanentsOnBattlefieldCount(filter2);
Ability ability = new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new DamageTargetEffect(dragons), filter, false, rule);
Ability ability = new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new ScourgeOfValkasDamageEffect(), filter, false, rule);
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability);
@ -96,3 +95,45 @@ public class ScourgeOfValkas extends CardImpl {
return new ScourgeOfValkas(this);
}
}
class ScourgeOfValkasDamageEffect extends OneShotEffect {
public ScourgeOfValkasDamageEffect() {
super(Outcome.Damage);
this.staticText = "it deals X damage to any target, where X is the number of Dragons you control";
}
public ScourgeOfValkasDamageEffect(final ScourgeOfValkasDamageEffect effect) {
super(effect);
}
@Override
public ScourgeOfValkasDamageEffect copy() {
return new ScourgeOfValkasDamageEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent enteringDragon = (Permanent) getValue("permanentEnteringBattlefield");
if (controller != null && enteringDragon != null) {
FilterPermanent filter = new FilterPermanent();
filter.add(new SubtypePredicate(SubType.DRAGON));
int dragons = game.getBattlefield().countAll(filter, source.getControllerId(), game);
if (dragons > 0) {
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent != null) {
permanent.damage(dragons, enteringDragon.getId(), game, false, true);
} else {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null
&& player.isInGame()) {
player.damage(dragons, enteringDragon.getId(), game, false, true);
}
}
}
return true;
}
return false;
}
}

View file

@ -153,7 +153,7 @@ class CouldAttackThisTurnWatcher extends Watcher {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(activePlayer.getId())) {
if (permanent.isCreature()) {
for (UUID defender : game.getCombat().getDefenders()) {
if (defender != activePlayer.getId()) {
if (!defender.equals(activePlayer.getId())) {
if (permanent.canAttack(defender, game)) {
// exclude Propaganda style effects
if (!game.getContinuousEffects().checkIfThereArePayCostToAttackBlockEffects(

View file

@ -35,8 +35,6 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect.FaceDownType;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.MorphAbility;
import mage.cards.Card;
@ -104,19 +102,18 @@ class ShorecrasherElementalEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent shorecrasherElemental = game.getPermanent(source.getSourceId());
MageObject sourceObject = source.getSourceObject(game);
if (shorecrasherElemental != null
&& sourceObject != null
if (controller != null && shorecrasherElemental != null && sourceObject != null
&& new MageObjectReference(sourceObject, game).refersTo(shorecrasherElemental, game)) {
if (shorecrasherElemental.moveToExile(source.getSourceId(), sourceObject.getName(), source.getSourceId(), game)) {
if (controller.moveCards(shorecrasherElemental, Zone.EXILED, source, game)) {
Card card = game.getExile().getCard(source.getSourceId(), game);
if (card != null) {
game.addEffect(new BecomesFaceDownCreatureEffect(Duration.Custom, FaceDownType.MEGAMORPHED), source);
return card.putOntoBattlefield(game, Zone.EXILED, source.getSourceId(), card.getOwnerId(), false, true);
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, true, true, null);
}
}
return true;
}
return false;
}

View file

@ -133,7 +133,7 @@ class SivvisValorEffect extends ReplacementEffectImpl {
DamageEvent damageEvent = (DamageEvent) event;
Permanent targetPermanent = game.getPermanent(source.getFirstTarget());
if (controller != null && targetPermanent != null) {
return targetPermanent.getId() == damageEvent.getTargetId();
return targetPermanent.getId().equals(damageEvent.getTargetId());
}
return false;
}

View file

@ -96,7 +96,7 @@ class GainControlAllPermanentsEffect extends ContinuousEffectImpl {
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
if (targetPlayer != null && targetPlayer.isInGame()) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (permanent != null && permanent.getId() != source.getSourceId()) {
if (permanent != null && !permanent.getId().equals(source.getSourceId())) {
permanent.changeControllerId(targetPlayer.getId(), game);
}
}

View file

@ -27,6 +27,8 @@
*/
package mage.cards.s;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
@ -38,8 +40,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
@ -113,25 +115,25 @@ class SorinLordOfInnistradEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Set<Card> toBattlefield = new HashSet<>();
for (UUID targetId : source.getTargets().get(0).getTargets()) {
Permanent perm = game.getPermanent(targetId);
if (perm != null) {
perm.destroy(source.getSourceId(), game, false);
}
}
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
for (UUID targetId : source.getTargets().get(0).getTargets()) {
if (game.getState().getZone(targetId) == Zone.GRAVEYARD) {
if (Zone.GRAVEYARD == game.getState().getZone(targetId)) {
Card card = game.getCard(targetId);
if (card != null) {
card.putOntoBattlefield(game, Zone.GRAVEYARD, source.getSourceId(), player.getId());
toBattlefield.add(card);
}
}
}
}
return true;
game.applyEffects();
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
return controller.moveCards(toBattlefield, Zone.BATTLEFIELD, source, game);
}
return false;
}
}

View file

@ -58,11 +58,9 @@ import mage.target.targetpointer.FixedTarget;
public class SovereignsOfLostAlara extends CardImpl {
public SovereignsOfLostAlara(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{W}{U}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{U}");
this.subtype.add(SubType.SPIRIT);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
@ -133,25 +131,25 @@ class SovereignsOfLostAlaraEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
Player controller = game.getPlayer(source.getControllerId());
Permanent attackingCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (you != null && attackingCreature != null) {
if (controller != null && attackingCreature != null) {
FilterCard filter = new FilterCard("aura that could enchant the lone attacking creature");
filter.add(new SubtypePredicate(SubType.AURA));
filter.add(new AuraCardCanAttachToPermanentId(attackingCreature.getId()));
if (you.chooseUse(Outcome.Benefit, "Do you want to search your library?", source, game)) {
if (controller.chooseUse(Outcome.Benefit, "Do you want to search your library?", source, game)) {
TargetCardInLibrary target = new TargetCardInLibrary(filter);
target.setNotTarget(true);
if (you.searchLibrary(target, game)) {
if (controller.searchLibrary(target, game)) {
if (target.getFirstTarget() != null) {
Card aura = game.getCard(target.getFirstTarget());
game.getState().setValue("attachTo:" + aura.getId(), attackingCreature);
aura.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), you.getId());
controller.moveCards(aura, Zone.BATTLEFIELD, source, game);
return attackingCreature.addAttachment(aura.getId(), game);
}
}
}
you.shuffleLibrary(source, game);
controller.shuffleLibrary(source, game);
}
return false;
}

View file

@ -27,6 +27,7 @@
*/
package mage.cards.s;
import java.util.Objects;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
@ -95,7 +96,7 @@ class SpiritualFocusTriggeredAbility extends TriggeredAbilityImpl {
if (game.getOpponents(this.getControllerId()).contains(stackObject.getControllerId())) {
Permanent permanent = game.getPermanent(getSourceId());
if (permanent != null) {
if (permanent.getControllerId() == event.getPlayerId()) {
if (Objects.equals(permanent.getControllerId(), event.getPlayerId())) {
return true;
}
}

View file

@ -30,6 +30,7 @@ package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BecomesTappedAttachedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.EnchantAbility;
@ -37,8 +38,8 @@ import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.Filter;
import mage.game.Game;
@ -47,6 +48,7 @@ import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -65,7 +67,8 @@ public class SteamVines extends CardImpl {
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// When enchanted land becomes tapped, destroy it and Steam Vines deals 1 damage to that land's controller. That player attaches Steam Vines to a land of their choice.
// When enchanted land becomes tapped, destroy it and Steam Vines deals 1 damage to that land's controller.
// That player attaches Steam Vines to a land of their choice.
this.addAbility(new BecomesTappedAttachedTriggeredAbility(new SteamVinesEffect(), "enchanted land"));
}
@ -98,10 +101,10 @@ class SteamVinesEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Permanent kudzu = game.getPermanentOrLKIBattlefield(source.getSourceId());
Card kudzuCard = game.getCard(source.getSourceId());
if (kudzu != null) {
Permanent enchantedLand = game.getPermanentOrLKIBattlefield(kudzu.getAttachedTo());
Permanent steamVines = game.getPermanentOrLKIBattlefield(source.getSourceId());
Card steamVinesCard = game.getCard(source.getSourceId());
if (steamVines != null) {
Permanent enchantedLand = game.getPermanentOrLKIBattlefield(steamVines.getAttachedTo());
Player controller = game.getPlayer(source.getControllerId());
if (enchantedLand != null
&& controller != null) {
@ -113,20 +116,20 @@ class SteamVinesEffect extends OneShotEffect {
if (!game.getBattlefield().getAllActivePermanents(CardType.LAND).isEmpty()) { //lands are available on the battlefield
Target target = new TargetLandPermanent();
target.setNotTarget(true); //not a target, it is chosen
if (kudzuCard != null
if (steamVinesCard != null
&& landsController != null) {
if (landsController.choose(Outcome.Detriment, target, source.getId(), game)) {
if (landsController.choose(Outcome.DestroyPermanent, target, source.getId(), game)) {
if (target.getFirstTarget() != null) {
Permanent landChosen = game.getPermanent(target.getFirstTarget());
if (landChosen != null) {
for (Target targetTest : kudzuCard.getSpellAbility().getTargets()) {
for (Target targetTest : steamVinesCard.getSpellAbility().getTargets()) {
Filter filterTest = targetTest.getFilter();
if (filterTest.match(landChosen, game)) {
if (game.getBattlefield().containsPermanent(landChosen.getId())) { //verify that it is still on the battlefield
game.getState().setValue("attachTo:" + kudzuCard.getId(), landChosen);
Zone zone = game.getState().getZone(kudzuCard.getId());
kudzuCard.putOntoBattlefield(game, zone, source.getSourceId(), controller.getId());
return landChosen.addAttachment(kudzuCard.getId(), game);
game.informPlayers(landsController.getLogName() + " attaches " + steamVines.getLogName() + " to " + landChosen.getLogName());
Effect effect = new AttachEffect(Outcome.Neutral);
effect.setTargetPointer(new FixedTarget(landChosen, game));
return effect.apply(game, source);
}
}
}

View file

@ -58,7 +58,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
public class StonehewerGiant extends CardImpl {
public StonehewerGiant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{W}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}{W}");
this.subtype.add(SubType.GIANT);
this.subtype.add(SubType.WARRIOR);
@ -102,28 +102,27 @@ class StonehewerGiantEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
FilterCard filter = new FilterCard("Equipment");
filter.add(new SubtypePredicate(SubType.EQUIPMENT));
TargetCardInLibrary target = new TargetCardInLibrary(filter);
if (player.searchLibrary(target, game)) {
Card card = player.getLibrary().getCard(target.getFirstTarget(), game);
if (controller.searchLibrary(target, game)) {
Card card = controller.getLibrary().getCard(target.getFirstTarget(), game);
if (card != null) {
card.putOntoBattlefield(game, Zone.LIBRARY, source.getSourceId(), source.getControllerId());
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
Permanent equipment = game.getPermanent(card.getId());
Target targetCreature = new TargetControlledCreaturePermanent();
if (equipment != null && player.choose(Outcome.BoostCreature, targetCreature, source.getSourceId(), game)) {
if (equipment != null && controller.choose(Outcome.BoostCreature, targetCreature, source.getSourceId(), game)) {
Permanent permanent = game.getPermanent(targetCreature.getFirstTarget());
permanent.addAttachment(equipment.getId(), game);
}
}
}
player.shuffleLibrary(source, game);
controller.shuffleLibrary(source, game);
return true;
}
}

View file

@ -117,7 +117,7 @@ public class TalonOfPain extends CardImpl {
UUID sourceControllerId = game.getControllerId(event.getSourceId());
if (sourceControllerId != null
&& sourceControllerId.equals(this.getControllerId())
&& this.getSourceId() != event.getSourceId()) {
&& !this.getSourceId().equals(event.getSourceId())) {
// return true so the effect will fire and a charge counter will be added
return true;
}

View file

@ -29,6 +29,7 @@ package mage.cards.t;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -128,7 +129,7 @@ class TidalFlatsEffect extends OneShotEffect {
if (group != null) {
for (UUID blockerId : group.getBlockers()) {
Permanent blocker = game.getPermanent(blockerId);
if (blocker != null && blocker.getControllerId() == controller.getId()) {
if (blocker != null && Objects.equals(blocker.getControllerId(), controller.getId())) {
ContinuousEffect effect = new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(blocker.getId()));
game.addEffect(effect, source);

View file

@ -90,56 +90,6 @@ public class TorgaarFamineIncarnate extends CardImpl {
}
}
//class TorgaarFamineIncarnateSacrificeCost extends CostImpl {
//
// int numbSacrificed = 0;
//
// public TorgaarFamineIncarnateSacrificeCost() {
// this.text = "sacrifice any number of creatures";
//
// }
//
// public TorgaarFamineIncarnateSacrificeCost(final TorgaarFamineIncarnateSacrificeCost cost) {
// super(cost);
// this.numbSacrificed = cost.numbSacrificed;
// }
//
// @Override
// public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
// return true;
// }
//
// @Override
// public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
// TargetControlledCreaturePermanent target
// = new TargetControlledCreaturePermanent(0, Integer.MAX_VALUE,
// new FilterControlledCreaturePermanent("select any number of creatures to sacrifice. "
// + "This spell costs {2} less to cast for each creature sacrificed this way"), true);
// Player player = game.getPlayer(controllerId);
// if (player != null) {
// player.chooseTarget(Outcome.Benefit, target, ability, game);
// for (UUID creatureId : target.getTargets()) {
// Permanent creature = game.getPermanent(creatureId);
// if (creature != null) {
// if (creature.sacrifice(sourceId, game)) {
// numbSacrificed++;
// }
// }
// }
// }
// this.paid = true;
// return paid;
// }
//
// public int getNumbSacrificed() {
// return numbSacrificed;
// }
//
// @Override
// public TorgaarFamineIncarnateSacrificeCost copy() {
// return new TorgaarFamineIncarnateSacrificeCost(this);
// }
//}
class TorgaarFamineIncarnateEffect extends OneShotEffect {
public TorgaarFamineIncarnateEffect() {

View file

@ -125,7 +125,7 @@ class TreacherousLinkEffect extends ReplacementEffectImpl {
if (controller != null && enchantment != null) {
Permanent enchantedCreature = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo());
if (enchantedCreature != null) {
return enchantedCreature.getId() == damageEvent.getTargetId();
return enchantedCreature.getId().equals(damageEvent.getTargetId());
}
}
return false;

View file

@ -83,7 +83,7 @@ class TyphoonEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
if (playerId != source.getControllerId()) {
if (!playerId.equals(source.getControllerId())) {
Player player = game.getPlayer(playerId);
if (player != null) {
int amount = 0;

View file

@ -132,7 +132,7 @@ class VoidMawEffect extends ReplacementEffectImpl {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getToZone() == Zone.GRAVEYARD) {
Permanent permanent = ((ZoneChangeEvent) event).getTarget();
if (permanent != null && permanent.getId() != source.getSourceId()) {
if (permanent != null && !permanent.getId().equals(source.getSourceId())) {
if (zEvent.getTarget() != null) { // if it comes from permanent, check if it was a creature on the battlefield
if (zEvent.getTarget().isCreature()) {
return true;

View file

@ -97,7 +97,7 @@ class WatchersOfTheDeadEffect extends OneShotEffect {
for (UUID opponentId : game.getState().getPlayersInRange(controller.getId(), game)) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null
&& opponent != controller) {
&& !opponent.equals(controller)) {
TargetCard target = new TargetCardInYourGraveyard(2, 2, new FilterCard());
target.setNotTarget(true);
Cards cardsInGraveyard = opponent.getGraveyard();

View file

@ -136,6 +136,7 @@ public class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Divine Transformation", 304, Rarity.UNCOMMON, mage.cards.d.DivineTransformation.class));
cards.add(new SetCardInfo("Dragon Engine", 366, Rarity.RARE, mage.cards.d.DragonEngine.class));
cards.add(new SetCardInfo("Drain Life", 18, Rarity.COMMON, mage.cards.d.DrainLife.class));
cards.add(new SetCardInfo("Drain Power", 82, Rarity.RARE, mage.cards.d.DrainPower.class));
cards.add(new SetCardInfo("Drudge Skeletons", 19, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class));
cards.add(new SetCardInfo("Durkwood Boars", 151, Rarity.COMMON, mage.cards.d.DurkwoodBoars.class));
cards.add(new SetCardInfo("Dust to Dust", 305, Rarity.UNCOMMON, mage.cards.d.DustToDust.class));

View file

@ -119,6 +119,7 @@ public class FourthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Control Magic", 64, Rarity.UNCOMMON, mage.cards.c.ControlMagic.class));
cards.add(new SetCardInfo("Counterspell", 65, Rarity.UNCOMMON, mage.cards.c.Counterspell.class));
cards.add(new SetCardInfo("Creature Bond", 66, Rarity.COMMON, mage.cards.c.CreatureBond.class));
cards.add(new SetCardInfo("Drain Power", 67, Rarity.RARE, mage.cards.d.DrainPower.class));
cards.add(new SetCardInfo("Energy Flux", 68, Rarity.UNCOMMON, mage.cards.e.EnergyFlux.class));
cards.add(new SetCardInfo("Energy Tap", 69, Rarity.COMMON, mage.cards.e.EnergyTap.class));
cards.add(new SetCardInfo("Erosion", 70, Rarity.COMMON, mage.cards.e.Erosion.class));

View file

@ -176,6 +176,7 @@ public class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Hyalopterous Lemure", 21, Rarity.UNCOMMON, mage.cards.h.HyalopterousLemure.class));
cards.add(new SetCardInfo("Hydroblast", 72, Rarity.COMMON, mage.cards.h.Hydroblast.class));
cards.add(new SetCardInfo("Hymn of Rebirth", 373, Rarity.UNCOMMON, mage.cards.h.HymnOfRebirth.class));
cards.add(new SetCardInfo("Ice Cauldron", 296, Rarity.RARE, mage.cards.i.IceCauldron.class));
cards.add(new SetCardInfo("Ice Floe", 333, Rarity.UNCOMMON, mage.cards.i.IceFloe.class));
cards.add(new SetCardInfo("Iceberg", 73, Rarity.UNCOMMON, mage.cards.i.Iceberg.class));
cards.add(new SetCardInfo("Icequake", 22, Rarity.UNCOMMON, mage.cards.i.Icequake.class));

View file

@ -88,6 +88,7 @@ public class LimitedEditionAlpha extends ExpansionSet {
cards.add(new SetCardInfo("Disrupting Scepter", 242, Rarity.RARE, mage.cards.d.DisruptingScepter.class));
cards.add(new SetCardInfo("Dragon Whelp", 142, Rarity.UNCOMMON, mage.cards.d.DragonWhelp.class));
cards.add(new SetCardInfo("Drain Life", 14, Rarity.COMMON, mage.cards.d.DrainLife.class));
cards.add(new SetCardInfo("Drain Power", 57, Rarity.RARE, mage.cards.d.DrainPower.class));
cards.add(new SetCardInfo("Drudge Skeletons", 15, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class));
cards.add(new SetCardInfo("Dwarven Demolition Team", 143, Rarity.UNCOMMON, mage.cards.d.DwarvenDemolitionTeam.class));
cards.add(new SetCardInfo("Dwarven Warriors", 144, Rarity.COMMON, mage.cards.d.DwarvenWarriors.class));

View file

@ -89,6 +89,7 @@ public class LimitedEditionBeta extends ExpansionSet {
cards.add(new SetCardInfo("Disrupting Scepter", 243, Rarity.RARE, mage.cards.d.DisruptingScepter.class));
cards.add(new SetCardInfo("Dragon Whelp", 142, Rarity.UNCOMMON, mage.cards.d.DragonWhelp.class));
cards.add(new SetCardInfo("Drain Life", 106, Rarity.COMMON, mage.cards.d.DrainLife.class));
cards.add(new SetCardInfo("Drain Power", 57, Rarity.RARE, mage.cards.d.DrainPower.class));
cards.add(new SetCardInfo("Drudge Skeletons", 107, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class));
cards.add(new SetCardInfo("Dwarven Demolition Team", 143, Rarity.UNCOMMON, mage.cards.d.DwarvenDemolitionTeam.class));
cards.add(new SetCardInfo("Dwarven Warriors", 144, Rarity.COMMON, mage.cards.d.DwarvenWarriors.class));

View file

@ -130,6 +130,7 @@ public class MastersEditionIV extends ExpansionSet {
cards.add(new SetCardInfo("Diabolic Machine", 196, Rarity.UNCOMMON, mage.cards.d.DiabolicMachine.class));
cards.add(new SetCardInfo("Divine Offering", 10, Rarity.COMMON, mage.cards.d.DivineOffering.class));
cards.add(new SetCardInfo("Dragon Engine", 197, Rarity.COMMON, mage.cards.d.DragonEngine.class));
cards.add(new SetCardInfo("Drain Power", 46, Rarity.RARE, mage.cards.d.DrainPower.class));
cards.add(new SetCardInfo("Dread Reaper", 78, Rarity.RARE, mage.cards.d.DreadReaper.class));
cards.add(new SetCardInfo("Drop of Honey", 150, Rarity.RARE, mage.cards.d.DropOfHoney.class));
cards.add(new SetCardInfo("Drowned", 47, Rarity.COMMON, mage.cards.d.Drowned.class));
@ -175,6 +176,7 @@ public class MastersEditionIV extends ExpansionSet {
cards.add(new SetCardInfo("Healing Salve", 14, Rarity.COMMON, mage.cards.h.HealingSalve.class));
cards.add(new SetCardInfo("Horn of Deafening", 205, Rarity.UNCOMMON, mage.cards.h.HornOfDeafening.class));
cards.add(new SetCardInfo("Howl from Beyond", 87, Rarity.COMMON, mage.cards.h.HowlFromBeyond.class));
cards.add(new SetCardInfo("Ice Cauldron", 206, Rarity.RARE, mage.cards.i.IceCauldron.class));
cards.add(new SetCardInfo("Icy Manipulator", 207, Rarity.UNCOMMON, mage.cards.i.IcyManipulator.class));
cards.add(new SetCardInfo("In the Eye of Chaos", 51, Rarity.RARE, mage.cards.i.InTheEyeOfChaos.class));
cards.add(new SetCardInfo("Instill Energy", 157, Rarity.UNCOMMON, mage.cards.i.InstillEnergy.class));

View file

@ -91,6 +91,7 @@ public class RevisedEdition extends ExpansionSet {
cards.add(new SetCardInfo("Dragon Engine", 246, Rarity.RARE, mage.cards.d.DragonEngine.class));
cards.add(new SetCardInfo("Dragon Whelp", 142, Rarity.UNCOMMON, mage.cards.d.DragonWhelp.class));
cards.add(new SetCardInfo("Drain Life", 14, Rarity.COMMON, mage.cards.d.DrainLife.class));
cards.add(new SetCardInfo("Drain Power", 56, Rarity.RARE, mage.cards.d.DrainPower.class));
cards.add(new SetCardInfo("Drudge Skeletons", 15, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class));
cards.add(new SetCardInfo("Dwarven Warriors", 143, Rarity.COMMON, mage.cards.d.DwarvenWarriors.class));
cards.add(new SetCardInfo("Dwarven Weaponsmith", 144, Rarity.UNCOMMON, mage.cards.d.DwarvenWeaponsmith.class));

View file

@ -130,10 +130,10 @@ public class StarWars extends ExpansionSet {
cards.add(new SetCardInfo("Force Reflex", 13, Rarity.COMMON, mage.cards.f.ForceReflex.class));
cards.add(new SetCardInfo("Force Scream", 104, Rarity.UNCOMMON, mage.cards.f.ForceScream.class));
cards.add(new SetCardInfo("Force Spark", 105, Rarity.COMMON, mage.cards.f.ForceSpark.class));
cards.add(new SetCardInfo("Forest", 268, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Forest", 269, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Forest", 270, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Forest", 271, Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Forest", "268a", Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Forest", "268b", Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Forest", "268c", Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Forest", "268d", Rarity.LAND, mage.cards.basiclands.Forest.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Fulfill Contract", 224, Rarity.COMMON, mage.cards.f.FulfillContract.class));
cards.add(new SetCardInfo("Gamorrean Prison Guard", 106, Rarity.UNCOMMON, mage.cards.g.GamorreanPrisonGuard.class));
cards.add(new SetCardInfo("General Grievous", 185, Rarity.MYTHIC, mage.cards.g.GeneralGrievous.class));
@ -160,10 +160,10 @@ public class StarWars extends ExpansionSet {
cards.add(new SetCardInfo("Interrogation", 81, Rarity.COMMON, mage.cards.i.Interrogation.class));
cards.add(new SetCardInfo("Ion Cannon", 15, Rarity.COMMON, mage.cards.i.IonCannon.class));
cards.add(new SetCardInfo("Iron Fist of the Empire", 191, Rarity.RARE, mage.cards.i.IronFistOfTheEmpire.class));
cards.add(new SetCardInfo("Island", 256, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Island", 257, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Island", 258, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Island", 259, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Island", "256a", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Island", "256b", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Island", "256c", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Island", "256d", Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Ithorian Initiate", 140, Rarity.COMMON, mage.cards.i.IthorianInitiate.class));
cards.add(new SetCardInfo("Jabba the Hutt", 192, Rarity.RARE, mage.cards.j.JabbaTheHutt.class));
cards.add(new SetCardInfo("Jango Fett", 111, Rarity.RARE, mage.cards.j.JangoFett.class));
@ -205,10 +205,10 @@ public class StarWars extends ExpansionSet {
cards.add(new SetCardInfo("Moisture Farm", 247, Rarity.UNCOMMON, mage.cards.m.MoistureFarm.class));
cards.add(new SetCardInfo("Mon Calamari Cruiser", 48, Rarity.UNCOMMON, mage.cards.m.MonCalamariCruiser.class));
cards.add(new SetCardInfo("Mon Calamari Initiate", 49, Rarity.COMMON, mage.cards.m.MonCalamariInitiate.class));
cards.add(new SetCardInfo("Mountain", 264, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Mountain", 265, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Mountain", 266, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Mountain", 267, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Mountain", "264a", Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Mountain", "264b", Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Mountain", "264c", Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Mountain", "264d", Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("N-1 Starfighter", 225, Rarity.COMMON, mage.cards.n.N1Starfighter.class));
cards.add(new SetCardInfo("Nebulon-B Frigate", 25, Rarity.COMMON, mage.cards.n.NebulonBFrigate.class));
cards.add(new SetCardInfo("Neophyte Hateflayer", 82, Rarity.COMMON, mage.cards.n.NeophyteHateflayer.class));
@ -226,10 +226,10 @@ public class StarWars extends ExpansionSet {
cards.add(new SetCardInfo("Outer Rim Slaver", 201, Rarity.COMMON, mage.cards.o.OuterRimSlaver.class));
cards.add(new SetCardInfo("Outlaw Holocron", 235, Rarity.COMMON, mage.cards.o.OutlawHolocron.class));
cards.add(new SetCardInfo("Personal Energy Shield", 51, Rarity.COMMON, mage.cards.p.PersonalEnergyShield.class));
cards.add(new SetCardInfo("Plains", 252, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plains", 253, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plains", 254, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plains", 255, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plains", "252a", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plains", "252b", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plains", "252c", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plains", "252d", Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Plo Koon", 27, Rarity.RARE, mage.cards.p.PloKoon.class));
cards.add(new SetCardInfo("Precipice of Mortis", 202, Rarity.RARE, mage.cards.p.PrecipiceOfMortis.class));
cards.add(new SetCardInfo("Predator's Strike", 151, Rarity.COMMON, mage.cards.p.PredatorsStrike.class));
@ -289,10 +289,10 @@ public class StarWars extends ExpansionSet {
cards.add(new SetCardInfo("Strike Team Commando", 227, Rarity.COMMON, mage.cards.s.StrikeTeamCommando.class));
cards.add(new SetCardInfo("Super Battle Droid", 59, Rarity.COMMON, mage.cards.s.SuperBattleDroid.class));
cards.add(new SetCardInfo("Surprise Maneuver", 60, Rarity.COMMON, mage.cards.s.SurpriseManeuver.class));
cards.add(new SetCardInfo("Swamp", 260, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swamp", 261, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swamp", 262, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swamp", 263, Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swamp", "260a", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swamp", "260b", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swamp", "260c", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swamp", "260d", Rarity.LAND, mage.cards.basiclands.Swamp.class, new CardGraphicInfo(FrameStyle.ZEN_FULL_ART_BASIC, true)));
cards.add(new SetCardInfo("Swarm the Skies", 92, Rarity.COMMON, mage.cards.s.SwarmTheSkies.class));
cards.add(new SetCardInfo("Syndicate Enforcer", 124, Rarity.COMMON, mage.cards.s.SyndicateEnforcerSWS.class));
cards.add(new SetCardInfo("Tank Droid", 218, Rarity.RARE, mage.cards.t.TankDroid.class));
@ -328,5 +328,4 @@ public class StarWars extends ExpansionSet {
cards.add(new SetCardInfo("Yoda, Jedi Master", 223, Rarity.MYTHIC, mage.cards.y.YodaJediMaster.class));
cards.add(new SetCardInfo("Zam Wesell", 64, Rarity.RARE, mage.cards.z.ZamWesell.class));
}
}

View file

@ -89,6 +89,7 @@ public class UnlimitedEdition extends ExpansionSet {
cards.add(new SetCardInfo("Disrupting Scepter", 243, Rarity.RARE, mage.cards.d.DisruptingScepter.class));
cards.add(new SetCardInfo("Dragon Whelp", 142, Rarity.UNCOMMON, mage.cards.d.DragonWhelp.class));
cards.add(new SetCardInfo("Drain Life", 14, Rarity.COMMON, mage.cards.d.DrainLife.class));
cards.add(new SetCardInfo("Drain Power", 57, Rarity.RARE, mage.cards.d.DrainPower.class));
cards.add(new SetCardInfo("Drudge Skeletons", 15, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class));
cards.add(new SetCardInfo("Dwarven Demolition Team", 143, Rarity.UNCOMMON, mage.cards.d.DwarvenDemolitionTeam.class));
cards.add(new SetCardInfo("Dwarven Warriors", 144, Rarity.COMMON, mage.cards.d.DwarvenWarriors.class));

View file

@ -329,7 +329,7 @@ public class TestPlayer implements Player {
}
UUID modeId = ability.getModes().getModeId(modeNr);
selectedMode = ability.getModes().get(modeId);
if (modeId != ability.getModes().getMode().getId()) {
if (!Objects.equals(modeId, ability.getModes().getMode().getId())) {
ability.getModes().setActiveMode(modeId);
index = 0; // reset target index if mode changes
}
@ -2416,4 +2416,21 @@ public class TestPlayer implements Player {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Player obj = (Player) o;
if (this.getId() == null || obj.getId() == null) {
return false;
}
return this.getId().equals(obj.getId());
}
}

View file

@ -1293,4 +1293,22 @@ public class PlayerStub implements Player {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Player obj = (Player) o;
if (this.getId() == null || obj.getId() == null) {
return false;
}
return this.getId().equals(obj.getId());
}
}

View file

@ -1083,7 +1083,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
&& this.red >= mana.red
&& this.colorless >= mana.colorless
&& (this.generic >= mana.generic
|| this.countColored() >= mana.countColored() + mana.generic);
|| this.countColored() + this.colorless >= mana.count());
}

View file

@ -63,9 +63,9 @@ public class AddConditionalManaOfAnyColorEffect extends ManaEffect {
staticText = "Add "
+ (amount instanceof StaticValue ? (CardUtil.numberToText(((StaticValue) amount).toString())) : "")
+ " mana "
+ (oneChoice ? "of any"
+ (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1") ? "" : " one")
+ " color" : "in any combination of colors")
+ (oneChoice || (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1"))
? "of any" + (amount instanceof StaticValue && (((StaticValue) amount).toString()).equals("1") ? "" : " one") + " color"
: "in any combination of colors")
+ ". " + manaBuilder.getRule();
}

View file

@ -53,6 +53,7 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl {
private FilterCard filter;
private int amount;
private final boolean upTo;
private boolean onlyControlled;
public SpellsCostReductionAllEffect(int amount) {
this(new FilterCard("Spells"), amount);
@ -63,19 +64,24 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl {
}
public SpellsCostReductionAllEffect(FilterCard filter, int amount, boolean upTo) {
this(filter, amount, upTo, false);
}
public SpellsCostReductionAllEffect(FilterCard filter, int amount, boolean upTo, boolean onlyControlled) {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
this.filter = filter;
this.amount = amount;
this.upTo = upTo;
this.onlyControlled = onlyControlled;
this.staticText = filter.getMessage() + " cost " + (upTo ? "up to " : "") + '{' + amount + "} less to cast";
}
protected SpellsCostReductionAllEffect(SpellsCostReductionAllEffect effect) {
protected SpellsCostReductionAllEffect(final SpellsCostReductionAllEffect effect) {
super(effect);
this.filter = effect.filter;
this.amount = effect.amount;
this.upTo = effect.upTo;
this.onlyControlled = effect.onlyControlled;
}
@Override
@ -136,6 +142,9 @@ public class SpellsCostReductionAllEffect extends CostModificationEffectImpl {
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (onlyControlled && abilityToModify.getControllerId().equals(source.getControllerId())) {
return false;
}
if (abilityToModify instanceof SpellAbility) {
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
if (spell != null) {

View file

@ -19,7 +19,11 @@ import mage.game.Game;
public class SpellsCostReductionAllOfChosenSubtypeEffect extends SpellsCostReductionAllEffect {
public SpellsCostReductionAllOfChosenSubtypeEffect(FilterCard filter, int amount) {
super(filter, amount);
this(filter, amount, false);
}
public SpellsCostReductionAllOfChosenSubtypeEffect(FilterCard filter, int amount, boolean onlyControlled) {
super(filter, amount, false, onlyControlled);
}
public SpellsCostReductionAllOfChosenSubtypeEffect(final SpellsCostReductionAllOfChosenSubtypeEffect effect) {

View file

@ -757,8 +757,8 @@ public class GameState implements Serializable, Copyable<GameState> {
ZoneChangeData data = (ZoneChangeData) obj;
return this.fromZone == data.fromZone
&& this.toZone == data.toZone
&& this.sourceId == data.sourceId
&& this.playerId == data.playerId;
&& Objects.equals(this.sourceId, data.sourceId)
&& Objects.equals(this.playerId, data.playerId);
}
return false;
}

View file

@ -28,11 +28,8 @@
package mage.game.combat;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;
import mage.abilities.common.ControllerAssignCombatDamageToBlockersAbility;
import mage.abilities.common.ControllerDivideCombatDamageAbility;
import mage.abilities.common.DamageAsThoughNotBlockedAbility;
@ -286,7 +283,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
if (attacker == null) {
return;
}
boolean oldRuleDamage = (player.getId() == defendingPlayerId);
boolean oldRuleDamage = (Objects.equals(player.getId(), defendingPlayerId));
int damage = getDamageValueFromPermanent(attacker, game);
if (canDamage(attacker, first)) {
// must be set before attacker damage marking because of effects like Test of Faith

View file

@ -29,6 +29,7 @@ package mage.game.command.planes;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
@ -132,7 +133,7 @@ class EdgeOfMalacolEffect extends ContinuousRuleModifyingEffectImpl {
}
}
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && filter.match(permanent, game) && permanent.getControllerId() == game.getActivePlayerId()) {
if (permanent != null && filter.match(permanent, game) && Objects.equals(permanent.getControllerId(), game.getActivePlayerId())) {
UUID oldController = source.getControllerId();
source.setControllerId(game.getActivePlayerId());
Effect effect = new AddCountersTargetEffect(CounterType.P1P1.createInstance(2));

View file

@ -149,6 +149,7 @@ public class Spell extends StackObjImpl implements Card {
this.resolving = spell.resolving;
this.doneActivatingManaAbilities = spell.doneActivatingManaAbilities;
this.targetChanged = spell.targetChanged;
}
public boolean activate(Game game, boolean noMana) {

View file

@ -89,6 +89,7 @@ public class StackAbility extends StackObjImpl implements Ability {
this.name = stackAbility.name;
this.expansionSetCode = stackAbility.expansionSetCode;
this.targetAdjustment = stackAbility.targetAdjustment;
this.targetChanged = stackAbility.targetChanged;
}
@Override

View file

@ -5,6 +5,8 @@
*/
package mage.game.stack;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Abilities;
import mage.abilities.AbilitiesImpl;
@ -19,16 +21,13 @@ import mage.players.Player;
import mage.target.Target;
import mage.target.TargetAmount;
import java.util.Set;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public abstract class StackObjImpl implements StackObject {
private boolean targetChanged; // for Psychic Battle
protected boolean targetChanged; // for Psychic Battle
/**
* Choose new targets for a stack Object
@ -74,12 +73,11 @@ public abstract class StackObjImpl implements StackObject {
* the change is legal.
*
* Example: Arc Trail is a sorcery that reads "Arc Trail deals 2 damage to
* any target and 1 damage to another target creature or
* player." The current targets of Arc Trail are Runeclaw Bear and Llanowar
* Elves, in that order. You cast Redirect, an instant that reads "You may
* choose new targets for target spell," targeting Arc Trail. You can change
* the first target to Llanowar Elves and change the second target to
* Runeclaw Bear.
* any target and 1 damage to another target creature or player." The
* current targets of Arc Trail are Runeclaw Bear and Llanowar Elves, in
* that order. You cast Redirect, an instant that reads "You may choose new
* targets for target spell," targeting Arc Trail. You can change the first
* target to Llanowar Elves and change the second target to Runeclaw Bear.
*
* 114.7. Modal spells and abilities may have different targeting
* requirements for each mode. An effect that allows a player to change the

View file

@ -395,7 +395,8 @@ public class ManaPool implements Serializable {
Mana mana = manaToAdd.copy();
if (!game.replaceEvent(new ManaEvent(EventType.ADD_MANA, source.getId(), source.getSourceId(), playerId, mana))) {
if (mana instanceof ConditionalMana) {
ManaPoolItem item = new ManaPoolItem((ConditionalMana) mana, source.getSourceObject(game), source.getOriginalId());
ManaPoolItem item = new ManaPoolItem((ConditionalMana) mana, source.getSourceObject(game),
((ConditionalMana) mana).getManaProducerOriginalId() != null ? ((ConditionalMana) mana).getManaProducerOriginalId() : source.getOriginalId());
if (emptyOnTurnsEnd) {
item.setDuration(Duration.EndOfTurn);
}
@ -505,4 +506,13 @@ public class ManaPool implements Serializable {
public boolean isEmpty() {
return count() == 0;
}
public List<ManaPoolItem> getManaItems() {
List<ManaPoolItem> itemsCopy = new ArrayList<>();
for (ManaPoolItem manaItem : manaItems) {
itemsCopy.add(manaItem.copy());
}
return itemsCopy;
}
}

View file

@ -3866,7 +3866,7 @@ public abstract class PlayerImpl implements Player, Serializable {
return false;
}
PlayerImpl obj = (PlayerImpl) o;
Player obj = (Player) o;
if (this.getId() == null || obj.getId() == null) {
return false;
}

View file

@ -27,11 +27,8 @@
*/
package mage.watchers.common;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import mage.constants.WatcherScope;
import mage.game.Game;
import mage.game.combat.CombatGroup;
@ -67,7 +64,7 @@ public class BlockedByOnlyOneCreatureThisCombatWatcher extends Watcher {
if (!blockedByOneCreature.containsKey(combatGroup)) {
blockedByOneCreature.put(combatGroup, event.getSourceId());
}
else if (blockedByOneCreature.get(combatGroup) != event.getSourceId()) {
else if (!Objects.equals(blockedByOneCreature.get(combatGroup), event.getSourceId())) {
blockedByOneCreature.put(combatGroup, null);
}
}