Merge branch 'master' into AminatousAugur

This commit is contained in:
LevelX2 2018-08-15 08:46:37 +02:00 committed by GitHub
commit 1c964ca0d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
141 changed files with 10476 additions and 3198 deletions

View file

@ -0,0 +1,86 @@
1 [C18:61] Ajani's Chosen
1 [C18:81] Archetype of Imagination
1 [C18:38] Arixmethes, Slumbering Isle
1 [C18:128] Aura Gnarlid
1 [C18:233] Azorius Chancery
1 [C18:169] Bant Charm
1 [C18:131] Bear Umbra
1 [C18:237] Blossoming Sands
1 [C18:132] Boon Satyr
1 [C18:170] Bruna, Light of Alabaster
1 [C18:64] Celestial Archon
1 [C18:172] Cold-Eyed Selkie
1 [C18:240] Command Tower
1 [C18:137] Creeping Renaissance
1 [C18:139] Dawn's Reflection
1 [C18:173] Daxos of Meletis
1 [C18:86] Dictate of Kruphix
1 [C18:66] Dismantling Blow
1 [C18:89] Eel Umbra
1 [C18:140] Eidolon of Blossoms
1 [C18:177] Elderwood Scion
1 [C18:2] Empyrial Storm
1 [C18:141] Enchantress's Presence
1 [C18:142] Epic Proportions
1 [C18:8] Estrid's Invocation
1 [C18:9] Ever-Watching Threshold
1 [C18:245] Evolving Wilds
1 [C18:147] Fertile Ground
1 [C18:180] Finest Hour
1 [C18:58] Forge of Heroes
1 [C18:30] Genesis Storm
1 [C18:149] Ground Seal
1 [C18:3] Heavenly Blademaster
1 [C18:151] Herald of the Pantheon
1 [C18:153] Hydra Omnivore
1 [C18:42] Kestia, the Cultivator
1 [C18:263] Krosan Verge
1 [C18:155] Kruphix's Insight
1 [C18:10] Loyal Drake
1 [C18:31] Loyal Guardian
1 [C18:4] Loyal Unicorn
1 [C18:69] Martial Coup
1 [C18:265] Meandering River
1 [C18:267] Mosswort Bridge
1 [C18:32] Myth Unbound
1 [C18:33] Nylea's Colossus
1 [C18:11] Octopus Umbra
1 [C18:157] Overgrowth
1 [C18:70] Phyrexian Rebirth
1 [C18:34] Ravenous Slime
1 [C18:159] Reclamation Sage
1 [C18:188] Righteous Authority
1 [C18:72] Sage's Reverie
1 [C18:277] Seaside Citadel
1 [C18:281] Selesnya Sanctuary
1 [C18:74] Sigil of the Empty Throne
1 [C18:75] Silent Sentinel
1 [C18:282] Simic Growth Chamber
1 [C18:162] Snake Umbra
1 [C18:222] Sol Ring
1 [C18:76] Soul Snare
1 [C18:163] Spawning Grounds
1 [C18:286] Terramorphic Expanse
1 [C18:287] Thornwood Falls
1 [C18:288] Tranquil Cove
1 [C18:289] Tranquil Expanse
1 [C18:47] Tuvasa the Sunlit
1 [C18:192] Unflinching Courage
1 [C18:78] Unquestioned Authority
1 [C18:110] Vow of Flight
1 [C18:164] Vow of Wildness
1 [C18:112] Whitewater Naiads
1 [C18:165] Wild Growth
1 [C18:79] Winds of Rath
1 [C18:79] Winds of Rath
1 [C18:167] Yavimaya Enchantress
2 [C18:307] Forest
2 [C18:296] Island
2 [C18:297] Island
2 [C18:298] Island
3 [C18:305] Forest
3 [C18:306] Forest
3 [C18:293] Plains
3 [C18:294] Plains
3 [C18:295] Plains
SB:1 [C18:40] Estrid, the Masked

View file

@ -0,0 +1,79 @@
1 [C18:197] Blinkmoth Urn
1 [C18:92] Into the Roil
1 [C18:230] Worn Powerstone
1 [C18:91] Inkwell Leviathan
1 [C18:199] Chief of the Foundry
1 [C18:90] Etherium Sculptor
1 [C18:111] Whirler Rogue
1 [C18:198] Bosh, Iron Golem
1 [C18:278] Seat of the Synod
1 [C18:58] Forge of Heroes
1 [C18:57] Retrofitter Foundry
1 [C18:13] Vedalken Humiliator
1 [C18:56] Geode Golem
1 [C18:55] Endless Atlas
1 [C18:99] Reverse Engineer
1 [C18:54] Coveted Jewel
1 [C18:10] Loyal Drake
1 [C18:53] Ancient Stone Idol
1 [C18:239] Buried Ruin
1 [C18:185] Maverick Thopterist
1 [C18:100] Saheeli's Artistry
1 [C18:223] Soul of New Phyrexia
1 [C18:27] Treasure Nabber
1 [C18:26] Saheeli's Directive
1 [C18:101] Sharding Sphinx
1 [C18:222] Sol Ring
1 [C18:225] Swiftfoot Boots
4 [C18:302] Mountain
1 [C18:224] Steel Hellkite
1 [C18:23] Loyal Apprentice
1 [C18:106] Thirst for Knowledge
1 [C18:227] Unstable Obelisk
4 [C18:304] Mountain
1 [C18:226] Thopter Assembly
4 [C18:303] Mountain
1 [C18:21] Enchanter's Bane
1 [C18:108] Tidings
1 [C18:229] Vessel of Endless Rest
1 [C18:107] Thopter Spy Network
1 [C18:228] Unwinding Clock
1 [C18:28] Varchild, Betrayer of Kjeldor
1 [C18:250] Great Furnace
5 [C18:296] Island
1 [C18:210] Mind Stone
5 [C18:298] Island
5 [C18:297] Island
1 [C18:256] Izzet Boilerworks
1 [C18:212] Myr Battlesphere
1 [C18:255] Highland Lake
1 [C18:211] Mirrorworks
1 [C18:214] Pilgrim's Eye
1 [C18:257] Izzet Guildgate
1 [C18:216] Prototype Portal
1 [C18:215] Prismatic Lens
1 [C18:218] Scrabbling Claws
1 [C18:217] Psychosis Crawler
1 [C18:219] Scuttling Doom Engine
1 [C18:7] Echo Storm
1 [C18:39] Brudiclad, Telchor Engineer
1 [C18:120] Blasphemous Act
1 [C18:241] Darksteel Citadel
1 [C18:80] Aether Gale
1 [C18:240] Command Tower
1 [C18:284] Swiftwater Cliffs
1 [C18:122] Chaos Warp
1 [C18:124] Hellkite Igniter
1 [C18:200] Commander's Sphere
1 [C18:126] Thopter Engineer
1 [C18:202] Darksteel Juggernaut
1 [C18:125] Magmaquake
1 [C18:205] Duplicant
1 [C18:45] Tawnos, Urza's Apprentice
1 [C18:204] Dreamstone Hedron
1 [C18:248] Foundry of the Consuls
1 [C18:207] Izzet Signet
1 [C18:206] Hedron Archive
1 [C18:209] Mimic Vat
1 [C18:208] Magnifying Glass
SB: 1 [C18:44] Saheeli, the Gifted

View file

@ -0,0 +1,91 @@
1 [C18:114] Moonlight Bargain
1 [C18:116] Retreat to Hagra
1 [C18:117] Ruinous Path
1 [C18:118] Soul of Innistrad
1 [C18:119] Stitch Together
1 [C18:121] Chain Reaction
1 [C18:123] Flameblast Dragon
1 [C18:127] Acidic Slime
1 [C18:129] Avenger of Zendikar
1 [C18:130] Baloth Woodcrasher
1 [C18:133] Borderland Explorer
1 [C18:134] Budoka Gardener
1 [C18:135] Centaur Vinecrasher
1 [C18:136] Consign to Dust
1 [C18:138] Cultivate
1 [C18:143] Explore
1 [C18:144] Explosive Vegetation
1 [C18:145] Far Wanderings
1 [C18:146] Farhaven Elf
1 [C18:148] Grapple with the Past
1 [C18:14] Bloodtracker
1 [C18:150] Harrow
1 [C18:152] Hunting Wilds
1 [C18:154] Khalni Heart Expedition
1 [C18:156] Moldgraf Monstrosity
1 [C18:158] Rampaging Baloths
1 [C18:160] Sakura-Tribe Elder
1 [C18:161] Scute Mob
1 [C18:166] Yavimaya Elder
1 [C18:16] Loyal Subordinate
1 [C18:171] Charnelhoard Wurm
1 [C18:174] Deathreap Ritual
1 [C18:175] Decimate
1 [C18:181] Gaze of Granite
1 [C18:182] Grisly Salvage
1 [C18:184] Lavalanche
1 [C18:187] Putrefy
1 [C18:189] Rubblehulk
1 [C18:190] Savage Twister
1 [C18:194] Worm Harvest
1 [C18:195] Zendikar Incarnate
1 [C18:221] Seer's Sundial
1 [C18:222] Sol Ring
1 [C18:22] Fury Storm
1 [C18:231] Akoum Refuge
1 [C18:235] Barren Moor
1 [C18:236] Blighted Woodland
1 [C18:238] Bojuka Bog
1 [C18:23] Loyal Apprentice
1 [C18:240] Command Tower
1 [C18:245] Evolving Wilds
1 [C18:246] Forgotten Cave
1 [C18:249] Golgari Rot Farm
1 [C18:24] Nesting Dragon
1 [C18:251] Grim Backwoods
1 [C18:252] Gruul Turf
1 [C18:254] Haunted Fengraf
1 [C18:258] Jund Panorama
1 [C18:259] Jungle Hollow
1 [C18:25] Reality Scramble
1 [C18:261] Kazandu Refuge
1 [C18:262] Khalni Garden
1 [C18:268] Mountain Valley
1 [C18:269] Myriad Landscape
1 [C18:273] Rakdos Carnarium
1 [C18:274] Rocky Tar Pit
1 [C18:275] Savage Lands
1 [C18:285] Temple of the False God
1 [C18:286] Terramorphic Expanse
1 [C18:290] Tranquil Thicket
1 [C18:29] Crash of Rhino Beetles
1 [C18:31] Loyal Guardian
1 [C18:35] Turntimber Sower
1 [C18:36] Whiptongue Hydra
1 [C18:41] Gyrus, Waker of Corpses
1 [C18:49] Windgrace's Judgment
1 [C18:58] Forge of Heroes
1 [C18:20] Emissary of Grudges
1 [C18:46] Thantis, the Warweaver
1 [C18:291] Warped Landscape
1 [C18:50] Xantcha, Sleeper Agent
2 [C18:299] Swamp
2 [C18:300] Swamp
2 [C18:301] Swamp
2 [C18:302] Mountain
2 [C18:303] Mountain
1 [C18:304] Mountain
2 [C18:306] Forest
2 [C18:307] Forest
3 [C18:305] Forest
SB: 1 [C18:43] Lord Windgrace

View file

@ -0,0 +1,93 @@
1 [C18:102] Sigiled Starfish
1 [C18:103] Sphinx of Jwar Isle
1 [C18:104] Sphinx of Uthuun
1 [C18:105] Telling Time
1 [C18:109] Treasure Hunt
1 [C18:113] Army of the Damned
1 [C18:115] Phyrexian Delver
1 [C18:12] Primordial Mist
1 [C18:15] Entreat the Dead
1 [C18:168] Aethermage's Touch
1 [C18:16] Loyal Subordinate
1 [C18:176] Duskmantle Seer
1 [C18:178] Enigma Sphinx
1 [C18:179] Esper Charm
1 [C18:17] Night Incarnate
1 [C18:183] High Priest of Penance
1 [C18:186] Mortify
1 [C18:18] Skull Storm
1 [C18:191] Silent-Blade Oni
1 [C18:193] Utter End
1 [C18:196] Azorius Signet
1 [C18:19] Sower of Discord
1 [C18:1] Boreas Charger
1 [C18:200] Commander's Sphere
1 [C18:201] Crystal Ball
1 [C18:203] Dimir Signet
1 [C18:210] Mind Stone
1 [C18:213] Orzhov Signet
1 [C18:214] Pilgrim's Eye
1 [C18:220] Seer's Lantern
1 [C18:222] Sol Ring
1 [C18:232] Arcane Sanctum
1 [C18:233] Azorius Chancery
1 [C18:234] Azorius Guildgate
1 [C18:235] Barren Moor
1 [C18:240] Command Tower
1 [C18:242] Dimir Aqueduct
1 [C18:243] Dimir Guildgate
1 [C18:244] Dismal Backwater
1 [C18:247] Forsaken Sanctuary
1 [C18:253] Halimar Depths
1 [C18:260] Jwar Isle Refuge
1 [C18:264] Lonely Sandbar
1 [C18:265] Meandering River
1 [C18:266] Mortuary Mire
1 [C18:270] New Benalia
1 [C18:271] Orzhov Basilica
1 [C18:272] Orzhov Guildgate
1 [C18:276] Scoured Barrens
1 [C18:279] Secluded Steppe
1 [C18:280] Sejiri Refuge
1 [C18:283] Submerged Boneyard
1 [C18:48] Varina, Lich Queen
1 [C18:4] Loyal Unicorn
1 [C18:56] Geode Golem
1 [C18:58] Forge of Heroes
1 [C18:59] Isolated Watchtower
1 [C18:5] Magus of the Balance
1 [C18:60] Adarkar Valkyrie
1 [C18:62] Akroma's Vengeance
1 [C18:63] Banishing Stroke
1 [C18:65] Crib Swap
1 [C18:67] Entreat the Angels
1 [C18:68] Lightform
1 [C18:71] Return to Dust
1 [C18:73] Serra Avatar
1 [C18:77] Terminus
1 [C18:82] Brainstorm
1 [C18:83] Cloudform
1 [C18:84] Conundrum Sphinx
1 [C18:85] Devastation Tide
1 [C18:87] Djinn of Wishes
1 [C18:88] Dream Cache
1 [C18:93] Jeskai Infiltrator
1 [C18:94] Mulldrifter
1 [C18:95] Ninja of the Deep Hours
1 [C18:96] Ponder
1 [C18:97] Portent
1 [C18:98] Predict
1 [C18:298] Island
1 [C18:299] Swamp
1 [C18:300] Swamp
1 [C18:301] Swamp
1 [C18:006] Aminatou's Augury
1 [C18:288] Tranquil Cove
1 [C18:51] Yennett, Cryptic Sovereign
1 [C18:52] Yuriko, the Tiger's Shadow
2 [C18:296] Island
2 [C18:297] Island
2 [C18:295] Plains
3 [C18:293] Plains
3 [C18:294] Plains
SB: 1 [C18:37] Aminatou, the Fateshifter

View file

