Merge pull request #1 from magefree/master

Update from original to fork
This commit is contained in:
jesusjbr 2018-08-16 00:31:46 +02:00 committed by GitHub
commit eac4950a7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
196 changed files with 10638 additions and 3334 deletions

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<groupId>org.mage</groupId>

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.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyVetoException;
import java.io.File;
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));
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() {

View file

@ -357,10 +357,81 @@ public enum GrabbagImageSource implements CardImageSource {
singleLinks.put("SWS/Yoda, Jedi Master", "6arN1Hl.png");
singleLinks.put("SWS/Y-Wing", "aQQ5zwA.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
singleLinks.put("SWS/Emblem Obi-Wan Kenobi", "Qyc10aT.png");
singleLinks.put("SWS/Aurra Sing", "BLWbVJC.png");
singleLinks.put("SWS/Yoda", "zH0sYxg.png");
singleLinks.put("SWS/Emblem Luke Skywalker", "kHELZDJ.jpg");
// Tokens
singleLinks.put("SWS/Ewok", "N2MvJyr.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/Tusken Raider", "gPMiSmP.png");
singleLinks.put("SWS/Droid", "4PRrWFF.png");
singleLinks.put("SWS/Trooper 2", "tcxvGOn.jpg");
singleLinks.put("SWS/Porg", "HBjt1A3.jpg");
}
@Override

View file

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

View file

@ -6,7 +6,6 @@ import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import mage.client.dialog.PreferencesDialog;
import org.mage.plugins.card.images.CardDownloadData;
@ -227,7 +226,8 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("A25");
supportedSets.add("DOM");
supportedSets.add("BBD");
// supportedSets.add("CM2");
supportedSets.add("C18");
supportedSets.add("CM2");
supportedSets.add("M19");
}
@ -240,7 +240,6 @@ public enum ScryfallImageSource implements CardImageSource {
// 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)
String baseUrl = null;
String alternativeUrl = null;

View file

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

View file

@ -75,4 +75,4 @@ dd3jvc=ddajvc
# Remove setname as soon as the images can be downloaded
ignore.urls=TOK,H17
# 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

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-common</artifactId>

View file

@ -13,8 +13,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
*/
public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 30;
public final static String MAGE_VERSION_MINOR_PATCH = "V6";
public final static int MAGE_VERSION_PATCH = 31;
public final static String MAGE_VERSION_MINOR_PATCH = "V0";
public final static String MAGE_VERSION_INFO = "";
private final int major;

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-counter-plugin</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<groupId>org.mage</groupId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-deck-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-deck-limited</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-brawlduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-brawlfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-canadianhighlanderduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-commanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-commanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-freeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-momirduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-momirfreeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-tinyleadersduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-game-twoplayerduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-player-ai-draftbot</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-player-ai-ma</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-player-ai</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-player-ai-mcts</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-player-aiminimax</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-player-human</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-tournament-boosterdraft</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-tournament-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-tournament-sealed</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-server-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<artifactId>mage-server</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.30</version>
<version>1.4.31</version>
</parent>
<groupId>org.mage</groupId>

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.LoyaltyAbility;
import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
@ -29,6 +30,10 @@ import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
*
* @author Colin Redman
*/
public class AminatouTheFateShifter extends CardImpl {
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.
ability = new LoyaltyAbility(new AminatouUltimateEffect(), -6);
this.addAbility(ability);
// Aminatou, the Fateshifter can be your commander.
this.addAbility(CanBeYourCommanderAbility.getInstance());
}
public AminatouTheFateShifter(final AminatouTheFateShifter card) {
super(card);

View file

@ -0,0 +1,253 @@
package mage.cards.a;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.Costs;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.*;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.ExileZone;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Optional;
import java.util.UUID;
/**
*
* @author credman0
*/
public class AminatousAugury extends CardImpl {
public AminatousAugury(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{6}{U}{U}");
// Exile the top eight cards of your library. You may put a land card from among them onto the battlefield.
// Until end of turn, for each nonland card type, you may cast a card of that type from among the exiled cards
// without paying its mana cost.
this.getSpellAbility().addEffect(new AminatousAuguryEffect());
}
public AminatousAugury(final AminatousAugury card) {
super(card);
}
@Override
public AminatousAugury copy() {
return new AminatousAugury(this);
}
}
class AminatousAuguryEffect extends OneShotEffect{
public AminatousAuguryEffect() {
super(Outcome.PlayForFree);
staticText = "Exile the top eight cards of your library. You may put a land card from among them onto the" +
" battlefield. Until end of turn, for each nonland card type, you may cast a card of that type from" +
" among the exiled cards without paying its mana cost.";
}
public AminatousAuguryEffect(final AminatousAuguryEffect effect) {
super(effect);
}
@Override
public AminatousAuguryEffect copy() {
return new AminatousAuguryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller != null && sourceObject != null) {
// move cards from library to exile
controller.moveCardsToExile(controller.getLibrary().getTopCards(game, 8), source, game, true, source.getSourceId(), CardUtil.createObjectRealtedWindowTitle(source, game, null));
ExileZone auguryExileZone = game.getExile().getExileZone(source.getSourceId());
if (auguryExileZone == null) {
return true;
}
Cards cardsToCast = new CardsImpl();
cardsToCast.addAll(auguryExileZone.getCards(game));
// put a land card from among them onto the battlefield
TargetCard target = new TargetCard(
Zone.EXILED,
StaticFilters.FILTER_CARD_LAND_A
);
if (controller.chooseUse(Outcome.PutLandInPlay, "Put a land from among the exiled cards into play?", source, game)) {
if (controller.choose(Outcome.PutLandInPlay, cardsToCast, target, game)) {
Card card = cardsToCast.get(target.getFirstTarget(), game);
if (card != null) {
cardsToCast.remove(card);
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
}
}
}
AminatousAuguryExileHandler exileHandler = new AminatousAuguryExileHandler(cardsToCast, source, game);
for (Card card:cardsToCast.getCards(StaticFilters.FILTER_CARD_NON_LAND,game)) {
AminatousAuguryCastFromExileEffect effect = new AminatousAuguryCastFromExileEffect(card.getCardType(), exileHandler);
effect.setTargetPointer(new FixedTarget(card.getId(), card.getZoneChangeCounter(game)));
game.addEffect(effect, source);
}
}
return false;
}
}
class AminatousAuguryCastFromExileEffect extends AsThoughEffectImpl {
private final AminatousAuguryExileHandler cardTypeHandler;
private final EnumSet<CardType> cardType;
public AminatousAuguryCastFromExileEffect(EnumSet<CardType> cardType, AminatousAuguryExileHandler cardTypeTracker) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.EndOfTurn, Outcome.PlayForFree);
this.cardTypeHandler = cardTypeTracker;
this.cardType = cardType;
staticText = "Cast this card without paying its mana cost";
}
public AminatousAuguryCastFromExileEffect(final AminatousAuguryCastFromExileEffect effect) {
super(effect);
this.cardTypeHandler = effect.cardTypeHandler;
this.cardType = effect.cardType;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public AminatousAuguryCastFromExileEffect copy() {
return new AminatousAuguryCastFromExileEffect(this);
}
@Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (!cardTypeHandler.atLeastOneAvailable(cardType)){
return false;
}
if (sourceId != null && sourceId.equals(getTargetPointer().getFirst(game, source))
&& affectedControllerId.equals(source.getControllerId())) {
Card card = game.getCard(sourceId);
if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) {
Player player = game.getPlayer(affectedControllerId);
Costs costs = card.getSpellAbility().getCosts().copy();
costs.add(new ConsumeCardTypeCost(cardType, cardTypeHandler));
player.setCastSourceIdWithAlternateMana(sourceId, null, costs);
return true;
}
}
return false;
}
}
/**
* Tracks which card types have already been cast, and provides utility functions for confirming used types.
* (one ExileHandler is shared between all cards from a single cast of Animatou's Augury)
*/
class AminatousAuguryExileHandler {
private final EnumSet<CardType> usedCardTypes;
public AminatousAuguryExileHandler(Cards cards, Ability source, Game game){
usedCardTypes = EnumSet.noneOf(CardType.class);
}
public EnumSet<CardType> availableTypes(EnumSet<CardType> types){
EnumSet<CardType> available = EnumSet.copyOf(types);
available.removeAll(usedCardTypes);
return available;
}
public boolean atLeastOneAvailable(EnumSet<CardType> types){
EnumSet<CardType> available = availableTypes(types);
return !available.isEmpty();
}
public boolean useCardType(CardType type){
if (usedCardTypes.contains(type)){
return false;
}
usedCardTypes.add(type);
return true;
}
}
/**
* Allows the user to choose one of the given card types
*/
class CardTypeChoice extends ChoiceImpl{
public CardTypeChoice (EnumSet<CardType> types){
super(false);
for (CardType type:types){
this.choices.add(type+"");
}
this.message = "Choose card type to cast as";
}
}
class ConsumeCardTypeCost extends CostImpl{
final private AminatousAuguryExileHandler exileHandler;
final private EnumSet<CardType> types;
public ConsumeCardTypeCost (EnumSet<CardType> types, AminatousAuguryExileHandler exileHandler){
this.exileHandler = exileHandler;
this.types = types;
this.text = "Cast as "+types;
}
@Override
public boolean canPay(Ability ability, UUID sourceId, UUID controllerId, Game game) {
return exileHandler.atLeastOneAvailable(types);
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
if (isPaid()){
return true;
}
CardType choiceType;
EnumSet<CardType> availableChoices = exileHandler.availableTypes(types);
if (availableChoices.size()==1){
// if there is only one possibility, don't need to prompt for a choice
choiceType = availableChoices.iterator().next();
}else {
Choice choice = new CardTypeChoice(availableChoices);
if (!game.getPlayer(controllerId).choose(Outcome.Neutral, choice, game)) {
return false;
}
Optional<CardType> optionalChoice = Arrays.stream(CardType.values()).filter(type -> type.toString().equals(choice.getChoice())).findAny();
if (optionalChoice.isPresent()){
choiceType = optionalChoice.get();
}else{
return false;
}
}
paid = exileHandler.useCardType(choiceType);
return paid;
}
@Override
public Cost copy() {
return new ConsumeCardTypeCost(types, exileHandler);
}
}