@ -9,6 +9,8 @@ package mage.client.table;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyVetoException; import java.beans.PropertyVetoException;
import java.io.File; import java.io.File;
import java.text.DateFormat; import java.text.DateFormat;
@ -316,6 +318,20 @@ public class TablesPanel extends javax.swing.JPanel {
actionButton1 = new ButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TableTableModel.ACTION_COLUMN)); actionButton1 = new ButtonColumn(tableTables, openTableAction, tableTables.convertColumnIndexToView(TableTableModel.ACTION_COLUMN));
actionButton2 = new ButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.COLUMN_ACTION)); actionButton2 = new ButtonColumn(tableCompleted, closedTableAction, tableCompleted.convertColumnIndexToView(MatchesTableModel.COLUMN_ACTION));
// !!!! // !!!!
addTableDoubleClickListener(tableTables, openTableAction);
addTableDoubleClickListener(tableCompleted, closedTableAction);
}
private void addTableDoubleClickListener(JTable table, Action action) {
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int row = table.rowAtPoint(e.getPoint());
if (e.getClickCount() == 2 && row != -1) {
action.actionPerformed(new ActionEvent(e.getSource(), e.getID(), "" + row));
}
}
});
} }
public void cleanUp() { public void cleanUp() {

View file

@ -357,10 +357,81 @@ public enum GrabbagImageSource implements CardImageSource {
singleLinks.put("SWS/Yoda, Jedi Master", "6arN1Hl.png"); singleLinks.put("SWS/Yoda, Jedi Master", "6arN1Hl.png");
singleLinks.put("SWS/Y-Wing", "aQQ5zwA.jpg"); singleLinks.put("SWS/Y-Wing", "aQQ5zwA.jpg");
singleLinks.put("SWS/Zam Wesell", "ToG0C1r.jpg"); singleLinks.put("SWS/Zam Wesell", "ToG0C1r.jpg");
singleLinks.put("SWS/Astromech Droid", "v0TpHMh.jpg");
singleLinks.put("SWS/Buried Ruin", "QkmIWYg.png");
singleLinks.put("SWS/Flame Trooper", "RkY7KFJ.jpg");
singleLinks.put("SWS/Force Stasis", "FavLrcY.jpg");
singleLinks.put("SWS/Salvage Trader", "qGwk7Bn.jpg");
singleLinks.put("SWS/Outer Rim Gang", "kEjKQGy.png");
singleLinks.put("SWS/Rathtar", "CYhHRqF.png");
singleLinks.put("SWS/Riot Trooper", "PusvaQB.jpg");
singleLinks.put("SWS/Sins of the Father", "32YHTPB.jpg");
singleLinks.put("SWS/Upsilon-class Shuttle", "Le3F3oW.jpg");
singleLinks.put("SWS/Finn", "TU2LI2q.jpg");
singleLinks.put("SWS/General Hux", "UpWfcV6.png");
singleLinks.put("SWS/Poe Dameron", "v8i21dn.png");
singleLinks.put("SWS/Rey", "7n5ZZFA.png");
singleLinks.put("SWS/Kylo Ren", "fFzDMTz.png");
singleLinks.put("SWS/TIE Striker", "6b5GDUQ.jpg");
singleLinks.put("SWS/Bludgeoning Pain", "ap5k3Wl.jpg");
singleLinks.put("SWS/Force Protection", "GrOQLHO.jpg");
singleLinks.put("SWS/Gerrera's Revolutionary", "FQFE1Jt.jpg");
singleLinks.put("SWS/Thermal Detonator", "gTPLM83.jpg");
singleLinks.put("SWS/Hammerhead Corvette", "IlhOAGv.jpg");
singleLinks.put("SWS/U-Wing", "FmoRCmG.jpg");
singleLinks.put("SWS/Bor Gullet", "jXafYHX.jpg");
singleLinks.put("SWS/Imperial Hovertank", "6X1wL4d.jpg");
singleLinks.put("SWS/Occupation", "h4mmkA5.jpg");
singleLinks.put("SWS/Resistance", "lbNhA59.jpg");
singleLinks.put("SWS/Jyn Erso and Cassian Andor", "o0SCGiJ.jpg");
singleLinks.put("SWS/Chirrut Imwe", "wgtXfUF.jpg");
singleLinks.put("SWS/Director Krennic", "52PGsH5.jpg");
singleLinks.put("SWS/Vader's Command", "7Lql6UT.jpg");
singleLinks.put("SWS/Delay Tactic", "ubmzD1m.jpg");
singleLinks.put("SWS/Resistance Bomber", "Sudfkd7.jpg");
singleLinks.put("SWS/Mouse Droid", "oO0p8QE.jpg");
singleLinks.put("SWS/First Order Dreadnought", "80pO9Cc.jpg");
singleLinks.put("SWS/TIE Silencer", "7yeYIjX.jpg");
singleLinks.put("SWS/Canto Bight Enforcer", "VKPQVsn.jpg");
singleLinks.put("SWS/Cantonica Casino", "7LiSvy6.jpg");
singleLinks.put("SWS/Fathier", "0oKquQp.jpg");
singleLinks.put("SWS/Code Slice", "7uNASji.jpg");
singleLinks.put("SWS/Captain Phasma", "LWujx1B.jpg");
singleLinks.put("SWS/Force Telepathy", "e90hswX.jpg");
singleLinks.put("SWS/Praetorian Trooper", "pjS1wyS.jpg");
singleLinks.put("SWS/Supreme Leader Snoke", "eewWiKE.jpg");
singleLinks.put("SWS/Sai Tok", "FVn29tT.jpg");
singleLinks.put("SWS/Porg Nest", "8DnNZKc.jpg");
singleLinks.put("SWS/Inspire", "7lIXhtd.jpg");
singleLinks.put("SWS/Force Projection", "5EfOwyn.jpg");
singleLinks.put("SWS/Luke Skywalker, the Last Jedi", "WMmQcyD.jpg");
singleLinks.put("SWS/Vulptex", "30WeCkw.jpg");
singleLinks.put("SWS/Glorious Charge", "yJwvKzk.jpg");
singleLinks.put("SWS/Plains-520b", "Fx59r9J.jpg");
singleLinks.put("SWS/Island-520a", "jIPpWp5.jpg");
singleLinks.put("SWS/Conscription", "An01yAe.jpg");
singleLinks.put("SWS/Afterburn", "2ydqSvT.jpg");
singleLinks.put("SWS/Corellian Gunship", "mZdDQWH.jpg");
singleLinks.put("SWS/Despair", "TLTddMI.jpg");
singleLinks.put("SWS/Dryden Vos", "6LbtUzN.jpg");
singleLinks.put("SWS/Droid Uprising", "aWuoxho.jpg");
singleLinks.put("SWS/Gamble", "Hwzr60O.jpg");
singleLinks.put("SWS/Han Solo, Scrumrat", "Hqj39dG.jpg");
singleLinks.put("SWS/Mud Trooper", "af8JaDy.jpg");
singleLinks.put("SWS/Enfys Nest", "pstVfQg.jpg");
singleLinks.put("SWS/Kalevan Star Yacht", "nHmSizp.jpg");
singleLinks.put("SWS/Maelstrom Blockade", "sUYT0pc.jpg");
singleLinks.put("SWS/Range Trooper", "kXGvTkE.jpg");
singleLinks.put("SWS/Tobias Beckett", "hzm6ilE.jpg");
singleLinks.put("SWS/Underground Forum", "FH2pRfU.jpg");
singleLinks.put("SWS/Chewbacca, the Beast", "Zb5TitZ.jpg");
// Emblems // Emblems
singleLinks.put("SWS/Emblem Obi-Wan Kenobi", "Qyc10aT.png"); singleLinks.put("SWS/Emblem Obi-Wan Kenobi", "Qyc10aT.png");
singleLinks.put("SWS/Aurra Sing", "BLWbVJC.png"); singleLinks.put("SWS/Aurra Sing", "BLWbVJC.png");
singleLinks.put("SWS/Yoda", "zH0sYxg.png"); singleLinks.put("SWS/Yoda", "zH0sYxg.png");
singleLinks.put("SWS/Emblem Luke Skywalker", "kHELZDJ.jpg");
// Tokens // Tokens
singleLinks.put("SWS/Ewok", "N2MvJyr.png"); singleLinks.put("SWS/Ewok", "N2MvJyr.png");
singleLinks.put("SWS/B-Wing", "oH62AUD.png"); singleLinks.put("SWS/B-Wing", "oH62AUD.png");
@ -372,6 +443,8 @@ public enum GrabbagImageSource implements CardImageSource {
singleLinks.put("SWS/Royal Guard", "9tqE8vL.png"); singleLinks.put("SWS/Royal Guard", "9tqE8vL.png");
singleLinks.put("SWS/Tusken Raider", "gPMiSmP.png"); singleLinks.put("SWS/Tusken Raider", "gPMiSmP.png");
singleLinks.put("SWS/Droid", "4PRrWFF.png"); singleLinks.put("SWS/Droid", "4PRrWFF.png");
singleLinks.put("SWS/Trooper 2", "tcxvGOn.jpg");
singleLinks.put("SWS/Porg", "HBjt1A3.jpg");
} }
@Override @Override

View file

@ -1,4 +1,3 @@
package org.mage.plugins.card.dl.sources; package org.mage.plugins.card.dl.sources;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -18,7 +17,6 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.remote.Connection; import mage.remote.Connection;
import mage.remote.Connection.ProxyType; import mage.remote.Connection.ProxyType;
@ -232,6 +230,8 @@ public enum MythicspoilerComSource implements CardImageSource {
supportedSets.add("RIX"); supportedSets.add("RIX");
supportedSets.add("DOM"); supportedSets.add("DOM");
supportedSets.add("BBD"); supportedSets.add("BBD");
supportedSets.add("M19");
supportedSets.add("C18");
// supportedSets.add("CM2"); // supportedSets.add("CM2");
sets = new LinkedHashMap<>(); sets = new LinkedHashMap<>();
@ -329,7 +329,7 @@ public enum MythicspoilerComSource implements CardImageSource {
} }
private Map<String, String> getSetLinksFromPage(String cardSet, Set<String> aliasesStart, Preferences prefs, private Map<String, String> getSetLinksFromPage(String cardSet, Set<String> aliasesStart, Preferences prefs,
ProxyType proxyType, String baseUrl, String pageUrl) throws IOException { ProxyType proxyType, String baseUrl, String pageUrl) throws IOException {
Map<String, String> pageLinks = new HashMap<>(); Map<String, String> pageLinks = new HashMap<>();
String urlDocument; String urlDocument;

View file

@ -6,7 +6,6 @@ import java.util.LinkedHashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
@ -227,7 +226,8 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("A25"); supportedSets.add("A25");
supportedSets.add("DOM"); supportedSets.add("DOM");
supportedSets.add("BBD"); supportedSets.add("BBD");
// supportedSets.add("CM2"); supportedSets.add("C18");
supportedSets.add("CM2");
supportedSets.add("M19"); supportedSets.add("M19");
} }
@ -240,7 +240,6 @@ public enum ScryfallImageSource implements CardImageSource {
// loc example: https://api.scryfall.com/cards/xln/121/ru?format=image // loc example: https://api.scryfall.com/cards/xln/121/ru?format=image
// TODO: do not use API at all? It's can help with scryfall request limits (1 request instead 2) // TODO: do not use API at all? It's can help with scryfall request limits (1 request instead 2)
String baseUrl = null; String baseUrl = null;
String alternativeUrl = null; String alternativeUrl = null;

View file

@ -239,7 +239,7 @@ public enum WizardCardsImageSource implements CardImageSource {
supportedSets.add("M19"); // Core 2019 supportedSets.add("M19"); // Core 2019
// supportedSets.add("GRN"); // Guilds of Ravnica // supportedSets.add("GRN"); // Guilds of Ravnica
// supportedSets.add("RNA"); // Ravnica Allegiance // supportedSets.add("RNA"); // Ravnica Allegiance
// supportedSets.add("C18"); // Commander 2018 supportedSets.add("C18"); // Commander 2018
sets = new HashMap<>(); sets = new HashMap<>();
setsAliases = new HashMap<>(); setsAliases = new HashMap<>();

View file

@ -75,4 +75,4 @@ dd3jvc=ddajvc
# Remove setname as soon as the images can be downloaded # Remove setname as soon as the images can be downloaded
ignore.urls=TOK,H17 ignore.urls=TOK,H17
# sets ordered by release time (newest goes first) # sets ordered by release time (newest goes first)
token.lookup.order=M19,A25,DOM,E02,RIX,UST,XLN,IMA,H17,C17,V17,E01,DDT,CMA,HOU,MM3,DDS,AKH,DD3DVD,DD3EVG,DD3GVL,DD3JVC,H09,AER,PCA,C16,V16,MPS,KLD,DDR,CN2,EMN,EMA,SOI,DDQ,CP,CMA,ARENA,SUS,APAC,EURO,UGIN,C15,OGW,EXP,DDP,BFZ,DRB,V09,V10,V11,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC token.lookup.order=C18,M19,A25,DOM,E02,RIX,UST,XLN,IMA,H17,C17,V17,E01,DDT,CMA,HOU,MM3,DDS,AKH,DD3DVD,DD3EVG,DD3GVL,DD3JVC,H09,AER,PCA,C16,V16,MPS,KLD,DDR,CN2,EMN,EMA,SOI,DDQ,CP,CMA,ARENA,SUS,APAC,EURO,UGIN,C15,OGW,EXP,DDP,BFZ,DRB,V09,V10,V11,V12,V13,V14,V15,TPR,MPRP,DD3,DDO,ORI,MM2,PTC,DTK,FRF,KTK,M15,VMA,CNS,JOU,BNG,THS,DDL,M14,MMA,DGM,GTC,RTR,M13,AVR,DDI,DKA,ISD,M12,NPH,MBS,SOM,M11,ROE,DDE,WWK,ZEN,M10,GVL,ARB,DVD,CFX,JVC,ALA,EVE,SHM,EVG,MOR,LRW,10E,CLS,CHK,GRC

View file

@ -0,0 +1,47 @@
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Mode;
import mage.abilities.effects.common.RemoveFromCombatTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Afterburn extends CardImpl {
public Afterburn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{R}");
// Choose One -
// Target creature gains haste and first strike until end of turn.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn).setText("Target creature gains haste"));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn).setText("and first strike until end of turn"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Remove target creature from combat.
Mode mode = new Mode();
mode.getEffects().add(new RemoveFromCombatTargetEffect());
mode.getTargets().add(new TargetCreaturePermanent());
this.getSpellAbility().addMode(mode);
}
public Afterburn(final Afterburn card) {
super(card);
}
@Override
public Afterburn copy() {
return new Afterburn(this);
}
}

View file

@ -2,6 +2,7 @@ package mage.cards.a;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
@ -29,6 +30,10 @@ import mage.target.targetpointer.FixedTarget;
import java.util.UUID; import java.util.UUID;
/**
*
* @author Colin Redman
*/
public class AminatouTheFateShifter extends CardImpl { public class AminatouTheFateShifter extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("permanent you own"); private static final FilterPermanent filter = new FilterPermanent("permanent you own");
@ -59,6 +64,9 @@ public class AminatouTheFateShifter extends CardImpl {
// Fateshifter controlled by the next player in the chosen direction. // Fateshifter controlled by the next player in the chosen direction.
ability = new LoyaltyAbility(new AminatouUltimateEffect(), -6); ability = new LoyaltyAbility(new AminatouUltimateEffect(), -6);
this.addAbility(ability); this.addAbility(ability);
// Aminatou, the Fateshifter can be your commander.
this.addAbility(CanBeYourCommanderAbility.getInstance());
} }
public AminatouTheFateShifter(final AminatouTheFateShifter card) { public AminatouTheFateShifter(final AminatouTheFateShifter card) {
super(card); super(card);

View file

@ -11,6 +11,7 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
@ -18,7 +19,6 @@ import mage.counters.CounterType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.util.CardUtil; import mage.util.CardUtil;
/** /**
@ -85,7 +85,7 @@ class AnimarCostReductionEffect extends CostModificationEffectImpl {
public boolean applies(Ability abilityToModify, Ability source, Game game) { public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (abilityToModify instanceof SpellAbility) { if (abilityToModify instanceof SpellAbility) {
if (abilityToModify.isControlledBy(source.getControllerId())) { if (abilityToModify.isControlledBy(source.getControllerId())) {
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId()); Card spell = ((SpellAbility) abilityToModify).getCharacteristics(game);
if (spell != null) { if (spell != null) {
return spell.isCreature(); return spell.isCreature();
} }

View file

@ -0,0 +1,63 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.RepairAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class AstromechDroid extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("starship creature");
static {
filter.add(new SubtypePredicate(SubType.STARSHIP));
}
public AstromechDroid(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{W}");
this.subtype.add(SubType.DROID);
this.power = new MageInt(0);
this.toughness = new MageInt(1);
// {T}: Target starship creature you control gets +1/+1 and gains vigilance until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new BoostTargetEffect(1, 1, Duration.EndOfTurn)
.setText("Target starship creature you control gets +1/+1"),
new TapSourceCost());
ability.addEffect(new GainAbilityTargetEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn)
.setText("and gains vigilance until end of turn"));
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
// Repair 4
this.addAbility(new RepairAbility(4));
}
public AstromechDroid(final AstromechDroid card) {
super(card);
}
@Override
public AstromechDroid copy() {
return new AstromechDroid(this);
}
}

View file

@ -16,6 +16,7 @@ import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterAbility; import mage.filter.FilterAbility;
import mage.filter.FilterStackObject;
import mage.filter.predicate.ability.ArtifactSourcePredicate; import mage.filter.predicate.ability.ArtifactSourcePredicate;
import mage.target.common.TargetActivatedAbility; import mage.target.common.TargetActivatedAbility;
@ -25,7 +26,7 @@ import mage.target.common.TargetActivatedAbility;
*/ */
public final class AyeshaTanaka extends CardImpl { public final class AyeshaTanaka extends CardImpl {
private final static FilterAbility filter = new FilterAbility("activated ability from an artifact source"); private final static FilterStackObject filter = new FilterStackObject("activated ability from an artifact source");
static { static {
filter.add(new ArtifactSourcePredicate()); filter.add(new ArtifactSourcePredicate());

View file

@ -0,0 +1,36 @@
package mage.cards.b;
import java.util.UUID;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class BludgeoningPain extends CardImpl {
public BludgeoningPain(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{B}");
// Target creature gets -2/-2 until end of turn. Tap that creature.
this.getSpellAbility().addEffect(new BoostTargetEffect(-2, -2, Duration.EndOfTurn));
this.getSpellAbility().addEffect(new TapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public BludgeoningPain(final BludgeoningPain card) {
super(card);
}
@Override
public BludgeoningPain copy() {
return new BludgeoningPain(this);
}
}

View file

@ -16,6 +16,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.common.TargetPlayerOrPlaneswalker;
/** /**
* *
@ -28,7 +29,7 @@ public final class BonfireOfTheDamned extends CardImpl {
// Bonfire of the Damned deals X damage to target player and each creature he or she controls. // Bonfire of the Damned deals X damage to target player and each creature he or she controls.
this.getSpellAbility().addEffect(new BonfireOfTheDamnedEffect()); this.getSpellAbility().addEffect(new BonfireOfTheDamnedEffect());
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
// Miracle {X}{R} // Miracle {X}{R}
this.addAbility(new MiracleAbility(this, new ManaCostsImpl("{X}{R}"))); this.addAbility(new MiracleAbility(this, new ManaCostsImpl("{X}{R}")));

View file

@ -0,0 +1,42 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetOpponent;
/**
*
* @author NinthWorld
*/
public final class BorGullet extends CardImpl {
public BorGullet(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{B}");
this.subtype.add(SubType.HORROR);
this.subtype.add(SubType.CEPHALID);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When Bor Gullet enters the battlefield, target opponent reveals his or her hand. You choose a card from it. That player discards that card.
Ability ability = new EntersBattlefieldTriggeredAbility(new DiscardCardYouChooseTargetEffect());
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
}
public BorGullet(final BorGullet card) {
super(card);
}
@Override
public BorGullet copy() {
return new BorGullet(this);
}
}

View file

@ -14,6 +14,7 @@ import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterAbility; import mage.filter.FilterAbility;
import mage.filter.FilterStackObject;
import mage.filter.predicate.ability.ArtifactSourcePredicate; import mage.filter.predicate.ability.ArtifactSourcePredicate;
import mage.target.common.TargetActivatedAbility; import mage.target.common.TargetActivatedAbility;
@ -23,7 +24,7 @@ import mage.target.common.TargetActivatedAbility;
*/ */
public final class BrownOuphe extends CardImpl { public final class BrownOuphe extends CardImpl {
private final static FilterAbility filter = new FilterAbility("activated ability from an artifact source"); private final static FilterStackObject filter = new FilterStackObject("activated ability from an artifact source");
static { static {
filter.add(new ArtifactSourcePredicate()); filter.add(new ArtifactSourcePredicate());

View file

@ -0,0 +1,48 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.BountyAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class CantoBightEnforcer extends CardImpl {
public CantoBightEnforcer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HUNTER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// When Canto Bight Enforcer enters the battlefield, you may put a bounty counter on target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), true);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// Bounty - Whenever a creature an opponent controls with a bounty counter on it dies, put a +1/+1 counter on Canto Bight Enforcer.
this.addAbility(new BountyAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance())));
}
public CantoBightEnforcer(final CantoBightEnforcer card) {
super(card);
}
@Override
public CantoBightEnforcer copy() {
return new CantoBightEnforcer(this);
}
}

View file

@ -0,0 +1,79 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.RollDiceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author NinthWorld
*/
public final class CantonicaCasino extends CardImpl {
public CantonicaCasino(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// {T}: Roll two six-sided dice. If you roll doubles, gain 10 life. Otherwise, lose 1 life.
this.addAbility(new SimpleActivatedAbility(new CantonicaCasinoEffect(), new TapSourceCost()));
}
public CantonicaCasino(final CantonicaCasino card) {
super(card);
}
@Override
public CantonicaCasino copy() {
return new CantonicaCasino(this);
}
}
class CantonicaCasinoEffect extends OneShotEffect {
public CantonicaCasinoEffect() {
super(Outcome.Neutral);
staticText = "Roll two six-sided dice. If you roll doubles, gain 10 life. Otherwise, lose 1 life";
}
public CantonicaCasinoEffect(final CantonicaCasinoEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
if(you != null) {
// Roll two six-sided dice
int dice1 = you.rollDice(game, 6);
int dice2 = you.rollDice(game, 6);
if(dice1 == dice2) {
// If you roll doubles, gain 10 life
you.gainLife(10, game, source);
return false;
}
else {
// Otherwise, lose 1 life
you.loseLife(1, game, false);
return false;
}
}
return false;
}
@Override
public CantonicaCasinoEffect copy() {
return new CantonicaCasinoEffect(this);
}
}

View file

@ -0,0 +1,67 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.permanent.token.TrooperToken;
import mage.target.common.TargetCardInLibrary;
/**
*
* @author NinthWorld
*/
public final class CaptainPhasma extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Nontoken trooper creatures");
private static final FilterCreatureCard filterCard = new FilterCreatureCard("Trooper card");
static {
filter.add(new SubtypePredicate(SubType.TROOPER));
filter.add(Predicates.not(new TokenPredicate()));
filterCard.add(new SubtypePredicate(SubType.TROOPER));
}
public CaptainPhasma(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.TROOPER);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Nontoken Trooper creatures you control have "When this creature enters the battlefield, create 1/1/ white Trooper creature token."
Ability ability = new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TrooperToken())
.setText("When this creature enters the battlefield, create a 1/1 white Trooper creature token"),
false, true);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityControlledEffect(ability, Duration.WhileOnBattlefield, filter, false)));
// {W}{U}{B}{R}{G}: Search your library for a Trooper creature card, reveal it, put it into your hand, then shuffle your library.
this.addAbility(new SimpleActivatedAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true, true), new ManaCostsImpl("{W}{U}{B}{R}{G}")));
}
public CaptainPhasma(final CaptainPhasma card) {
super(card);
}
@Override
public CaptainPhasma copy() {
return new CaptainPhasma(this);
}
}

View file

@ -19,7 +19,6 @@ import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game; import mage.game.Game;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker; import mage.target.common.TargetPlayerOrPlaneswalker;
@ -36,9 +35,9 @@ public final class ChandraNalaar extends CardImpl {
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6)); this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(6));
// +1: Chandra Nalaar deals 1 damage to target player. // +1: Chandra Nalaar deals 1 damage to target player or planeswalker.
LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1); LoyaltyAbility ability1 = new LoyaltyAbility(new DamageTargetEffect(1), 1);
ability1.addTarget(new TargetPlayer()); ability1.addTarget(new TargetPlayerOrPlaneswalker());
this.addAbility(ability1); this.addAbility(ability1);
// -X: Chandra Nalaar deals X damage to target creature. // -X: Chandra Nalaar deals X damage to target creature.
@ -46,7 +45,7 @@ public final class ChandraNalaar extends CardImpl {
ability2.addTarget(new TargetCreaturePermanent()); ability2.addTarget(new TargetCreaturePermanent());
this.addAbility(ability2); this.addAbility(ability2);
// -8: Chandra Nalaar deals 10 damage to target player and each creature he or she controls. // -8: Chandra Nalaar deals 10 damage to target player or planeswalker and each creature that player or that planeswalkers controller controls.
Effects effects1 = new Effects(); Effects effects1 = new Effects();
effects1.add(new DamageTargetEffect(10)); effects1.add(new DamageTargetEffect(10));
effects1.add(new DamageAllControlledTargetEffect(10, new FilterCreaturePermanent()) effects1.add(new DamageAllControlledTargetEffect(10, new FilterCreaturePermanent())

View file

@ -0,0 +1,60 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.IndestructibleAbility;
import mage.abilities.keyword.PartnerWithAbility;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherTargetPredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.filter.predicate.permanent.AttackingPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class ChewbaccaTheBeast extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another target attacking creature you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(new AnotherPredicate());
filter.add(new AttackingPredicate());
}
public ChewbaccaTheBeast(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}{G}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.WOOKIEE);
this.subtype.add(SubType.WARRIOR);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Partner with Han Solo, Scrumrat
this.addAbility(new PartnerWithAbility("Han Solo, Scrumrat"));
// Whenever Chewbacca, the Beast attacks, another target attacking creature you control gains indestructible until end of turn.
Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(IndestructibleAbility.getInstance(), Duration.EndOfTurn), false);
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}
public ChewbaccaTheBeast(final ChewbaccaTheBeast card) {
super(card);
}
@Override
public ChewbaccaTheBeast copy() {
return new ChewbaccaTheBeast(this);
}
}

View file

@ -0,0 +1,100 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.PreventCombatDamageToSourceEffect;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author NinthWorld
*/
public final class ChirrutImwe extends CardImpl {
public ChirrutImwe(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.MONK);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Chirrut Imwe can block up to two additional creatures.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ChirrutImweEffect()));
// {1}{W}: Prevent all combat damage that would be dealt to Chirrut Imwe until end of turn.
Effect effect = new PreventCombatDamageToSourceEffect(Duration.EndOfTurn);
effect.setText("Prevent all combat damage that would be dealt to {this} until end of turn");
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}{W}")));
}
public ChirrutImwe(final ChirrutImwe card) {
super(card);
}
@Override
public ChirrutImwe copy() {
return new ChirrutImwe(this);
}
}
class ChirrutImweEffect extends ContinuousEffectImpl {
public ChirrutImweEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit);
staticText = "{this} can block up to two additional creatures";
}
public ChirrutImweEffect(final ChirrutImweEffect effect) {
super(effect);
}
@Override
public ChirrutImweEffect copy() {
return new ChirrutImweEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent perm = game.getPermanent(source.getSourceId());
if(perm != null) {
switch(layer) {
case RulesEffects:
// maxBlocks = 0 equals to "can block any number of creatures"
if(perm.getMaxBlocks() > 0) {
perm.setMaxBlocks(perm.getMaxBlocks() + 2);
}
break;
}
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.RulesEffects;
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.combat.CantBlockAllEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.CounterPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class CodeSlice extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Artifact creatures with bounty counters on them");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
filter.add(new CounterPredicate(CounterType.BOUNTY));
}
public CodeSlice(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}");
// Put a bounty counter on target creature.
this.getSpellAbility().addEffect(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Artifact creatures with bounty counters on them can't block this turn.
this.getSpellAbility().addEffect(new CantBlockAllEffect(filter, Duration.EndOfTurn));
}
public CodeSlice(final CodeSlice card) {
super(card);
}
@Override
public CodeSlice copy() {
return new CodeSlice(this);
}
}

View file

@ -53,7 +53,7 @@ public final class CollectiveDefiance extends CardImpl {
mode.getTargets().add(new TargetCreaturePermanent(filterCreature)); mode.getTargets().add(new TargetCreaturePermanent(filterCreature));
this.getSpellAbility().addMode(mode); this.getSpellAbility().addMode(mode);
// Collective Defiance deals 3 damage to target opponent. // Collective Defiance deals 3 damage to target opponent or planeswalker.
mode = new Mode(); mode = new Mode();
effect = new DamageTargetEffect(3); effect = new DamageTargetEffect(3);
effect.setText("{this} deals 3 damage to target opponent or planeswalker"); effect.setText("{this} deals 3 damage to target opponent or planeswalker");

View file

@ -0,0 +1,49 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.effects.common.continuous.BecomesChosenCreatureTypeTargetEffect;
import mage.abilities.effects.common.continuous.BecomesCreatureTypeTargetEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Conscription extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with power 2 or less");
static {
filter.add(new PowerPredicate(ComparisonType.FEWER_THAN, 3));
}
public Conscription(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{U}");
// Gain control of target creature with power 2 or less. It becomes a Trooper in addition to its other types.
this.getSpellAbility().addEffect(new GainControlTargetEffect(Duration.EndOfGame));
this.getSpellAbility().addEffect(new BecomesCreatureTypeTargetEffect(Duration.EndOfGame, SubType.TROOPER, false)
.setText("It becomes a Trooper in addition to its other types"));
this.getSpellAbility().addTarget(new TargetCreaturePermanent(filter));
}
public Conscription(final Conscription card) {
super(card);
}
@Override
public Conscription copy() {
return new Conscription(this);
}
}

View file

@ -0,0 +1,45 @@
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetPlayerOrPlaneswalker;
/**
*
* @author NinthWorld
*/
public final class CorellianGunship extends CardImpl {
public CorellianGunship(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{R}");
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
// When Corellian Gunship enters the battlefield, it deals 1 damage to target player or planeswalker.
Ability ability = new EntersBattlefieldTriggeredAbility(new DamageTargetEffect(1));
ability.addTarget(new TargetPlayerOrPlaneswalker());
this.addAbility(ability);
}
public CorellianGunship(final CorellianGunship card) {
super(card);
}
@Override
public CorellianGunship copy() {
return new CorellianGunship(this);
}
}

View file

@ -15,7 +15,7 @@ import mage.constants.SubType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPlayer; import mage.target.common.TargetPlayerOrPlaneswalker;
/** /**
* *
@ -31,9 +31,9 @@ public final class CragganwickCremator extends CardImpl {
this.power = new MageInt(5); this.power = new MageInt(5);
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// When Cragganwick Cremator enters the battlefield, discard a card at random. If you discard a creature card this way, Cragganwick Cremator deals damage equal to that card's power to target player. // When Cragganwick Cremator enters the battlefield, discard a card at random. If you discard a creature card this way, Cragganwick Cremator deals damage equal to that card's power to target player or planeswalker.
Ability ability = new EntersBattlefieldTriggeredAbility(new CragganwickCrematorEffect(), false); Ability ability = new EntersBattlefieldTriggeredAbility(new CragganwickCrematorEffect(), false);
ability.addTarget(new TargetPlayer()); ability.addTarget(new TargetPlayerOrPlaneswalker());
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -0,0 +1,215 @@
/*
* 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.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.SpecialAction;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledPermanent;
/**
*
* @author jeffwadsworth
*/
public class DampingEngine extends CardImpl {
public DampingEngine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// A player who controls more permanents than each other player can't play lands or cast artifact, creature, or enchantment spells. That player may sacrifice a permanent for that player to ignore this effect until end of turn.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new DampingEngineEffect()));
this.addAbility(new DampingEngineSpecialAction());
}
public DampingEngine(final DampingEngine card) {
super(card);
}
@Override
public DampingEngine copy() {
return new DampingEngine(this);
}
}
class DampingEngineEffect extends ContinuousRuleModifyingEffectImpl {
public DampingEngineEffect() {
super(Duration.WhileOnBattlefield, Outcome.AIDontUseIt);
staticText = "A player who controls more permanents than each other player can't play lands or cast artifact, creature, or enchantment spells"
+ "That player may sacrifice a permanent for that player to ignore this effect until end of turn.<br><br>";
}
public DampingEngineEffect(final DampingEngineEffect effect) {
super(effect);
}
@Override
public DampingEngineEffect copy() {
return new DampingEngineEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) {
return "You can't play the land or cast the spell (" + mageObject.getName() + " in play).";
}
return null;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.PLAY_LAND
|| event.getType() == GameEvent.EventType.CAST_SPELL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(event.getPlayerId());
Permanent dampingEngine = game.getPermanent(source.getSourceId());
final Card card = game.getCard(event.getSourceId());
if (player != null
|| card != null) {
// check type of spell
if (card.isCreature()
|| card.isArtifact()
|| card.isEnchantment()
|| card.isLand()) {
// check to see if the player has more permanents
if (new ControlsMorePermanentsThanEachOtherPlayer(player).apply(game, source)) {
// check to see if the player choose to ignore the effect
if (game.getState().getValue("ignoreEffect") != null
&& dampingEngine != null
&& game.getState().getValue("ignoreEffect").equals
(dampingEngine.getId() + "ignoreEffect" + game.getState().getPriorityPlayerId() + game.getState().getTurnNum())) {
return false;
}
return true;
}
}
}
return false;
}
}
class DampingEngineSpecialAction extends SpecialAction {
public DampingEngineSpecialAction() {
super(Zone.BATTLEFIELD);
this.addCost(new SacrificeTargetCost(new TargetControlledPermanent(), true));
this.addEffect(new DampingEngineIgnoreEffect());
this.setMayActivate(TargetController.ANY);
}
public DampingEngineSpecialAction(final DampingEngineSpecialAction ability) {
super(ability);
}
@Override
public DampingEngineSpecialAction copy() {
return new DampingEngineSpecialAction(this);
}
}
class DampingEngineIgnoreEffect extends OneShotEffect {
public DampingEngineIgnoreEffect() {
super(Outcome.AIDontUseIt);
this.staticText = "That player may sacrifice a permanent for that player to ignore this effect until end of turn";
}
public DampingEngineIgnoreEffect(final DampingEngineIgnoreEffect effect) {
super(effect);
}
@Override
public DampingEngineIgnoreEffect copy() {
return new DampingEngineIgnoreEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
String key = permanent.getId() + "ignoreEffect" + game.getState().getPriorityPlayerId() + game.getState().getTurnNum();
if (key != null) {
game.getState().setValue("ignoreEffect", key);
}
return true;
}
}
class ControlsMorePermanentsThanEachOtherPlayer implements Condition {
Player player;
public ControlsMorePermanentsThanEachOtherPlayer(Player player) {
this.player = player;
}
@Override
public boolean apply(Game game, Ability source) {
int numPermanents = game.getBattlefield().countAll(new FilterPermanent(), player.getId(), game);
for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
if (numPermanents > game.getBattlefield().countAll(new FilterPermanent(), playerId, game)) {
return true;
}
}
return false;
}
@Override
public String toString() {
return "a player controls less permanents than you";
}
}

View file

@ -31,9 +31,9 @@ import mage.target.common.TargetCreaturePermanent;
* *
* @author Styxo * @author Styxo
*/ */
public final class DarthTyranus extends CardImpl { public final class DarthTyranusCountOfSerenno extends CardImpl {
public DarthTyranus(UUID ownerId, CardSetInfo setInfo) { public DarthTyranusCountOfSerenno(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{1}{W}{U}{B}"); super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{1}{W}{U}{B}");
this.subtype.add(SubType.DOOKU); this.subtype.add(SubType.DOOKU);
@ -55,13 +55,13 @@ public final class DarthTyranus extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
} }
public DarthTyranus(final DarthTyranus card) { public DarthTyranusCountOfSerenno(final DarthTyranusCountOfSerenno card) {
super(card); super(card);
} }
@Override @Override
public DarthTyranus copy() { public DarthTyranusCountOfSerenno copy() {
return new DarthTyranus(this); return new DarthTyranusCountOfSerenno(this);
} }
} }

View file