View file

@ -11,6 +11,7 @@ import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@ -18,7 +19,6 @@ import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.util.CardUtil;
/**
@ -85,7 +85,7 @@ class AnimarCostReductionEffect extends CostModificationEffectImpl {
public boolean applies(Ability abilityToModify, Ability source, Game game) {
if (abilityToModify instanceof SpellAbility) {
if (abilityToModify.isControlledBy(source.getControllerId())) {
Spell spell = (Spell) game.getStack().getStackObject(abilityToModify.getId());
Card spell = ((SpellAbility) abilityToModify).getCharacteristics(game);
if (spell != null) {
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.Zone;
import mage.filter.FilterAbility;
import mage.filter.FilterStackObject;
import mage.filter.predicate.ability.ArtifactSourcePredicate;
import mage.target.common.TargetActivatedAbility;
@ -25,7 +26,7 @@ import mage.target.common.TargetActivatedAbility;
*/
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 {
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.players.Player;
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.
this.getSpellAbility().addEffect(new BonfireOfTheDamnedEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addTarget(new TargetPlayerOrPlaneswalker());
// Miracle {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.Zone;
import mage.filter.FilterAbility;
import mage.filter.FilterStackObject;
import mage.filter.predicate.ability.ArtifactSourcePredicate;
import mage.target.common.TargetActivatedAbility;
@ -23,7 +24,7 @@ import mage.target.common.TargetActivatedAbility;
*/
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 {
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.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetPlayerOrPlaneswalker;
@ -36,9 +35,9 @@ public final class ChandraNalaar extends CardImpl {
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);
ability1.addTarget(new TargetPlayer());
ability1.addTarget(new TargetPlayerOrPlaneswalker());
this.addAbility(ability1);
// -X: Chandra Nalaar deals X damage to target creature.
@ -46,7 +45,7 @@ public final class ChandraNalaar extends CardImpl {
ability2.addTarget(new TargetCreaturePermanent());
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();
effects1.add(new DamageTargetEffect(10));
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

@ -97,7 +97,7 @@ public final class CityInABottle extends CardImpl {
namePredicatesArabianNights.add(new NamePredicate("Jandor's Saddlebags"));
namePredicatesArabianNights.add(new NamePredicate("Jeweled Bird"));
namePredicatesArabianNights.add(new NamePredicate("Jihad"));
namePredicatesArabianNights.add(new NamePredicate("Junún Efreet"));
namePredicatesArabianNights.add(new NamePredicate("Junun Efreet"));
namePredicatesArabianNights.add(new NamePredicate("Juzam Djinn"));
namePredicatesArabianNights.add(new NamePredicate("Khabal Ghoul"));
namePredicatesArabianNights.add(new NamePredicate("King Suleiman"));

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));
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();
effect = new DamageTargetEffect(3);
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.game.Game;
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.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.addTarget(new TargetPlayer());
ability.addTarget(new TargetPlayerOrPlaneswalker());
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
*/
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}");
this.subtype.add(SubType.DOOKU);
@ -55,13 +55,13 @@ public final class DarthTyranus extends CardImpl {
this.addAbility(ability);
}
public DarthTyranus(final DarthTyranus card) {
public DarthTyranusCountOfSerenno(final DarthTyranusCountOfSerenno card) {
super(card);
}
@Override
public DarthTyranus copy() {
return new DarthTyranus(this);
public DarthTyranusCountOfSerenno copy() {
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.game.permanent.token.TokenImpl;
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());
// {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) {
@ -43,25 +49,4 @@ public final class DimirKeyrune extends CardImpl {
public DimirKeyrune copy() {
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.filter.Filter;
import mage.filter.FilterCard;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.CardCounterPredicate;
import mage.filter.predicate.permanent.CounterPredicate;
import mage.game.Game;
@ -59,13 +60,13 @@ public final class DustOfMoments extends CardImpl {
public abstract static class DustOfMomentsEffect extends OneShotEffect {
private final Counter counter;
private final Filter<Card> permFilter;
private final Filter<Permanent> permFilter;
private final Filter<Card> exiledFilter;
public DustOfMomentsEffect() {
super(Outcome.Benefit);
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));
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.filter.common.FilterControlledPermanent;
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.);
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().addTarget(new TargetOpponent());
this.getSpellAbility().addTarget(new TargetOpponentOrPlaneswalker());
}
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) {
TargetCardInLibrary target = new TargetCardInLibrary(0, 1, StaticFilters.FILTER_CARD_BASIC_LAND);
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);
}
}

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
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());
if (player == null || permanent == null) {
return false;
@ -75,24 +75,30 @@ class FumbleEffect extends OneShotEffect {
for (UUID permId : permanent.getAttachments()) {
Permanent attachment = game.getPermanent(permId);
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);
Target target = new TargetCreaturePermanent(1, 1, StaticFilters.FILTER_PERMANENT_CREATURE, true);
Permanent newCreature = null;
if (player.choose(Outcome.BoostCreature, target, source.getSourceId(), game)) {
newCreature = game.getPermanent(target.getFirstTarget());
}
for (Permanent attachment : attachments) {
if (!attachment.hasSubtype(SubType.AURA, game) && !attachment.hasSubtype(SubType.EQUIPMENT, game)) {
continue;
if (!attachments.isEmpty()) {
Target target = new TargetCreaturePermanent(1, 1, StaticFilters.FILTER_PERMANENT_CREATURE, true);
Permanent newCreature = null;
if (player.choose(Outcome.BoostCreature, target, source.getSourceId(), game)) {
newCreature = game.getPermanent(target.getFirstTarget());
}
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);
for (Permanent attachment : attachments) {
if (!attachment.hasSubtype(SubType.AURA, game) && !attachment.hasSubtype(SubType.EQUIPMENT, game)) {
continue;
}
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;

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

@ -131,9 +131,11 @@ class HaphazardBombardmentEndOfTurnEffect extends OneShotEffect {
filter.add(new CounterPredicate(CounterType.AIM));
filter.add(Predicates.not(new AbilityPredicate(IndestructibleAbility.class)));
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
Permanent permanent = permanents.get(RandomUtil.nextInt(permanents.size()));
if (permanent != null) {
permanent.destroy(source.getSourceId(), game, false);
if (!permanents.isEmpty()) {
Permanent permanent = permanents.get(RandomUtil.nextInt(permanents.size()));
if (permanent != null) {
permanent.destroy(source.getSourceId(), game, false);
}
}
return true;
}

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.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.target.common.TargetActivatedAbility;
import mage.target.common.TargetActivatedOrTriggeredAbility;
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.
this.getSpellAbility().addEffect(new InterdictCounterEffect());
this.getSpellAbility().addTarget(new TargetActivatedOrTriggeredAbility(filter));
this.getSpellAbility().addTarget(new TargetActivatedAbility(filter));
// 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() {
}
@Override
public boolean apply(Ability input, Game game) {
if (input instanceof StackAbility && input.getAbilityType() == AbilityType.ACTIVATED) {
MageObject sourceObject = input.getSourceObject(game);
public boolean apply(StackObject input, Game game) {
if (input instanceof StackAbility && ((StackAbility) input).getAbilityType() == AbilityType.ACTIVATED) {
MageObject sourceObject = ((StackAbility) input).getSourceObject(game);
if (sourceObject != null) {
return (sourceObject.isArtifact()
|| sourceObject.isEnchantment()

View file

@ -27,7 +27,7 @@ public final class JununEfreet extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// At the beginning of your upkeep, sacrifice Junún Efreet unless you pay {B}{B}.
// At the beginning of your upkeep, sacrifice Junun Efreet unless you pay {B}{B}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{B}{B}")), TargetController.YOU, false));
}

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);
}
}

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