@ -0,0 +1,91 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.DontUntapInPlayersNextUntapStepAllEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author NinthWorld
*/
public final class DelayTactic extends CardImpl {
public DelayTactic(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Choose one -
// Creatures you control gain hexproof until end of turn.
this.getSpellAbility().addEffect(new GainAbilityAllEffect(HexproofAbility.getInstance(), Duration.EndOfTurn, new FilterControlledCreaturePermanent())
.setText("Creatures you control gain hexproof until end of turn"));
// Creatures target opponent controls don't untap during his or her next untap step.
Mode mode = new Mode();
mode.getEffects().add(new DelayTacticEffect());
mode.getTargets().add(new TargetOpponent());
this.getSpellAbility().addMode(mode);
}
public DelayTactic(final DelayTactic card) {
super(card);
}
@Override
public DelayTactic copy() {
return new DelayTactic(this);
}
}
// Based on ManaVaporsEffect
class DelayTacticEffect extends OneShotEffect {
DelayTacticEffect() {
super(Outcome.Benefit);
this.staticText = "Creatures target opponent controls don't untap during his or her next untap step";
}
DelayTacticEffect(final DelayTacticEffect effect) {
super(effect);
}
@Override
public DelayTacticEffect copy() {
return new DelayTacticEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
if (targetPlayer != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new ControllerIdPredicate(targetPlayer.getId()));
ContinuousEffect effect = new DontUntapInPlayersNextUntapStepAllEffect(filter);
effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
game.addEffect(effect, source);
return true;
}
return false;
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.effects.common.SacrificeControllerEffect;
import mage.abilities.effects.common.SacrificeOpponentsEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterControlledCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Despair extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("creature");
public Despair(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{B}");
// Each opponent sacrifices a creature.
this.getSpellAbility().addEffect(new SacrificeOpponentsEffect(filter));
}
public Despair(final Despair card) {
super(card);
}
@Override
public Despair copy() {
return new Despair(this);
}
}

View file

@ -17,6 +17,7 @@ import mage.constants.Duration;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.permanent.token.TokenImpl; import mage.game.permanent.token.TokenImpl;
import mage.game.permanent.token.Token; import mage.game.permanent.token.Token;
import mage.game.permanent.token.custom.CreatureToken;
/** /**
* *
@ -32,7 +33,12 @@ public final class DimirKeyrune extends CardImpl {
this.addAbility(new BlackManaAbility()); this.addAbility(new BlackManaAbility());
// {U}{B}: Dimir Keyrune becomes a 2/2 blue and black Horror and can't be blocked this turn // {U}{B}: Dimir Keyrune becomes a 2/2 blue and black Horror and can't be blocked this turn
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(new DimirKeyruneToken(), "", Duration.EndOfTurn), new ManaCostsImpl("{U}{B}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureSourceEffect(
new CreatureToken(2, 2, "2/2 blue and black Horror creature that can't be blocked")
.withColor("UB")
.withSubType(SubType.HORROR)
.withAbility(new CantBeBlockedSourceAbility()),
"", Duration.EndOfTurn), new ManaCostsImpl("{U}{B}")));
} }
public DimirKeyrune(final DimirKeyrune card) { public DimirKeyrune(final DimirKeyrune card) {
@ -43,25 +49,4 @@ public final class DimirKeyrune extends CardImpl {
public DimirKeyrune copy() { public DimirKeyrune copy() {
return new DimirKeyrune(this); return new DimirKeyrune(this);
} }
private static class DimirKeyruneToken extends TokenImpl {
DimirKeyruneToken() {
super("Horror", "2/2 blue and black Horror until end of turn and can't be blocked this turn");
cardType.add(CardType.ARTIFACT);
cardType.add(CardType.CREATURE);
color.setBlue(true);
color.setBlack(true);
subtype.add(SubType.HORROR);
power = new MageInt(2);
toughness = new MageInt(2);
this.addAbility(new CantBeBlockedSourceAbility());
}
public DimirKeyruneToken(final DimirKeyruneToken token) {
super(token);
}
public DimirKeyruneToken copy() {
return new DimirKeyruneToken(this);
}
}
} }

View file

@ -0,0 +1,60 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.game.permanent.token.TrooperToken2;
import mage.target.TargetPermanent;
/**
*
* @author NinthWorld
*/
public final class DirectorKrennic extends CardImpl {
private static final FilterPermanent filterLand = new FilterPermanent("basic land");
static {
filterLand.add(new CardTypePredicate(CardType.LAND));
filterLand.add(new SupertypePredicate(SuperType.BASIC));
}
public DirectorKrennic(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ADVISOR);
this.power = new MageInt(3);
this.toughness = new MageInt(4);
// When Director Krennic enters the battlefield, create two 1/1 black Trooper creature tokens.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TrooperToken2(), 2)));
// When Director Krennic leaves the battlefield, destroy target basic land.
Ability ability = new LeavesBattlefieldTriggeredAbility(new DestroyTargetEffect(), false);
ability.addTarget(new TargetPermanent(filterLand));
this.addAbility(ability);
}
public DirectorKrennic(final DirectorKrennic card) {
super(card);
}
@Override
public DirectorKrennic copy() {
return new DirectorKrennic(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.d;
import java.util.UUID;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.TapAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.permanent.token.DroidToken;
/**
*
* @author NinthWorld
*/
public final class DroidUprising extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonartifact creatures");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.ARTIFACT)));
}
public DroidUprising(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W}{W}");
// Tap all nonartifact creatures.
this.getSpellAbility().addEffect(new TapAllEffect(filter));
// Create two colorless 1/1 Droid artifact creature tokens.
this.getSpellAbility().addEffect(new CreateTokenEffect(new DroidToken(), 2));
}
public DroidUprising(final DroidUprising card) {
super(card);
}
@Override
public DroidUprising copy() {
return new DroidUprising(this);
}
}

View file

@ -0,0 +1,57 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.BountyAbility;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.target.common.TargetAnyTarget;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class DrydenVos extends CardImpl {
public DrydenVos(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Menace
this.addAbility(new MenaceAbility());
// When Dryden Vos enters the battlefield, put a bounty counter on target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// Bounty - Whenever a creature an opponent controls with a bounty counter on it dies, Dryden Vos deals 2 damage to any target.
Ability ability2 = new BountyAbility(new DamageTargetEffect(2));
ability2.addTarget(new TargetAnyTarget());
this.addAbility(ability2);
}
public DrydenVos(final DrydenVos card) {
super(card);
}
@Override
public DrydenVos copy() {
return new DrydenVos(this);
}
}

View file

@ -18,6 +18,7 @@ import mage.counters.Counter;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.Filter; import mage.filter.Filter;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.CardCounterPredicate; import mage.filter.predicate.permanent.CardCounterPredicate;
import mage.filter.predicate.permanent.CounterPredicate; import mage.filter.predicate.permanent.CounterPredicate;
import mage.game.Game; import mage.game.Game;
@ -59,13 +60,13 @@ public final class DustOfMoments extends CardImpl {
public abstract static class DustOfMomentsEffect extends OneShotEffect { public abstract static class DustOfMomentsEffect extends OneShotEffect {
private final Counter counter; private final Counter counter;
private final Filter<Card> permFilter; private final Filter<Permanent> permFilter;
private final Filter<Card> exiledFilter; private final Filter<Card> exiledFilter;
public DustOfMomentsEffect() { public DustOfMomentsEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.counter = new Counter(CounterType.TIME.getName(), 2); this.counter = new Counter(CounterType.TIME.getName(), 2);
this.permFilter = new FilterCard("permanent and each suspended card"); this.permFilter = new FilterPermanent("permanent and each suspended card");
permFilter.add(new CounterPredicate(CounterType.TIME)); permFilter.add(new CounterPredicate(CounterType.TIME));
this.exiledFilter = new FilterCard("permanent and each suspended card"); this.exiledFilter = new FilterCard("permanent and each suspended card");

View file

@ -0,0 +1,116 @@
package mage.cards.e;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.RevealSecretOpponentCost;
import mage.abilities.effects.EntersBattlefieldEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseSecretOpponentEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetStackObject;
import java.util.UUID;
/**
*
* @author credman0
*/
public class EmissaryOfGrudges extends CardImpl {
public EmissaryOfGrudges(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}");
this.subtype.add(SubType.EFREET);
this.power = new MageInt(6);
this.toughness = new MageInt(5);
// flying
this.addAbility(FlyingAbility.getInstance());
// haste
this.addAbility(HasteAbility.getInstance());
// As Emissary of Grudges enters the battlefield, secretly choose an opponent.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new EntersBattlefieldEffect(new ChooseSecretOpponentEffect(),"As {this} enters the battlefield, secretly choose an opponent.")));
// Choose new targets for target spell or ability if its controlled by the chosen player and if it targets you
// or a permanent you control. Activate this ability only once.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EmissaryOfGrudgesEffect(), new RevealSecretOpponentCost());
ability.addTarget(new TargetStackObject());
this.addAbility(ability);
}
public EmissaryOfGrudges(final EmissaryOfGrudges card) {
super(card);
}
@Override
public EmissaryOfGrudges copy() {
return new EmissaryOfGrudges(this);
}
}
class EmissaryOfGrudgesEffect extends OneShotEffect {
public EmissaryOfGrudgesEffect() {
super(Outcome.Neutral);
this.staticText = "Choose new targets for target spell or ability if its controlled by the chosen player and" +
" if it targets you or a permanent you control. Activate this ability only once.";
}
public EmissaryOfGrudgesEffect(final EmissaryOfGrudgesEffect effect) {
super(effect);
}
@Override
public EmissaryOfGrudgesEffect copy() {
return new EmissaryOfGrudgesEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
if (stackObject != null) {
UUID opponentId = (UUID) game.getState().getValue(source.getSourceId() + ChooseSecretOpponentEffect.SECRET_OPPONENT);
if (opponentId != null && opponentId.equals(stackObject.getControllerId())) {
// find if it targets you or a permanent you control
boolean targetsYouOrAPermanentYouControl = false;
for (UUID modeId : stackObject.getStackAbility().getModes().getSelectedModes()) {
Mode mode = stackObject.getStackAbility().getModes().get(modeId);
for (Target target : mode.getTargets()) {
for (UUID targetId : target.getTargets()) {
if (source.getControllerId().equals(targetId)) {
targetsYouOrAPermanentYouControl = true;
}
Permanent permanent = game.getPermanent(targetId);
if (permanent != null && source.getControllerId().equals(permanent.getControllerId())) {
targetsYouOrAPermanentYouControl = true;
}
}
}
}
if (targetsYouOrAPermanentYouControl){
return stackObject.chooseNewTargets(game, source.getControllerId(), false, false, null);
}
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,88 @@
package mage.cards.e;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetOpponentsCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class EnfysNest extends CardImpl {
public EnfysNest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.REBEL);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Whenever Enfys Nest enters the battlefield, you may exile target creature an opponent controls. If you do, that player gains life equal to that creature's power.
Ability ability = new EntersBattlefieldTriggeredAbility(new EnfysNestEffect(), true);
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
}
public EnfysNest(final EnfysNest card) {
super(card);
}
@Override
public EnfysNest copy() {
return new EnfysNest(this);
}
}
class EnfysNestEffect extends ExileTargetEffect {
public EnfysNestEffect() {
super();
staticText = "you may exile target creature an opponent controls. If you do, that player gains life equal to that creature's power";
}
public EnfysNestEffect(final EnfysNestEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getFirstTarget());
if(permanent != null) {
// you may exile target creature an opponent controls
if(!super.apply(game, source)) {
return false;
}
// If you do, that player gains life equal to that creature's power.
Player player = game.getPlayer(permanent.getControllerId());
player.gainLife(permanent.getPower().getValue(), game, source);
return true;
}
return false;
}
@Override
public EnfysNestEffect copy() {
return new EnfysNestEffect(this);
}
}

View file

@ -12,7 +12,7 @@ import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.common.FilterControlledPermanent; import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponentOrPlaneswalker;
/** /**
* *
@ -32,7 +32,7 @@ public final class EternalFlame extends CardImpl {
// Eternal Flame deals X damage to target opponent, where X is the number of Mountains you control. It deals half X damage, rounded up, to you.); // Eternal Flame deals X damage to target opponent, where X is the number of Mountains you control. It deals half X damage, rounded up, to you.);
this.getSpellAbility().addEffect(new DamageTargetEffect(new PermanentsOnBattlefieldCount(filter)).setText("{this} deals X damage to target opponent, where X is the number of Mountains you control")); this.getSpellAbility().addEffect(new DamageTargetEffect(new PermanentsOnBattlefieldCount(filter)).setText("{this} deals X damage to target opponent, where X is the number of Mountains you control"));
this.getSpellAbility().addEffect(new DamageControllerEffect(new HalfValue(new PermanentsOnBattlefieldCount(filter), true)).setText("It deals half X damage, rounded up, to you")); this.getSpellAbility().addEffect(new DamageControllerEffect(new HalfValue(new PermanentsOnBattlefieldCount(filter), true)).setText("It deals half X damage, rounded up, to you"));
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponentOrPlaneswalker());
} }
public EternalFlame(final EternalFlame card) { public EternalFlame(final EternalFlame card) {

View file

@ -0,0 +1,40 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.MonstrosityAbility;
import mage.constants.SubType;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author NinthWorld
*/
public final class Fathier extends CardImpl {
public Fathier(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Haste
this.addAbility(HasteAbility.getInstance());
// {4}{R}{R}: Monstrosity 2.
this.addAbility(new MonstrosityAbility("{4}{R}{R}", 2));
}
public Fathier(final Fathier card) {
super(card);
}
@Override
public Fathier copy() {
return new Fathier(this);
}
}

View file

@ -91,7 +91,7 @@ class FieldOfRuinEffect extends OneShotEffect {
if (player != null) { if (player != null) {
TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND); TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND);
if (player.searchLibrary(target, game)) { if (player.searchLibrary(target, game)) {
player.moveCards(new CardsImpl(target.getTargets()), Zone.BATTLEFIELD, source, game); player.moveCards(new CardsImpl(target.getTargets()).getCards(game), Zone.BATTLEFIELD, source, game);
player.shuffleLibrary(source, game); player.shuffleLibrary(source, game);
} }
} }

View file

@ -0,0 +1,59 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.GainLifeEffect;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Finn extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("{this} or another nontoken creature you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(Predicates.not(new TokenPredicate()));
}
public Finn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.TROOPER);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Finn or another nontoken creature you control enters the battlefield under your control, you gain 1 life for each nontoken creature you control.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD,
new GainLifeEffect(new PermanentsOnBattlefieldCount(filter))
.setText("you gain 1 life for each nontoken creature you control"),
filter, false));
}
public Finn(final Finn card) {
super(card);
}
@Override
public Finn copy() {
return new Finn(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class FirstOrderDreadnought extends CardImpl {
public FirstOrderDreadnought(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{B}{B}");
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(5);
this.toughness = new MageInt(6);
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
// {2}{B}, {T}: Destroy target creature.
Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new ManaCostsImpl("{2}{B}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public FirstOrderDreadnought(final FirstOrderDreadnought card) {
super(card);
}
@Override
public FirstOrderDreadnought copy() {
return new FirstOrderDreadnought(this);
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author NinthWorld
*/
public final class FlameTrooper extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Trooper creatures");
static {
filter.add(new SubtypePredicate(SubType.TROOPER));
}
public FlameTrooper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.TROOPER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Trooper creatures you control have menace.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(new MenaceAbility(), Duration.WhileOnBattlefield, filter, false)));
}
public FlameTrooper(final FlameTrooper card) {
super(card);
}
@Override
public FlameTrooper copy() {
return new FlameTrooper(this);
}
}

View file

@ -0,0 +1,95 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BecomesTargetTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterSpell;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author NinthWorld
*/
public final class ForceProjection extends CardImpl {
public ForceProjection(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}{U}");
// Create a token that is a copy of target creature you control except that it is an Illusion in addition to its other types and gains "When this creature becomes the target of a spell, sacrifice it."
this.getSpellAbility().addEffect(new ForceProjectionEffect());
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent());
// Scry 2.
this.getSpellAbility().addEffect(new ScryEffect(2));
}
public ForceProjection(final ForceProjection card) {
super(card);
}
@Override
public ForceProjection copy() {
return new ForceProjection(this);
}
}
class ForceProjectionEffect extends OneShotEffect {
public ForceProjectionEffect() {
super(Outcome.Copy);
this.staticText = "Create a token that is a copy of target creature you control except that it is an Illusion " +
"in addition to its other types and gains \"When this creature becomes the target of a spell, sacrifice it.\"";
}
public ForceProjectionEffect(final ForceProjectionEffect effect) {
super(effect);
}
@Override
public ForceProjectionEffect copy() {
return new ForceProjectionEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanentOrLKIBattlefield(getTargetPointer().getFirst(game, source));
if (controller != null && permanent != null) {
// Create a token that is a copy of target creature
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, true);
effect.setTargetPointer(new FixedTarget(permanent, game));
// except that it is an Illusion in addition to its other types
effect.setAdditionalSubType(SubType.SPIRIT);
effect.apply(game, source);
// and gains "When this creature becomes the target of a spell, sacrifice it."
Effect sacrificeEffect = new SacrificeSourceEffect();
sacrificeEffect.setTargetPointer(new FixedTarget(effect.getAddedPermanent().get(0), game));
TriggeredAbility ability = new BecomesTargetTriggeredAbility(sacrificeEffect, new FilterSpell());
game.addTriggeredAbility(ability);
return true;
}
return false;
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.effects.common.continuous.GainProtectionFromColorTargetEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class ForceProtection extends CardImpl {
public ForceProtection(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{W}");
// Target creature you control gains protection from color of your choice until end of turn. Scry 1.
this.getSpellAbility().addEffect(new GainProtectionFromColorTargetEffect(Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new ScryEffect(1));
}
public ForceProtection(final ForceProtection card) {
super(card);
}
@Override
public ForceProtection copy() {
return new ForceProtection(this);
}
}

View file

@ -0,0 +1,59 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.Mode;
import mage.abilities.effects.common.DontUntapInControllersNextUntapStepTargetEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.filter.FilterSpell;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.TargetSpell;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class ForceStasis extends CardImpl {
private static final FilterSpell filter = new FilterSpell("instant or sorcery spell you don't control");
static {
filter.add(new ControllerPredicate(TargetController.NOT_YOU));
filter.add(new CardTypePredicate(CardType.INSTANT));
filter.add(new CardTypePredicate(CardType.SORCERY));
}
public ForceStasis(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Choose one -
// Tap target creature. It doesn't untap during its controller's next untap step.
getSpellAbility().addEffect(new TapTargetEffect());
getSpellAbility().addEffect(new DontUntapInControllersNextUntapStepTargetEffect()
.setText("It doesn't untap during its controller's next untap step"));
getSpellAbility().addTarget(new TargetCreaturePermanent());
// Return target instant or sorcery spell you don't control to its owner's hand.
Mode mode = new Mode();
mode.getEffects().add(new ReturnToHandTargetEffect());
mode.getTargets().add(new TargetSpell(filter));
this.getSpellAbility().addMode(mode);
}
public ForceStasis(final ForceStasis card) {
super(card);
}
@Override
public ForceStasis copy() {
return new ForceStasis(this);
}
}

View file

@ -0,0 +1,38 @@
package mage.cards.f;
import java.util.UUID;
import mage.abilities.effects.common.RevealHandTargetEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.TargetPlayer;
/**
*
* @author NinthWorld
*/
public final class ForceTelepathy extends CardImpl {
public ForceTelepathy(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{U/B}");
// Target player reveals his or her hand.
this.getSpellAbility().addEffect(new RevealHandTargetEffect().setText("Target player reveals his or her hand"));
this.getSpellAbility().addTarget(new TargetPlayer());
// Scry 2
this.getSpellAbility().addEffect(new ScryEffect(2));
}
public ForceTelepathy(final ForceTelepathy card) {
super(card);
}
@Override
public ForceTelepathy copy() {
return new ForceTelepathy(this);
}
}

View file

@ -66,7 +66,7 @@ class FumbleEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getTargets().getFirstTarget());
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(source.getControllerId());
if (player == null || permanent == null) { if (player == null || permanent == null) {
return false; return false;
@ -75,24 +75,30 @@ class FumbleEffect extends OneShotEffect {
for (UUID permId : permanent.getAttachments()) { for (UUID permId : permanent.getAttachments()) {
Permanent attachment = game.getPermanent(permId); Permanent attachment = game.getPermanent(permId);
if (attachment != null) { if (attachment != null) {
attachments.add(permanent); if (attachment.hasSubtype(SubType.AURA, game) || attachment.hasSubtype(SubType.EQUIPMENT, game)) {
attachments.add(attachment);
}
} }
} }
new ReturnToHandTargetEffect().apply(game, source); new ReturnToHandTargetEffect().apply(game, source);
Target target = new TargetCreaturePermanent(1, 1, StaticFilters.FILTER_PERMANENT_CREATURE, true);
Permanent newCreature = null; if (!attachments.isEmpty()) {
if (player.choose(Outcome.BoostCreature, target, source.getSourceId(), game)) { Target target = new TargetCreaturePermanent(1, 1, StaticFilters.FILTER_PERMANENT_CREATURE, true);
newCreature = game.getPermanent(target.getFirstTarget()); Permanent newCreature = null;
} if (player.choose(Outcome.BoostCreature, target, source.getSourceId(), game)) {
for (Permanent attachment : attachments) { newCreature = game.getPermanent(target.getFirstTarget());
if (!attachment.hasSubtype(SubType.AURA, game) && !attachment.hasSubtype(SubType.EQUIPMENT, game)) {
continue;
} }
ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, true, player.getId()); for (Permanent attachment : attachments) {
effect.setTargetPointer(new FixedTarget(attachment, game)); if (!attachment.hasSubtype(SubType.AURA, game) && !attachment.hasSubtype(SubType.EQUIPMENT, game)) {
game.addEffect(effect, source); continue;
if (newCreature != null) { }
attachment.attachTo(newCreature.getId(), game); ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, true, player.getId());
effect.setTargetPointer(new FixedTarget(attachment, game));
game.addEffect(effect, source);
if (newCreature != null) {
attachment.attachTo(newCreature.getId(), game);
}
} }
} }
return true; return true;

View file

@ -0,0 +1,62 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
/**
*
* @author NinthWorld
*/
public final class GeneralHux extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("{this} or another nontoken creature you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(Predicates.not(new TokenPredicate()));
}
public GeneralHux(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ADVISOR);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever General Hux or another nontoken creature enters the battlefield under your control, until end of turn, target creature gains "{B}: This creature gets +1/+1 until end of turn."
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new BoostSourceEffect(1, 1, Duration.EndOfTurn)
.setText("This creature gets +1/+1 until end of turn"),
new ManaCostsImpl("{B}"));
Effect effect = new GainAbilitySourceEffect(ability, Duration.EndOfTurn);
effect.setText("until end of turn, target creature gains");
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, effect, filter, false));
}
public GeneralHux(final GeneralHux card) {
super(card);
}
@Override
public GeneralHux copy() {
return new GeneralHux(this);
}
}

View file

@ -0,0 +1,107 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author spjspj
*/
public final class GeodeGolem extends CardImpl {
public GeodeGolem(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{5}");
this.subtype.add(SubType.GOLEM);
this.power = new MageInt(5);
this.toughness = new MageInt(3);
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever Geode Golem deals combat damage to a player, you may cast your commander from the command zone without paying its mana cost.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new GeodeGolemEffect(), true));
}
public GeodeGolem(final GeodeGolem card) {
super(card);
}
@Override
public GeodeGolem copy() {
return new GeodeGolem(this);
}
}
class GeodeGolemEffect extends OneShotEffect {
public GeodeGolemEffect() {
super(Outcome.PlayForFree);
staticText = "you may cast your commander from the command zone without paying its mana cost";
}
public GeodeGolemEffect(final GeodeGolemEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
for (UUID commanderId : controller.getCommandersIds()) {
if (game.getState().getZone(commanderId) == Zone.COMMAND) {
Card commander = game.getCard(commanderId);
if (commander != null && game.getState().getZone(commanderId) == Zone.COMMAND) {
SpellAbility ability = commander.getSpellAbility();
SpellAbility newAbility = commander.getSpellAbility().copy();
newAbility.getCosts().clear();
Integer castCount = (Integer) game.getState().getValue(commander.getId() + "_castCount");
Cost cost = null;
if (castCount > 0) {
cost = new GenericManaCost(castCount * 2);
}
if ((castCount == 0 || castCount > 0 && cost.pay(source, game, source.getSourceId(), controller.getId(), false, null))
&& controller.cast(newAbility, game, true, new MageObjectReference(source.getSourceObject(game), game))) {
// save amount of times commander was cast
if (castCount == null) {
castCount = 1;
} else {
castCount++;
}
game.getState().setValue(commander.getId() + "_castCount", castCount);
return true;
}
}
}
}
return true;
}
return false;
}
@Override
public GeodeGolemEffect copy() {
return new GeodeGolemEffect(this);
}
}

View file

@ -0,0 +1,37 @@
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksEachCombatStaticAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author NinthWorld
*/
public final class GerrerasRevolutionary extends CardImpl {
public GerrerasRevolutionary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}");
this.subtype.add(SubType.BARABEL);
this.subtype.add(SubType.REBEL);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Gerrera's Revolutionary attacks each turn if able.
this.addAbility(new AttacksEachCombatStaticAbility());
}
public GerrerasRevolutionary(final GerrerasRevolutionary card) {
super(card);
}
@Override
public GerrerasRevolutionary copy() {
return new GerrerasRevolutionary(this);
}
}

View file

@ -0,0 +1,63 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.effects.common.combat.MustBeBlockedByTargetSourceEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class HammerheadCorvette extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Starship creature defending player controls");
static {
filter.add(new SubtypePredicate(SubType.STARSHIP));
filter.add(new DefendingPlayerControlsPredicate());
}
public HammerheadCorvette(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{G}");
this.subtype.add(SubType.REBEL);
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
// Whenever Hammerhead Corvette attacks, you may untap target Starship creature defending player controls and have that creature block Hammerhead Corvette this turn if able.
Effect effect1 = new UntapTargetEffect();
Effect effect2 = new MustBeBlockedByTargetSourceEffect(Duration.EndOfTurn);
Ability ability = new AttacksTriggeredAbility(effect1, true,
"Whenever {this} attacks, you may uptap target Starship creature defending player controls and have that creature block {this} this turn if able");
ability.addEffect(effect2);
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}
public HammerheadCorvette(final HammerheadCorvette card) {
super(card);
}
@Override
public HammerheadCorvette copy() {
return new HammerheadCorvette(this);
}
}

View file

@ -0,0 +1,102 @@
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.*;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.PartnerWithAbility;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.counters.CounterType;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class HanSoloScrumrat extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("another target creature you control");
static {
filter.add(new AnotherPredicate());
}
public HanSoloScrumrat(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Partner with Chewbacca, the Beast
this.addAbility(new PartnerWithAbility("Chewbacca, the Beast"));
// R: Han Solo, Scrumrat gains first strike until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), new ManaCostsImpl("{R}")));
// Whenever Han Solo, Scrumrat deals damage during your turn, put a +1/+1 counter on another target creature you control.
Ability ability = new HanSoloScrumratTriggeredAbility();
ability.addTarget(new TargetControlledCreaturePermanent(filter));
this.addAbility(ability);
}
public HanSoloScrumrat(final HanSoloScrumrat card) {
super(card);
}
@Override
public HanSoloScrumrat copy() {
return new HanSoloScrumrat(this);
}
}
class HanSoloScrumratTriggeredAbility extends TriggeredAbilityImpl {
public HanSoloScrumratTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false);
}
public HanSoloScrumratTriggeredAbility(final HanSoloScrumratTriggeredAbility ability) {
super(ability);
}
@Override
public HanSoloScrumratTriggeredAbility copy() {
return new HanSoloScrumratTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_CREATURE
|| event.getType() == GameEvent.EventType.DAMAGED_PLAYER
|| event.getType() == GameEvent.EventType.DAMAGED_PLANESWALKER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent source = game.getPermanent(this.getSourceId());
return source != null
&& game.isActivePlayer(source.getControllerId())
&& event.getSourceId().equals(this.getSourceId());
}
@Override
public String getRule() {
return "Whenever {this} creature deals damage during your turn, " + super.getRule();
}
}

View file

@ -0,0 +1,84 @@
package mage.cards.i;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author NinthWorld
*/
public final class ImperialHovertank extends CardImpl {
public ImperialHovertank(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}{W}{B}");
this.subtype.add(SubType.TROOPER);
this.subtype.add(SubType.CONSTRUCT);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Whenever a Trooper creature you control attacks, defending player loses 1 life and you gain 1 life.
this.addAbility(new ImperialHovertankTriggeredAbility());
}
public ImperialHovertank(final ImperialHovertank card) {
super(card);
}
@Override
public ImperialHovertank copy() {
return new ImperialHovertank(this);
}
}
class ImperialHovertankTriggeredAbility extends TriggeredAbilityImpl {
public ImperialHovertankTriggeredAbility() {
super(Zone.BATTLEFIELD, new LoseLifeTargetEffect(1));
this.addEffect(new GainLifeEffect(1));
}
public ImperialHovertankTriggeredAbility(final ImperialHovertankTriggeredAbility ability) {
super(ability);
}
@Override
public ImperialHovertankTriggeredAbility copy() {
return new ImperialHovertankTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ATTACKER_DECLARED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent source = game.getPermanent(event.getSourceId());
if (source != null && source.isControlledBy(controllerId) && source.hasSubtype(SubType.TROOPER, game)) {
UUID defendingPlayerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game);
this.getEffects().get(0).setTargetPointer(new FixedTarget(defendingPlayerId));
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever a Trooper creature you control attacks, defending player loses 1 life and you gain 1 life.";
}
}

View file

@ -0,0 +1,39 @@
package mage.cards.i;
import java.util.UUID;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.UntapTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Inspire extends CardImpl {
public Inspire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}");
// Untap target creature.
this.getSpellAbility().addEffect(new UntapTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1));
}
public Inspire(final Inspire card) {
super(card);
}
@Override
public Inspire copy() {
return new Inspire(this);
}
}

View file

@ -19,6 +19,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.StackAbility; import mage.game.stack.StackAbility;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.target.common.TargetActivatedAbility;
import mage.target.common.TargetActivatedOrTriggeredAbility; import mage.target.common.TargetActivatedOrTriggeredAbility;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
@ -39,7 +40,7 @@ public final class Interdict extends CardImpl {
// Counter target activated ability from an artifact, creature, enchantment, or land. That permanent's activated abilities can't be activated this turn. // Counter target activated ability from an artifact, creature, enchantment, or land. That permanent's activated abilities can't be activated this turn.
this.getSpellAbility().addEffect(new InterdictCounterEffect()); this.getSpellAbility().addEffect(new InterdictCounterEffect());
this.getSpellAbility().addTarget(new TargetActivatedOrTriggeredAbility(filter)); this.getSpellAbility().addTarget(new TargetActivatedAbility(filter));
// Draw a card. // Draw a card.
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("<br><br>Draw a card")); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("<br><br>Draw a card"));
@ -55,15 +56,15 @@ public final class Interdict extends CardImpl {
} }
} }
class InterdictPredicate implements Predicate<Ability> { class InterdictPredicate implements Predicate<StackObject> {
public InterdictPredicate() { public InterdictPredicate() {
} }
@Override @Override
public boolean apply(Ability input, Game game) { public boolean apply(StackObject input, Game game) {
if (input instanceof StackAbility && input.getAbilityType() == AbilityType.ACTIVATED) { if (input instanceof StackAbility && ((StackAbility) input).getAbilityType() == AbilityType.ACTIVATED) {
MageObject sourceObject = input.getSourceObject(game); MageObject sourceObject = ((StackAbility) input).getSourceObject(game);
if (sourceObject != null) { if (sourceObject != null) {
return (sourceObject.isArtifact() return (sourceObject.isArtifact()
|| sourceObject.isEnchantment() || sourceObject.isEnchantment()

View file

@ -0,0 +1,50 @@
package mage.cards.j;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class JynErsoAndCassianAndor extends CardImpl {
public JynErsoAndCassianAndor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.REBEL);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// At the beginning of combat on your turn, target creature gets +1/+0 and gains haste until end of turn.
Ability ability = new BeginningOfCombatTriggeredAbility(
new BoostTargetEffect(1, 0, Duration.EndOfTurn)
.setText("target creature gets +1/+0"),
TargetController.YOU, false);
ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)
.setText("and gains haste until end of turn"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public JynErsoAndCassianAndor(final JynErsoAndCassianAndor card) {
super(card);
}
@Override
public JynErsoAndCassianAndor copy() {
return new JynErsoAndCassianAndor(this);
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class KalevanStarYacht extends CardImpl {
public KalevanStarYacht(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
// When Kalevan Star Yacht enters the battlefield, lose 1 life, draw a card, and put a bounty counter on up to one target creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new LoseLifeSourceControllerEffect(1));
ability.addEffect(new DrawCardSourceControllerEffect(1));
ability.addEffect(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()));
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability);
}
public KalevanStarYacht(final KalevanStarYacht card) {
super(card);
}
@Override
public KalevanStarYacht copy() {
return new KalevanStarYacht(this);
}
}

View file

@ -0,0 +1,128 @@
/*
* 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.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterOpponent;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetOpponent;
/**
*
* @author jeffwadsworth
*/
public class KeeperOfTheMind extends CardImpl {
public final UUID originalId;
private static final FilterOpponent filter = new FilterOpponent();
static {
filter.add(new KeeperOfTheMindPredicate());
}
public KeeperOfTheMind(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// {U}, {tap}: Choose target opponent who had at least two more cards in hand than you did as you activated this ability. Draw a card.
Effect effect = new DrawCardSourceControllerEffect(1);
effect.setText("Choose target opponent who had at least two more cards in hand than you did as you activated this ability. Draw a card.");
Ability ability = new SimpleActivatedAbility(effect, new ManaCostsImpl("{U}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
originalId = ability.getOriginalId();
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
Player activePlayer = game.getPlayer(game.getActivePlayerId());
if (activePlayer != null) {
ability.getTargets().clear();
TargetPlayer target = new TargetPlayer(1, 1, false, filter);
target.setTargetController(activePlayer.getId());
ability.getTargets().add(target);
}
}
}
public KeeperOfTheMind(final KeeperOfTheMind card) {
super(card);
this.originalId = card.originalId;
}
@Override
public KeeperOfTheMind copy() {
return new KeeperOfTheMind(this);
}
}
class KeeperOfTheMindPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<Player>> {
@Override
public boolean apply(ObjectSourcePlayer<Player> input, Game game) {
Player targetPlayer = input.getObject();
Player firstPlayer = game.getPlayer(game.getActivePlayerId());
if (targetPlayer == null
|| firstPlayer == null
|| !firstPlayer.hasOpponent(targetPlayer.getId(), game)) {
return false;
}
int countHandTargetPlayer = targetPlayer.getHand().size();
int countHandFirstPlayer = firstPlayer.getHand().size();
return countHandTargetPlayer - 2 >= countHandFirstPlayer;
}
@Override
public String toString() {
return "opponent who had at least two more cards in hand than you did as you activated this ability";
}
}

View file

@ -0,0 +1,114 @@
package mage.cards.k;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.AttacksEachCombatStaticAbility;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.IntPlusDynamicValue;
import mage.abilities.dynamicvalue.LockedInDynamicValue;
import mage.abilities.dynamicvalue.common.CardsInControllerGraveyardCount;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.constants.*;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.DefendingPlayerControlsPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class KyloRen extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature defending player controls");
static {
filter.add(new DefendingPlayerControlsPredicate());
}
public KyloRen(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}{B}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SITH);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Haste
this.addAbility(HasteAbility.getInstance());
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Kylo Ren attacks each turn if able.
this.addAbility(new AttacksEachCombatStaticAbility());
// Whenever Kylo Ren attacks, it gets +1/+0 for each creature in your graveyard and you may tap target creature defending player controls.
CardsInControllerGraveyardCount value = new CardsInControllerGraveyardCount(StaticFilters.FILTER_CARD_CREATURE);
Effect effect = new BoostSourceEffect(value, new StaticValue(0), Duration.WhileOnBattlefield);
effect.setText("it gets +1/+0 for each creature in your graveyard");
Ability ability = new AttacksTriggeredAbility(effect, false);
ability.addEffect(new KyloRenTapTargetEffect());
ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false));
this.addAbility(ability);
}
public KyloRen(final KyloRen card) {
super(card);
}
@Override
public KyloRen copy() {
return new KyloRen(this);
}
}
class KyloRenTapTargetEffect extends TapTargetEffect {
public KyloRenTapTargetEffect() {
super();
}
public KyloRenTapTargetEffect(final KyloRenTapTargetEffect effect) {
super(effect);
}
@Override
public KyloRenTapTargetEffect copy() {
return new KyloRenTapTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
Player player = game.getPlayer(source.getControllerId());
if(player != null && permanent != null) {
if(player.chooseUse(outcome, "Tap target creature defending player controls (" + permanent.getLogName() + ")", source, game)) {
super.apply(game, source);
}
}
return false;
}
@Override
public String getText(Mode mode) {
return "and you may tap target creature defending player controls";
}
}

View file

@ -0,0 +1,69 @@
package mage.cards.l;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.effects.common.ExileSourceEffect;
import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.command.emblems.LukeSkywalkerEmblem;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class LukeSkywalkerTheLastJedi extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("noncreature permanent");
static {
filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE)));
}
public LukeSkywalkerTheLastJedi(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{G}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.LUKE);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3));
// +1: Put two +1/+1 counters on up to one target creature.
Ability ability1 = new LoyaltyAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), 2);
ability1.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability1);
// -3: Put target noncreature permanent on top of its owner's library.
Ability ability2 = new LoyaltyAbility(new PutOnLibraryTargetEffect(true), -3);
ability2.addTarget(new TargetPermanent(filter));
this.addAbility(ability2);
// -6: You get an emblem with "Prevent all damage that would be dealt to you during combat." Exile Luke Skywalker, the Last Jedi.
Ability ability3 = new LoyaltyAbility(new GetEmblemEffect(new LukeSkywalkerEmblem()), -6);
ability3.addEffect(new ExileSourceEffect());
this.addAbility(ability3);
}
public LukeSkywalkerTheLastJedi(final LukeSkywalkerTheLastJedi card) {
super(card);
}
@Override
public LukeSkywalkerTheLastJedi copy() {
return new LukeSkywalkerTheLastJedi(this);
}
}

View file

@ -0,0 +1,34 @@
package mage.cards.m;
import java.util.UUID;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.common.TargetAttackingCreature;
/**
*
* @author NinthWorld
*/
public final class MaelstromBlockade extends CardImpl {
public MaelstromBlockade(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{W/B}");
// Exile target attacking creature.
this.getSpellAbility().addEffect(new ExileTargetEffect());
this.getSpellAbility().addTarget(new TargetAttackingCreature());
}
public MaelstromBlockade(final MaelstromBlockade card) {
super(card);
}
@Override
public MaelstromBlockade copy() {
return new MaelstromBlockade(this);
}
}

View file

@ -0,0 +1,41 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.RepairAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author NinthWorld
*/
public final class MouseDroid extends CardImpl {
public MouseDroid(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.DROID);
this.power = new MageInt(0);
this.toughness = new MageInt(1);
// When Mouse Droid dies, draw a card.
this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(1)));
// Repair 3
this.addAbility(new RepairAbility(3));
}
public MouseDroid(final MouseDroid card) {
super(card);
}
@Override
public MouseDroid copy() {
return new MouseDroid(this);
}
}

View file

@ -0,0 +1,59 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ColorlessManaCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author NinthWorld
*/
public final class MudTrooper extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Trooper creatures you control");
static {
filter.add(new SubtypePredicate(SubType.TROOPER));
}
public MudTrooper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.TROOPER);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Trooper creatures you control have "2: This creature gets +1/+1 until end of turn."
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new BoostSourceEffect(1, 1, Duration.EndOfTurn)
.setText("This creature gets +1/+1 until end of turn"),
new GenericManaCost(2));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityControlledEffect(ability, Duration.WhileOnBattlefield, filter, false)));
}
public MudTrooper(final MudTrooper card) {
super(card);
}
@Override
public MudTrooper copy() {
return new MudTrooper(this);
}
}

View file

@ -0,0 +1,193 @@
package mage.cards.o;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.effects.common.combat.CantAttackBlockTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.EntersTheBattlefieldEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.turn.Step;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Occupation extends CardImpl {
public Occupation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{B}");
// Creatures your opponents control enter the battlefield tapped.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new OccupationTapEffect()));
// {W}{B}: Target creature can't attack or block this turn, and its activated abilities can't be activated until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new OccupationOneShotEffect("Target creature can't attack or block this turn, and its activated abilities can't be activated until end of turn"),
new ManaCostsImpl("{W}{B}"));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public Occupation(final Occupation card) {
super(card);
}
@Override
public Occupation copy() {
return new Occupation(this);
}
}
class OccupationTapEffect extends ReplacementEffectImpl {
OccupationTapEffect() {
super(Duration.WhileOnBattlefield, Outcome.Tap);
staticText = "Creatures your opponents control enter the battlefield tapped";
}
OccupationTapEffect(final OccupationTapEffect effect) {
super(effect);
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Permanent target = ((EntersTheBattlefieldEvent) event).getTarget();
if (target != null) {
target.setTapped(true);
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) {
Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget();
if (permanent != null && permanent.isCreature()) {
return true;
}
}
return false;
}
@Override
public OccupationTapEffect copy() {
return new OccupationTapEffect(this);
}
}
class OccupationOneShotEffect extends OneShotEffect {
public OccupationOneShotEffect() {
super(Outcome.LoseAbility);
}
public OccupationOneShotEffect(String ruleText) {
super(Outcome.LoseAbility);
staticText = ruleText;
}
public OccupationOneShotEffect(final OccupationOneShotEffect effect) {
super(effect);
}
@Override
public OccupationOneShotEffect copy() {
return new OccupationOneShotEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
OccupationRestrictionEffect effect = new OccupationRestrictionEffect();
game.addEffect(effect, source);
return true;
}
}
class OccupationRestrictionEffect extends RestrictionEffect {
public OccupationRestrictionEffect() {
super(Duration.Custom);
staticText = "";
}
public OccupationRestrictionEffect(final OccupationRestrictionEffect effect) {
super(effect);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.addInfo("Can't attack or block and its activated abilities can't be activated." + getId(), "", game);
}
}
}
@Override
public boolean isInactive(Ability source, Game game) {
if (game.getPhase().getStep().getType() == PhaseStep.UNTAP
&& game.getStep().getStepPart() == Step.StepPart.PRE) {
if (game.isActivePlayer(source.getControllerId())
|| game.getPlayer(source.getControllerId()).hasReachedNextTurnAfterLeaving()) {
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null) {
permanent.addInfo("Can't attack or block and its activated abilities can't be activated." + getId(), "", game);
}
}
return true;
}
}
return false;
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (this.targetPointer.getTargets(game, source).contains(permanent.getId())) {
return true;
}
return false;
}
@Override
public boolean canAttack(Game game) {
return false;
}
@Override
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
return false;
}
@Override
public boolean canUseActivatedAbilities(Permanent permanent, Ability source, Game game) {
return false;
}
@Override
public OccupationRestrictionEffect copy() {
return new OccupationRestrictionEffect(this);
}
}

View file

@ -18,10 +18,12 @@ import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterStackObject; import mage.filter.FilterStackObject;
import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicate;
import mage.filter.predicate.ability.ArtifactSourcePredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.StackAbility; import mage.game.stack.StackAbility;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.target.common.TargetActivatedAbility;
import mage.target.common.TargetActivatedOrTriggeredAbility; import mage.target.common.TargetActivatedOrTriggeredAbility;
/** /**
@ -47,7 +49,7 @@ public final class OupheVandals extends CardImpl {
// {G}, Sacrifice Ouphe Vandals: Counter target activated ability from an artifact source and destroy that artifact if it's on the battlefield. // {G}, Sacrifice Ouphe Vandals: Counter target activated ability from an artifact source and destroy that artifact if it's on the battlefield.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new OupheVandalsEffect(), new ManaCostsImpl<>("{G}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new OupheVandalsEffect(), new ManaCostsImpl<>("{G}"));
ability.addCost(new SacrificeSourceCost()); ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetActivatedOrTriggeredAbility(filter)); ability.addTarget(new TargetActivatedAbility(filter));
this.addAbility(ability); this.addAbility(ability);
} }
@ -61,25 +63,6 @@ public final class OupheVandals extends CardImpl {
} }
} }
class ArtifactSourcePredicate implements Predicate<Ability> {
public ArtifactSourcePredicate() {
}
@Override
public boolean apply(Ability input, Game game) {
if (input instanceof StackAbility) {
return input.getSourceObject(game).isArtifact() && input.getAbilityType() == AbilityType.ACTIVATED;
}
return false;
}
@Override
public String toString() {
return "Source(Artifact)";
}
}
class OupheVandalsEffect extends OneShotEffect { class OupheVandalsEffect extends OneShotEffect {
public OupheVandalsEffect() { public OupheVandalsEffect() {

View file

@ -0,0 +1,49 @@
package mage.cards.o;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.CounterPredicate;
/**
*
* @author NinthWorld
*/
public final class OuterRimGang extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("each creature with a bounty counter on it");
static {
filter.add(new CounterPredicate(CounterType.BOUNTY));
}
public OuterRimGang(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}{R}{G}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ROGUE);
this.subtype.add(SubType.HUNTER);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// When Outer Rim Gang enters the battlefield, each creature with a bounty counter on it gets -2/-2 until end of turn.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BoostAllEffect(-2, -2, Duration.EndOfTurn, filter, false)));
}
public OuterRimGang(final OuterRimGang card) {
super(card);
}
@Override
public OuterRimGang copy() {
return new OuterRimGang(this);
}
}

View file

@ -12,6 +12,8 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AnotherTargetPredicate;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
/** /**
@ -30,8 +32,14 @@ public final class OuterRimSlaver extends CardImpl {
// When Outer Rim Slaver enters the battlefield, you may put a bounty counter on target creature. If you do, another target creature fights that creature // When Outer Rim Slaver enters the battlefield, you may put a bounty counter on target creature. If you do, another target creature fights that creature
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), true); Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()), true);
ability.addEffect(new FightTargetsEffect("another target creature fights that creature")); ability.addEffect(new FightTargetsEffect("another target creature fights that creature"));
ability.addTarget(new TargetCreaturePermanent()); TargetCreaturePermanent target = new TargetCreaturePermanent();
ability.addTarget(new TargetCreaturePermanent()); target.setTargetTag(1);
ability.addTarget(target);
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new AnotherTargetPredicate(2));
TargetCreaturePermanent target2 = new TargetCreaturePermanent(filter);
target2.setTargetTag(2);
ability.addTarget(target2);
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -0,0 +1,54 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
/**
*
* @author NinthWorld
*/
public final class PoeDameron extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("{this} or another nontoken creature you control");
private static final FilterCreaturePermanent filterStarship = new FilterCreaturePermanent("starship creatures you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(Predicates.not(new TokenPredicate()));
filterStarship.add(new ControllerPredicate(TargetController.YOU));
filterStarship.add(new SubtypePredicate(SubType.STARSHIP));
}
public PoeDameron(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Poe Dameron or another nontoken creature enters the battlefield under your control, starship creatures you control get +1/+1 until end of turn.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.EndOfTurn, filterStarship, false), filter, false));
}
public PoeDameron(final PoeDameron card) {
super(card);
}
@Override
public PoeDameron copy() {
return new PoeDameron(this);
}
}

View file

@ -0,0 +1,44 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.constants.SubType;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.permanent.token.PorgToken;
/**
*
* @author NinthWorld
*/
public final class PorgNest extends CardImpl {
public PorgNest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.subtype.add(SubType.BIRD);
this.power = new MageInt(0);
this.toughness = new MageInt(2);
// Defender
this.addAbility(DefenderAbility.getInstance());
// At the beginning of your upkeep, create a 0/1 green Bird creature token named Porg with "{G}: Monstrosity 1."
this.addAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new PorgToken()), TargetController.YOU, false));
}
public PorgNest(final PorgNest card) {
super(card);
}
@Override
public PorgNest copy() {
return new PorgNest(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author NinthWorld
*/
public final class PraetorianTrooper extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Trooper creatures");
static {
filter.add(new SubtypePredicate(SubType.TROOPER));
}
public PraetorianTrooper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.TROOPER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Trooper creatures you control have double strike.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityControlledEffect(DoubleStrikeAbility.getInstance(), Duration.WhileOnBattlefield, filter, false)));
}
public PraetorianTrooper(final PraetorianTrooper card) {
super(card);
}
@Override
public PraetorianTrooper copy() {
return new PraetorianTrooper(this);
}
}

View file

@ -11,6 +11,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.common.TargetPlayerOrPlaneswalker;
/** /**
* *
@ -22,12 +23,12 @@ public final class QuenchableFire extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}"); super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{R}");
// Quenchable Fire deals 3 damage to target player. // Quenchable Fire deals 3 damage to target player.
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
this.getSpellAbility().addEffect(new DamageTargetEffect(3)); this.getSpellAbility().addEffect(new DamageTargetEffect(3));
// It deals an additional 3 damage to that player at the beginning of your next upkeep step unless he or she pays {U} before that step. // It deals an additional 3 damage to that player or planeswalker at the beginning of your next upkeep step unless that player or that planeswalkers controller pays {U} before that step.
this.getSpellAbility().addEffect(new UnlessPaysDelayedEffect(new ManaCostsImpl("{U}"), this.getSpellAbility().addEffect(new UnlessPaysDelayedEffect(new ManaCostsImpl("{U}"),
new DamageTargetEffect(3, true, "that player"), PhaseStep.UPKEEP, false, new DamageTargetEffect(3, true, "that player or that planeswalker's controller"), PhaseStep.UPKEEP, false,
"It deals an additional 3 damage to that player at the beginning of your next upkeep step unless he or she pays {U} before that step.")); "It deals an additional 3 damage to that player or planeswalker at the beginning of your next upkeep step unless that player or that planeswalkers controller pays {U} before that step."));
} }
public QuenchableFire(final QuenchableFire card) { public QuenchableFire(final QuenchableFire card) {

View file

@ -15,6 +15,7 @@ import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import mage.target.common.TargetOpponentOrPlaneswalker;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
/** /**
@ -26,10 +27,10 @@ public final class RakdossReturn extends CardImpl {
public RakdossReturn(UUID ownerId, CardSetInfo setInfo) { public RakdossReturn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{R}"); super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{B}{R}");
// Rakdos's Return deals X damage to target opponent. That player discards X cards. // Rakdos's Return deals X damage to target opponent or planeswalker. That player or that planeswalkers controller discards X cards.
this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue())); this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue()));
this.getSpellAbility().addEffect(new RakdossReturnEffect()); this.getSpellAbility().addEffect(new RakdossReturnEffect());
this.getSpellAbility().addTarget(new TargetOpponent()); this.getSpellAbility().addTarget(new TargetOpponentOrPlaneswalker());
} }
public RakdossReturn(final RakdossReturn card) { public RakdossReturn(final RakdossReturn card) {

View file

@ -0,0 +1,92 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author NinthWorld
*/
public final class RangeTrooper extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Trooper creatures you control");
static {
filter.add(new SubtypePredicate(SubType.TROOPER));
}
public RangeTrooper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.TROOPER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Trooper creatures you control have "When this creature enters that battlefield, you may exile target creature. Return that creature to the battlefield at the beginning of the next end step."
Ability ability = new EntersBattlefieldTriggeredAbility(new RangeTrooperEffect(), true, true);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityControlledEffect(ability, Duration.WhileOnBattlefield, filter, false)));
}
public RangeTrooper(final RangeTrooper card) {
super(card);
}
@Override
public RangeTrooper copy() {
return new RangeTrooper(this);
}
}
class RangeTrooperEffect extends OneShotEffect {
public RangeTrooperEffect() {
super(Outcome.Detriment);
staticText = "When this creature enters the battlefield, you may exile target creature. Return that creature to the battlefield at the beginning of the next end step";
}
public RangeTrooperEffect(final RangeTrooperEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getFirstTarget());
MageObject sourceObject = game.getObject(source.getSourceId());
if (permanent != null && sourceObject != null) {
if (permanent.moveToExile(source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game)) {
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
effect.setText("Return that card to the battlefield under its owner's control at the beginning of the next end step");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);
return true;
}
}
return false;
}
@Override
public RangeTrooperEffect copy() {
return new RangeTrooperEffect(this);
}
}

View file

@ -0,0 +1,49 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect;
import mage.abilities.keyword.MonstrosityAbility;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Rathtar extends CardImpl {
public Rathtar(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{G}");
this.subtype.add(SubType.BEAST);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// {5}{G}{G}: Monstrosity 2.
this.addAbility(new MonstrosityAbility("{5}{G}{G}", 2));
// When Rathtar becomes monstrous, any number of target creatures must block it this turn if able.
Ability ability = new BecomesMonstrousSourceTriggeredAbility(
new BlocksIfAbleTargetEffect(Duration.EndOfTurn).setText("any number of target creatures must block it this turn if able"));
ability.addTarget(new TargetCreaturePermanent(0, Integer.MAX_VALUE));
this.addAbility(ability);
}
public Rathtar(final Rathtar card) {
super(card);
}
@Override
public Rathtar copy() {
return new Rathtar(this);
}
}

View file

@ -19,6 +19,7 @@ import mage.filter.common.FilterArtifactPermanent;
import mage.filter.predicate.permanent.ControllerPredicate; import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.target.common.TargetPlayerOrPlaneswalker;
/** /**
* *
@ -44,9 +45,9 @@ public final class RelicBind extends CardImpl {
this.addAbility(ability); this.addAbility(ability);
// Whenever enchanted artifact becomes tapped, choose one // Whenever enchanted artifact becomes tapped, choose one
// Relic Bind deals 1 damage to target player. // Relic Bind deals 1 damage to target player or planeswalker.
Ability ability2 = new BecomesTappedAttachedTriggeredAbility(new DamageTargetEffect(1), "enchanted artifact"); Ability ability2 = new BecomesTappedAttachedTriggeredAbility(new DamageTargetEffect(1), "enchanted artifact");
ability2.addTarget(new TargetPlayer()); ability2.addTarget(new TargetPlayerOrPlaneswalker());
// Target player gains 1 life. // Target player gains 1 life.
Mode mode = new Mode(); Mode mode = new Mode();
mode.getEffects().add(new GainLifeTargetEffect(1)); mode.getEffects().add(new GainLifeTargetEffect(1));

View file

@ -8,6 +8,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.FilterAbility; import mage.filter.FilterAbility;
import mage.filter.FilterStackObject;
import mage.filter.predicate.mageobject.NumberOfTargetsPredicate; import mage.filter.predicate.mageobject.NumberOfTargetsPredicate;
import mage.target.common.TargetActivatedAbility; import mage.target.common.TargetActivatedAbility;
@ -17,7 +18,7 @@ import mage.target.common.TargetActivatedAbility;
*/ */
public final class Reroute extends CardImpl { public final class Reroute extends CardImpl {
private static final FilterAbility filter = new FilterAbility("activated ability with a single target"); private static final FilterStackObject filter = new FilterStackObject("activated ability with a single target");
static { static {
filter.add(new NumberOfTargetsPredicate(1)); filter.add(new NumberOfTargetsPredicate(1));

View file

@ -0,0 +1,60 @@
package mage.cards.r;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.combat.AttacksIfAbleTargetEffect;
import mage.abilities.effects.common.combat.BlocksIfAbleTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.AttacksThisTurnMarkerAbility;
import mage.abilities.keyword.BlocksThisTurnMarkerAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class Resistance extends CardImpl {
public Resistance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{W}");
// Whenever a creature enters the battlefield under your control, Resistance deals 1 damage to each opponent.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new DamagePlayersEffect(1, TargetController.OPPONENT), StaticFilters.FILTER_PERMANENT_CREATURE, false));
// {R}{W}: Target creature gains haste until end of turn and must attack or block this turn if able.
Ability ability = new SimpleActivatedAbility(
new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.EndOfTurn)
.setText("Target creature gains haste until end of turn"),
new ManaCostsImpl("{R}{W}"));
ability.addEffect(new AttacksIfAbleTargetEffect(Duration.EndOfTurn).setText("and must attack"));
//ability.addEffect(new GainAbilityTargetEffect(AttacksThisTurnMarkerAbility.getInstance(), Duration.EndOfTurn, "").setText(""));
ability.addEffect(new BlocksIfAbleTargetEffect(Duration.EndOfTurn).setText("or block this turn if able"));
//ability.addEffect(new GainAbilityTargetEffect(BlocksThisTurnMarkerAbility.getInstance(), Duration.EndOfTurn, "").setText(""));
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public Resistance(final Resistance card) {
super(card);
}
@Override
public Resistance copy() {
return new Resistance(this);
}
}

View file

@ -0,0 +1,60 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.SourceAttackingCondition;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class ResistanceBomber extends CardImpl {
public ResistanceBomber(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{R}");
this.subtype.add(SubType.REBEL);
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
// Resistance Bomber enters the battlefield with a charge counter on it.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.CHARGE.createInstance())
.setText("with a charge counter on it")));
// Remove a charge counter from Resistance Bomber: Resistance Bomber deals 5 damage to target creature. Activate this ability only if Resistance Bomber is attacking.
Ability ability = new ConditionalActivatedAbility(Zone.BATTLEFIELD,
new DamageTargetEffect(5),
new RemoveCountersSourceCost(CounterType.CHARGE.createInstance()),
SourceAttackingCondition.instance);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public ResistanceBomber(final ResistanceBomber card) {
super(card);
}
@Override
public ResistanceBomber copy() {
return new ResistanceBomber(this);
}
}

View file

@ -0,0 +1,97 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldOrLeavesSourceTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
/**
*
* @author NinthWorld
*/
public final class Rey extends CardImpl {
public Rey(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{G}{W}{U}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// First strike
this.addAbility(FirstStrikeAbility.getInstance());
// Whenever Rey enters or leaves the battlefield, reveal the top card of target player's library. You gain life equal to that card's converted mana cost.
Ability ability = new EntersBattlefieldOrLeavesSourceTriggeredAbility(new ReyEffect(), false);
ability.addTarget(new TargetPlayer());
this.addAbility(ability);
}
public Rey(final Rey card) {
super(card);
}
@Override
public Rey copy() {
return new Rey(this);
}
}
class ReyEffect extends OneShotEffect {
public ReyEffect() {
super(Outcome.Detriment);
staticText = "reveal the top card of target player's library. You gain life equal to that card's converted mana cost";
}
public ReyEffect(final ReyEffect effect) {
super(effect);
}
@Override
public ReyEffect copy() {
return new ReyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source));
if(targetPlayer != null && controller != null) {
if(targetPlayer.getLibrary().hasCards()) {
// reveal the top card of target player's library.
Card topCard = targetPlayer.getLibrary().getFromTop(game);
CardsImpl reveal = new CardsImpl();
reveal.add(topCard);
targetPlayer.revealCards(source, reveal, game);
// You gain life equal to that card's converted mana cost.
if (topCard != null) {
controller.gainLife(topCard.getConvertedManaCost(), game, source);
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,50 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CanBlockAdditionalCreatureAllEffect;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author NinthWorld
*/
public final class RiotTrooper extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("trooper creatures you control");
static {
filter.add(new SubtypePredicate(SubType.TROOPER));
}
public RiotTrooper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.TROOPER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Each trooper creature you control can block an additional creature each combat.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new CanBlockAdditionalCreatureAllEffect(1, filter, Duration.WhileOnBattlefield)
.setText("Each trooper creature you control can block an additional creature each combat")));
}
public RiotTrooper(final RiotTrooper card) {
super(card);
}
@Override
public RiotTrooper copy() {
return new RiotTrooper(this);
}
}

View file

@ -7,6 +7,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.FilterAbility; import mage.filter.FilterAbility;
import mage.filter.FilterStackObject;
import mage.filter.predicate.ability.ArtifactSourcePredicate; import mage.filter.predicate.ability.ArtifactSourcePredicate;
import mage.target.common.TargetActivatedAbility; import mage.target.common.TargetActivatedAbility;
@ -16,7 +17,7 @@ import mage.target.common.TargetActivatedAbility;
*/ */
public final class Rust extends CardImpl { public final class Rust extends CardImpl {
private final static FilterAbility filter = new FilterAbility("activated ability from an artifact source"); private final static FilterStackObject filter = new FilterStackObject("activated ability from an artifact source");
static { static {
filter.add(new ArtifactSourcePredicate()); filter.add(new ArtifactSourcePredicate());

View file

@ -0,0 +1,47 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreatureOrPlaneswalker;
/**
*
* @author NinthWorld
*/
public final class SaiTok extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("creature or planeswalker if it has converted mana cost 4 or less");
static {
filter.add(new CardTypePredicate(CardType.CREATURE));
filter.add(new CardTypePredicate(CardType.PLANESWALKER));
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, 5));
}
public SaiTok(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}{B}");
// Destroy target creature or planeswalker if it has converted mana cost 4 or less.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent(filter));
}
public SaiTok(final SaiTok card) {
super(card);
}
@Override
public SaiTok copy() {
return new SaiTok(this);
}
}

View file

@ -0,0 +1,171 @@
package mage.cards.s;
import java.util.*;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.ExchangeControlTargetEffect;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterArtifactCard;
import mage.filter.common.FilterArtifactPermanent;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetCard;
import mage.target.common.TargetArtifactPermanent;
import mage.target.common.TargetControlledPermanent;
/**
*
* @author NinthWorld
*/
public final class SalvageTrader extends CardImpl {
private static final FilterArtifactPermanent filterYou = new FilterArtifactPermanent("artifact you control");
static {
filterYou.add(new ControllerPredicate(TargetController.YOU));
}
public SalvageTrader(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}");
this.subtype.add(SubType.CROLUTE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// {T}: Exchange control of target artifact you control and target artifact an opponent controls with the same converted mana cost.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SalvageTraderEffect(), new TapSourceCost());
ability.addTarget(new TargetArtifactPermanent(filterYou));
this.addAbility(ability);
}
public SalvageTrader(final SalvageTrader card) {
super(card);
}
@Override
public SalvageTrader copy() {
return new SalvageTrader(this);
}
}
// effect is based on JuxtaposeEffect
// which is based on ExchangeControlTargetEffect
class SalvageTraderEffect extends ContinuousEffectImpl {
private final Map<UUID, Integer> zoneChangeCounter;
private final Map<UUID, UUID> lockedControllers;
public SalvageTraderEffect() {
super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
staticText = "Exchange control of target artifact you control and target artifact an opponent controls with the same converted mana cost";
this.zoneChangeCounter = new HashMap<>();
this.lockedControllers = new HashMap<>();
}
public SalvageTraderEffect(final SalvageTraderEffect effect) {
super(effect);
this.zoneChangeCounter = new HashMap<>(effect.zoneChangeCounter);
this.lockedControllers = new HashMap<>(effect.lockedControllers);
}
@Override
public void init(Ability source, Game game) {
Player you = game.getPlayer(source.getControllerId());
Permanent permanent1 = game.getPermanent(targetPointer.getFirst(game, source));
MageObject sourceObject = game.getCard(source.getSourceId());
if(you != null && permanent1 != null) {
FilterArtifactCard filterArtifactCard = new FilterArtifactCard();
filterArtifactCard.add(new ControllerPredicate(TargetController.OPPONENT));
filterArtifactCard.add(new SpellZonePredicate(Zone.BATTLEFIELD));
filterArtifactCard.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, permanent1.getConvertedManaCost()));
FilterArtifactPermanent filterArtifactPermanent = new FilterArtifactPermanent();
filterArtifactPermanent.add(new ControllerPredicate(TargetController.OPPONENT));
filterArtifactPermanent.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, permanent1.getConvertedManaCost()));
Cards cards = new CardsImpl();
for(Permanent permanent : game.getBattlefield().getAllActivePermanents(filterArtifactPermanent, game)) {
cards.add(permanent);
}
Player opponent = null;
Permanent permanent2 = null;
TargetCard targetCard = new TargetCard(Zone.BATTLEFIELD, filterArtifactCard);
if(you.choose(Outcome.Benefit, cards, targetCard, game)) {
permanent2 = game.getPermanent(targetCard.getFirstTarget());
if(permanent2 != null) {
opponent = game.getPlayer(permanent2.getControllerId());
}
}
if (opponent != null) {
// exchange works only for two different controllers
if (permanent1.isControlledBy(permanent2.getControllerId())) {
// discard effect if controller of both permanents is the same
discard();
return;
}
this.lockedControllers.put(permanent1.getId(), permanent2.getControllerId());
this.zoneChangeCounter.put(permanent1.getId(), permanent1.getZoneChangeCounter(game));
this.lockedControllers.put(permanent2.getId(), permanent1.getControllerId());
this.zoneChangeCounter.put(permanent2.getId(), permanent2.getZoneChangeCounter(game));
permanent1.changeControllerId(opponent.getId(), game);
permanent2.changeControllerId(you.getId(), game);
game.informPlayers(new StringBuilder(sourceObject != null ? sourceObject.getLogName() : "").append(": ").append(you.getLogName())
.append(" and ").append(opponent.getLogName()).append(" exchange control of ").append(permanent1.getLogName())
.append(" and ").append(permanent2.getName()).toString());
} else {
// discard if there are less than 2 permanents
discard();
}
}
}
@Override
public boolean apply(Game game, Ability source) {
Set<UUID> toDelete = new HashSet<>();
for (Map.Entry<UUID, Integer> entry : zoneChangeCounter.entrySet()) {
Permanent permanent = game.getPermanent(entry.getKey());
if (permanent == null || permanent.getZoneChangeCounter(game) != entry.getValue()) {
// control effect cease if the same permanent is no longer on the battlefield
toDelete.add(entry.getKey());
continue;
}
permanent.changeControllerId(lockedControllers.get(permanent.getId()), game);
}
if (!toDelete.isEmpty()) {
for (UUID uuid : toDelete) {
zoneChangeCounter.remove(uuid);
}
if (zoneChangeCounter.isEmpty()) {
discard();
return false;
}
}
return true;
}
@Override
public SalvageTraderEffect copy() {
return new SalvageTraderEffect(this);
}
}

View file

@ -10,7 +10,7 @@ import mage.constants.CardType;
import mage.filter.FilterSpell; import mage.filter.FilterSpell;
import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicate;
import mage.game.Game; import mage.game.Game;
import mage.game.stack.Spell; import mage.game.stack.StackObject;
import mage.target.TargetSpell; import mage.target.TargetSpell;
import mage.watchers.common.CastSpellLastTurnWatcher; import mage.watchers.common.CastSpellLastTurnWatcher;
@ -45,10 +45,10 @@ public final class SecondGuess extends CardImpl {
} }
} }
class SecondSpellPredicate implements Predicate<Spell> { class SecondSpellPredicate implements Predicate<StackObject> {
@Override @Override
public boolean apply(Spell input, Game game) { public boolean apply(StackObject input, Game game) {
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName()); CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(CastSpellLastTurnWatcher.class.getSimpleName());
if (watcher.getSpellOrder(new MageObjectReference(input.getId(), game), game) == 2) { if (watcher.getSpellOrder(new MageObjectReference(input.getId(), game), game) == 2) {

View file

@ -12,6 +12,7 @@ import mage.filter.FilterSpell;
import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicate;
import mage.game.Game; import mage.game.Game;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.game.stack.StackObject;
/** /**
* *
@ -43,7 +44,7 @@ public final class SecretsOfTheDead extends CardImpl {
} }
} }
class SpellZonePredicate implements Predicate<Spell> { class SpellZonePredicate implements Predicate<StackObject> {
private final Zone zone; private final Zone zone;
@ -52,8 +53,8 @@ class SpellZonePredicate implements Predicate<Spell> {
} }
@Override @Override
public boolean apply(Spell input, Game game) { public boolean apply(StackObject input, Game game) {
return input.getFromZone().match(zone); return input instanceof Spell && ((Spell) input).getFromZone().match(zone);
} }
@Override @Override

View file

@ -0,0 +1,79 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
/**
*
* @author NinthWorld
*/
public final class SinsOfTheFather extends CardImpl {
public SinsOfTheFather(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}");
// Exile target player's graveyard. That player loses 1 life for each instant or sorcery card exiled this way.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new SinsOfTheFatherEffect());
}
public SinsOfTheFather(final SinsOfTheFather card) {
super(card);
}
@Override
public SinsOfTheFather copy() {
return new SinsOfTheFather(this);
}
}
class SinsOfTheFatherEffect extends OneShotEffect {
private static final FilterInstantOrSorceryCard filter = new FilterInstantOrSorceryCard();
public SinsOfTheFatherEffect() {
super(Outcome.Detriment);
staticText = "Exile target player's graveyard. That player loses 1 life for each instant or sorcery card exiled this way";
}
public SinsOfTheFatherEffect(final SinsOfTheFatherEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if(you != null && targetPlayer != null) {
int exiledCards = 0;
for(Card card : targetPlayer.getGraveyard().getCards(game)) {
if(filter.match(card, game)) {
if(card.moveToExile(null, "", source.getSourceId(), game)) {
exiledCards++;
}
}
}
targetPlayer.loseLife(exiledCards, game, false);
return true;
}
return false;
}
@Override
public SinsOfTheFatherEffect copy() {
return new SinsOfTheFatherEffect(this);
}
}

View file

@ -1,19 +1,15 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.common.RevealSecretOpponentCost;
import mage.abilities.costs.CostImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseSecretOpponentEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import static mage.cards.s.StalkingLeonin.SECRET_OPPONENT;
import static mage.cards.s.StalkingLeonin.SECRET_OWNER;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
@ -23,8 +19,8 @@ import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.FilterCreatureAttackingYou; import mage.target.common.FilterCreatureAttackingYou;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
import mage.util.CardUtil; import java.util.UUID;
/** /**
* *
@ -32,9 +28,6 @@ import mage.util.CardUtil;
*/ */
public final class StalkingLeonin extends CardImpl { public final class StalkingLeonin extends CardImpl {
static final String SECRET_OPPONENT = "_secOpp";
static final String SECRET_OWNER = "_secOwn";
public StalkingLeonin(UUID ownerId, CardSetInfo setInfo) { public StalkingLeonin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
@ -43,9 +36,9 @@ public final class StalkingLeonin extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// When Stalking Leonin enters the battlefield, secretly choose an opponent. // When Stalking Leonin enters the battlefield, secretly choose an opponent.
this.addAbility(new EntersBattlefieldTriggeredAbility(new StalkingLeoninChooseOpponent(), false)); this.addAbility(new EntersBattlefieldTriggeredAbility(new ChooseSecretOpponentEffect(), false));
// Reveal the player you chose: Exile target creature that's attacking you if it's controlled by the chosen player. Activate this ability only once. // Reveal the player you chose: Exile target creature that's attacking you if it's controlled by the chosen player. Activate this ability only once.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StalkingLeoninEffect(), new StalkingLeoninRevealOpponentCost()); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new StalkingLeoninEffect(), new RevealSecretOpponentCost());
ability.addTarget(new TargetCreaturePermanent(new FilterCreatureAttackingYou())); ability.addTarget(new TargetCreaturePermanent(new FilterCreatureAttackingYou()));
this.addAbility(ability); this.addAbility(ability);
} }
@ -60,105 +53,6 @@ public final class StalkingLeonin extends CardImpl {
} }
} }
class StalkingLeoninChooseOpponent extends OneShotEffect {
public StalkingLeoninChooseOpponent() {
super(Outcome.Neutral);
staticText = "secretly choose an opponent";
}
public StalkingLeoninChooseOpponent(final StalkingLeoninChooseOpponent effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject mageObject = game.getPermanentEntering(source.getSourceId());
if (mageObject == null) {
mageObject = game.getObject(source.getSourceId());
}
if (controller != null && mageObject != null) {
TargetOpponent targetOpponent = new TargetOpponent();
targetOpponent.setTargetName("opponent (secretly)");
while (!controller.choose(outcome, targetOpponent, source.getSourceId(), game)) {
if (!controller.canRespond()) {
return false;
}
}
if (targetOpponent.getTargets().isEmpty()) {
return false;
}
if (!game.isSimulation()) {
game.informPlayers(mageObject.getName() + ": " + controller.getLogName() + " has secretly chosen an opponent.");
}
game.getState().setValue(mageObject.getId() + SECRET_OPPONENT, targetOpponent.getTargets().get(0));
game.getState().setValue(mageObject.getId() + SECRET_OWNER, controller.getId());
if (mageObject instanceof Permanent) {
((Permanent) mageObject).addInfo(SECRET_OPPONENT,
CardUtil.addToolTipMarkTags(controller.getLogName() + " has secretly chosen an opponent."), game);
}
}
return false;
}
@Override
public StalkingLeoninChooseOpponent copy() {
return new StalkingLeoninChooseOpponent(this);
}
}
class StalkingLeoninRevealOpponentCost extends CostImpl {
public StalkingLeoninRevealOpponentCost() {
this.text = "Reveal the player you chose";
}
public StalkingLeoninRevealOpponentCost(final StalkingLeoninRevealOpponentCost cost) {
super(cost);
}
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
UUID playerThatChoseId = (UUID) game.getState().getValue(sourceId + SECRET_OWNER);
if (playerThatChoseId == null || !playerThatChoseId.equals(controllerId)) {
return false;
}
UUID opponentId = (UUID) game.getState().getValue(sourceId + SECRET_OPPONENT);
return opponentId != null;
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
UUID playerThatChoseId = (UUID) game.getState().getValue(sourceId + SECRET_OWNER);
if (playerThatChoseId == null || !playerThatChoseId.equals(controllerId)) {
return false;
}
UUID opponentId = (UUID) game.getState().getValue(sourceId + SECRET_OPPONENT);
if (opponentId != null) {
game.getState().setValue(sourceId + SECRET_OWNER, null); // because only once, the vale is set to null
Player controller = game.getPlayer(controllerId);
Player opponent = game.getPlayer(opponentId);
MageObject sourceObject = game.getObject(sourceId);
if (controller != null && opponent != null && sourceObject != null) {
if (sourceObject instanceof Permanent) {
((Permanent) sourceObject).addInfo(SECRET_OPPONENT, null, game);
}
game.informPlayers(sourceObject.getLogName() + ": " + controller.getLogName() + " reveals the secretly chosen opponent " + opponent.getLogName());
}
paid = true;
}
return paid;
}
@Override
public StalkingLeoninRevealOpponentCost copy() {
return new StalkingLeoninRevealOpponentCost(this);
}
}
class StalkingLeoninEffect extends OneShotEffect { class StalkingLeoninEffect extends OneShotEffect {
public StalkingLeoninEffect() { public StalkingLeoninEffect() {
@ -181,7 +75,7 @@ class StalkingLeoninEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetCreature != null) { if (targetCreature != null) {
UUID opponentId = (UUID) game.getState().getValue(source.getSourceId() + SECRET_OPPONENT); UUID opponentId = (UUID) game.getState().getValue(source.getSourceId() + ChooseSecretOpponentEffect.SECRET_OPPONENT);
if (opponentId != null && opponentId.equals(targetCreature.getControllerId())) { if (opponentId != null && opponentId.equals(targetCreature.getControllerId())) {
controller.moveCards(targetCreature, Zone.EXILED, source, game); controller.moveCards(targetCreature, Zone.EXILED, source, game);
} }

View file

@ -0,0 +1,156 @@
package mage.cards.s;
import java.util.Iterator;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayVariableLoyaltyCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.OpponentsLostLifeCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.*;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.players.PlayerList;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.common.PlayerLostLifeNonCombatWatcher;
import mage.watchers.common.PlayerLostLifeWatcher;
/**
*
* @author NinthWorld
*/
public final class SupremeLeaderSnoke extends CardImpl {
UUID ability3Id;
public SupremeLeaderSnoke(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{U}{B}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.SNOKE);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(3));
// +1: Put a loyalty counter on Supreme Leader Snoke for each life lost by all opponents from noncombat sources this turn.
Ability ability1 = new LoyaltyAbility(new SupremeLeaderSnokeCounterEffect(CounterType.LOYALTY.createInstance()), 1);
this.addAbility(ability1);
// -1: Draw a card and lose 1 life.
Ability ability2 = new LoyaltyAbility(new DrawCardSourceControllerEffect(1), -1);
ability2.addEffect(new LoseLifeSourceControllerEffect(1).setText("and lose 1 life"));
this.addAbility(ability2);
// -X: Gain control of target creature with converted mana cost X. Untap that creature. It gains haste. Sacrifice that creature at the beginning of the next end step.
Ability ability3 = new LoyaltyAbility(new GainControlTargetEffect(Duration.WhileOnBattlefield)
.setText("Gain control of target creature with converted mana cost X"));
ability3.addEffect(new UntapTargetEffect().setText("Untap that creature"));
ability3.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance(), Duration.WhileOnBattlefield).setText("It gains haste"));
ability3.addEffect(new GainAbilityTargetEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()), Duration.WhileOnBattlefield)
.setText("Sacrifice that creature at the beginning of the next end step"));
ability3Id = ability3.getOriginalId();
ability3.addTarget(new TargetCreaturePermanent());
this.addAbility(ability3);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(ability3Id)) {
int cmc = 0;
for (Cost cost : ability.getCosts()) {
if (cost instanceof PayVariableLoyaltyCost) {
cmc = ((PayVariableLoyaltyCost) cost).getAmount();
}
}
FilterCreaturePermanent newFilter = StaticFilters.FILTER_PERMANENT_CREATURE.copy();
newFilter.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, cmc));
ability.getTargets().clear();
ability.addTarget(new TargetCreaturePermanent(newFilter));
}
}
public SupremeLeaderSnoke(final SupremeLeaderSnoke card) {
super(card);
this.ability3Id = card.ability3Id;
}
@Override
public SupremeLeaderSnoke copy() {
return new SupremeLeaderSnoke(this);
}
}
class OpponentNoncombatLostLifeCount implements DynamicValue {
@Override
public int calculate(Game game, Ability source, Effect effect) {
PlayerLostLifeNonCombatWatcher watcher = (PlayerLostLifeNonCombatWatcher) game.getState().getWatchers().get(PlayerLostLifeNonCombatWatcher.class.getSimpleName());
if(watcher != null) {
return watcher.getAllOppLifeLost(source.getControllerId(), game);
}
return 0;
}
@Override
public DynamicValue copy() {
return new OpponentNoncombatLostLifeCount();
}
@Override
public String getMessage() {
return "life lost by all opponents from noncombat sources this turn";
}
}
class SupremeLeaderSnokeCounterEffect extends OneShotEffect {
protected final Counter counter;
public SupremeLeaderSnokeCounterEffect(Counter counter) {
super(Outcome.Benefit);
this.counter = counter;
staticText = "Put a loyalty counter on {this} for each life lost by all opponents from noncombat sources this turn";
}
public SupremeLeaderSnokeCounterEffect(final SupremeLeaderSnokeCounterEffect effect) {
super(effect);
this.counter = effect.counter;
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if(permanent != null) {
int amount = new OpponentNoncombatLostLifeCount().calculate(game, source, this);
if(amount > 0) {
Counter counterToAdd = counter.copy();
counterToAdd.add(amount - counter.getCount());
permanent.addCounters(counterToAdd, source, game);
}
}
return true;
}
@Override
public SupremeLeaderSnokeCounterEffect copy() {
return new SupremeLeaderSnokeCounterEffect(this);
}
}

View file

@ -0,0 +1,89 @@
package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamagePlayersEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TargetController;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author NinthWorld
*/
public final class TIESilencer extends CardImpl {
public TIESilencer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{B}{R}");
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Haste
this.addAbility(HasteAbility.getInstance());
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
// Whenever TIE Silencer attacks, it deals 1 damage to defending player and 1 damage to up to one target creature that player controls.
Ability ability = new AttacksTriggeredAbility(new TIESilencerEffect(), false);
ability.addTarget(new TargetCreaturePermanent(0, 1));
this.addAbility(ability);
}
public TIESilencer(final TIESilencer card) {
super(card);
}
@Override
public TIESilencer copy() {
return new TIESilencer(this);
}
}
class TIESilencerEffect extends OneShotEffect {
public TIESilencerEffect() {
super(Outcome.Damage);
staticText = "it deals 1 damage to defending player and 1 damage to up to one target creature that player controls";
}
public TIESilencerEffect(final TIESilencerEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
UUID defender = game.getCombat().getDefendingPlayerId(source.getSourceId(), game);
if(defender != null) {
game.damagePlayerOrPlaneswalker(defender, 1, source.getSourceId(), game, false, true);
UUID target = source.getTargets().getFirstTarget();
Permanent permanent = game.getPermanent(target);
if(permanent != null) {
permanent.damage(1, source.getSourceId(), game, false, true);
}
return true;
}
return false;
}
public TIESilencerEffect copy() {
return new TIESilencerEffect(this);
}
}

View file

@ -0,0 +1,36 @@
package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author NinthWorld
*/
public final class TIEStriker extends CardImpl {
public TIEStriker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
}
public TIEStriker(final TIEStriker card) {
super(card);
}
@Override
public TIEStriker copy() {
return new TIEStriker(this);
}
}

View file

@ -0,0 +1,51 @@
package mage.cards.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureOrPlayer;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author NinthWorld
*/
public final class ThermalDetonator extends CardImpl {
private static final FilterCreatureOrPlayer filter = new FilterCreatureOrPlayer("creature without spaceflight or target player");
static {
filter.add(Predicates.not(new AbilityPredicate(SpaceflightAbility.class)));
}
public ThermalDetonator(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {2}, Sacrifice Thermal Detonator: Thermal Detonator deals 2 damage to target creature without spaceflight or target player.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(2), new ManaCostsImpl("{2}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCreatureOrPlayer(filter));
this.addAbility(ability);
}
public ThermalDetonator(final ThermalDetonator card) {
super(card);
}
@Override
public ThermalDetonator copy() {
return new ThermalDetonator(this);
}
}

View file

@ -0,0 +1,185 @@
package mage.cards.t;
import java.util.Objects;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.*;
import mage.abilities.effects.common.ExileCardsFromTopOfLibraryTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.BountyAbility;
import mage.cards.Card;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.counters.CounterType;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.ManaPoolItem;
import mage.players.Player;
import mage.target.common.TargetOpponentsCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
*
* @author NinthWorld
*/
public final class TobiasBeckett extends CardImpl {
public TobiasBeckett(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.HUNTER);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// When Tobias Becket enters the battlefield, put a bounty counter on target creature an opponent controls.
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersTargetEffect(CounterType.BOUNTY.createInstance()));
ability.addTarget(new TargetOpponentsCreaturePermanent());
this.addAbility(ability);
// Bounty - Whenever a creature an opponent controls with a bounty counter on it dies, exile the top card of that player's library. You may cast cards exiled this way and spend mana as though it were mana of any type to cast that spell.
this.addAbility(new BountyAbility(new TobiasBeckettEffect(), false, true));
}
public TobiasBeckett(final TobiasBeckett card) {
super(card);
}
@Override
public TobiasBeckett copy() {
return new TobiasBeckett(this);
}
}
// Based on GrenzoHavocRaiserEffect
class TobiasBeckettEffect extends OneShotEffect {
public TobiasBeckettEffect() {
super(Outcome.Exile);
staticText = "exile the top card of that player's library. You may cast cards exiled this way and spend mana as though it were mana of any type to cast that spell";
}
public TobiasBeckettEffect(final TobiasBeckettEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent bountyTriggered = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if(bountyTriggered != null) {
Player opponent = game.getPlayer(bountyTriggered.getControllerId());
if (opponent != null) {
MageObject sourceObject = game.getObject(source.getSourceId());
UUID exileId = CardUtil.getCardExileZoneId(game, source);
Card card = opponent.getLibrary().getFromTop(game);
if (card != null) {
// move card to exile
controller.moveCardToExileWithInfo(card, exileId, sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
// Add effects only if the card has a spellAbility (e.g. not for lands).
if (card.getSpellAbility() != null) {
// allow to cast the card
game.addEffect(new TobiasBeckettCastFromExileEffect(card.getId(), exileId), source);
// and you may spend mana as though it were mana of any color to cast it
ContinuousEffect effect = new TobiasBeckettSpendAnyManaEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
}
}
return true;
}
}
}
return false;
}
@Override
public TobiasBeckettEffect copy() {
return new TobiasBeckettEffect(this);
}
}
// Based on GrenzoHavocRaiserCastFromExileEffect
class TobiasBeckettCastFromExileEffect extends AsThoughEffectImpl {
private UUID cardId;
private UUID exileId;
public TobiasBeckettCastFromExileEffect(UUID cardId, UUID exileId) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit);
staticText = "You may cast that card and you may spend mana as though it were mana of any color to cast it";
this.cardId = cardId;
this.exileId = exileId;
}
public TobiasBeckettCastFromExileEffect(final TobiasBeckettCastFromExileEffect effect) {
super(effect);
this.cardId = effect.cardId;
this.exileId = effect.exileId;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public TobiasBeckettCastFromExileEffect copy() {
return new TobiasBeckettCastFromExileEffect(this);
}
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(cardId) && source.isControlledBy(affectedControllerId)) {
ExileZone exileZone = game.getState().getExile().getExileZone(exileId);
return exileZone != null && exileZone.contains(cardId);
}
return false;
}
}
// Based on GrenzoHavocRaiserSpendAnyManaEffect
class TobiasBeckettSpendAnyManaEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
public TobiasBeckettSpendAnyManaEffect() {
super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.EndOfTurn, Outcome.Benefit);
staticText = "you may spend mana as though it were mana of any color to cast it";
}
public TobiasBeckettSpendAnyManaEffect(final TobiasBeckettSpendAnyManaEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public TobiasBeckettSpendAnyManaEffect copy() {
return new TobiasBeckettSpendAnyManaEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, ((FixedTarget) getTargetPointer()).getTarget())
&& ((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId)
&& (((FixedTarget) getTargetPointer()).getZoneChangeCounter() + 1 == game.getState().getZoneChangeCounter(objectId))
&& game.getState().getZone(objectId) == Zone.STACK;
}
@Override
public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) {
return mana.getFirstAvailable();
}
}

View file

@ -0,0 +1,73 @@
package mage.cards.u;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceTappedCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.SpaceflightAbility;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author NinthWorld
*/
public final class UWing extends CardImpl {
public UWing(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}{U}");
this.subtype.add(SubType.REBEL);
this.subtype.add(SubType.STARSHIP);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Spaceflight
this.addAbility(SpaceflightAbility.getInstance());
// As long as U-Wing is tapped, it gets +1/+0.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
new BoostSourceEffect(1, 0, Duration.WhileOnBattlefield),
SourceTappedCondition.instance,
"As long as {this} is tapped, it gets +1/+0")));
// As long as U-Wing is untapped, it gets +0/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
new BoostSourceEffect(0, 1, Duration.WhileOnBattlefield),
SourceUntappedCondition.instance,
"As long as {this} is untapped, it gets +0/+1")));
}
public UWing(final UWing card) {
super(card);
}
@Override
public UWing copy() {
return new UWing(this);
}
}
enum SourceUntappedCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getBattlefield().getPermanent(source.getSourceId());
if (permanent != null) {
return !permanent.isTapped();
}
return false;
}
}

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