Merge branch 'master' into 'MCTS_AI_Improvements' + added logging to Scanner and made some optimizations to AbilitiesImpl

This commit is contained in:
betasteward 2015-01-08 22:14:09 -05:00
parent 634d7cdc3c
commit 299658054a
822 changed files with 59010 additions and 30448 deletions

View file

@ -0,0 +1,44 @@
NAME:Speed vs Cunning - Cunning
1 [DDN:48] Sparkmage Apprentice
1 [DDN:49] Lone Missionary
1 [DDN:68] Steam Augury
1 [DDN:46] Jeskai Elder
2 [DDN:69] Traumatic Visions
1 [DDN:47] Willbender
2 [DDN:44] Coral Trickster
1 [DDN:66] Hold the Line
1 [DDN:67] Inferno Trap
2 [DDN:45] Fathom Seer
1 [DDN:42] Arcanis the Omnipotent
1 [DDN:64] Mana Leak
2 [DDN:43] Faerie Impostor
1 [DDN:65] Lightning Helix
1 [DDN:62] Swift Justice
1 [DDN:63] Impulse
1 [DDN:60] Fleeting Distraction
1 [DDN:61] Stave Off
2 [DDN:80] Plains
1 [DDN:81] Plains
1 [DDN:59] Sphinx of Uthuun
1 [DDN:37] Mountain
2 [DDN:38] Plains
1 [DDN:57] Faerie Invaders
2 [DDN:79] Plains
1 [DDN:35] Mountain
1 [DDN:58] Thousand Winds
1 [DDN:36] Mountain
1 [DDN:55] Hussar Patrol
3 [DDN:77] Island
1 [DDN:56] Lightning Angel
1 [DDN:53] Stonecloaker
3 [DDN:75] Island
2 [DDN:54] Aquamorph Entity
4 [DDN:76] Island
1 [DDN:51] Echo Tracer
2 [DDN:73] Mystic Monastery
1 [DDN:52] Kor Hookmaster
2 [DDN:74] Terramorphic Expanse
1 [DDN:71] Arrow Volley Trap
1 [DDN:50] Master Decoy
1 [DDN:72] Repeal
1 [DDN:70] Whiplash Trap

View file

@ -0,0 +1,45 @@
NAME:Speed vs Cunning - Speed
1 [DDN:28] Orcish Cannonade
2 [DDN:29] Fiery Fall
1 [DDN:26] Act of Treason
1 [DDN:27] Dauntless Onslaught
1 [DDN:24] Goblin Bombardment
2 [DDN:25] Krenko's Command
1 [DDN:22] Bone Splinters
1 [DDN:23] Arc Trail
1 [DDN:20] Reckless Abandon
1 [DDN:21] Shock
2 [DDN:40] Swamp
2 [DDN:41] Swamp
1 [DDN:80] Plains
1 [DDN:19] Oni of Wild Places
1 [DDN:17] Flame-Kin Zealot
2 [DDN:39] Swamp
1 [DDN:18] Scourge Devil
1 [DDN:15] Krenko, Mob Boss
2 [DDN:37] Mountain
1 [DDN:16] Ogre Battledriver
1 [DDN:38] Plains
1 [DDN:79] Plains
3 [DDN:35] Mountain
1 [DDN:13] Mardu Heart-Piercer
3 [DDN:36] Mountain
2 [DDN:14] Beetleback Chief
1 [DDN:11] Kathari Bomber
1 [DDN:33] Ghitu Encampment
1 [DDN:12] Shambling Remains
2 [DDN:78] Mountain
2 [DDN:34] Nomad Outpost
1 [DDN:31] Banefire
1 [DDN:10] Hell's Thunder
2 [DDN:32] Evolving Wilds
1 [DDN:9] Goblin Warchief
1 [DDN:8] Fleshbag Marauder
1 [DDN:30] Fury of the Horde
1 [DDN:7] Hellraiser Goblin
1 [DDN:6] Goblin Deathraiders
2 [DDN:5] Dregscape Zombie
2 [DDN:4] Leonin Snarecaster
1 [DDN:3] Infantry Veteran
1 [DDN:2] Frenzied Goblin
1 [DDN:1] Zurgo Helmsmasher

View file

@ -1,5 +1,5 @@
woogerworks (Version 1.3.0 dev 2014-10-29V2) :xmage.woogerworks.com:17171
XMage.info 1 (Version 1.3.0 dev 2014-11-29v4) :176.31.186.181:17171
XMage.info 2 (Version 1.3.0 dev 2014-11-29V4) :176.31.186.181:17000
Seedds Server (Version 1.3.0 dev 2014-11-29v2) :115.29.203.80:17171
woogerworks :xmage.woogerworks.com:17171
XMage.info 1 :176.31.186.181:17171
XMage.info 2 :176.31.186.181:17000
Seedds Server (inactive?) :115.29.203.80:17171
localhost -> connect to your local server (must be started):localhost:17171

View file

@ -962,6 +962,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
return;
}
}
CardRepository.instance.closeDB();
Plugins.getInstance().shutdown();
dispose();
System.exit(0);

View file

@ -66,7 +66,7 @@ public class AddLandDialog extends MageDialog {
// decide from which sets basic lands are taken from
for (String setCode :deck.getExpansionSetCodes()) {
ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode);
if (expansionInfo.hasBasicLands()) {
if (expansionInfo != null && expansionInfo.hasBasicLands()) {
this.setCodesland.add(expansionInfo.getCode());
}
}
@ -75,10 +75,12 @@ public class AddLandDialog extends MageDialog {
if (this.setCodesland.isEmpty()) {
for (String setCode :deck.getExpansionSetCodes()) {
ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode);
ExpansionInfo [] blockSets = ExpansionRepository.instance.getSetsFromBlock(expansionInfo.getBlockName());
for (ExpansionInfo blockSet: blockSets) {
if (blockSet.hasBasicLands()) {
this.setCodesland.add(blockSet.getCode());
if (expansionInfo != null) {
ExpansionInfo [] blockSets = ExpansionRepository.instance.getSetsFromBlock(expansionInfo.getBlockName());
for (ExpansionInfo blockSet: blockSets) {
if (blockSet.hasBasicLands()) {
this.setCodesland.add(blockSet.getCode());
}
}
}
}

View file

@ -864,15 +864,8 @@ public final class GamePanel extends javax.swing.JPanel {
public void select(String message, GameView gameView, int messageId, Map<String, Serializable> options) {
updateGame(gameView, options);
String messageToDisplay = message;
Map<String, Serializable> panelOptions = null;
for (PlayerView playerView : gameView.getPlayers()) {
if (playerView.getPlayerId().equals(playerId)) {
if (playerView.isActive()) {
panelOptions = new HashMap<>();
panelOptions.put("your_turn", true);
messageToDisplay = message + " <div style='font-size:11pt'>Your turn</div>";
}
// magenoxx: because of uncaught bug with saving state, rolling back and stack
// undo is allowed only for empty stack
if (playerView.getStatesSavedSize() > 0 && gameView.getStack().size() == 0) {
@ -880,7 +873,18 @@ public final class GamePanel extends javax.swing.JPanel {
}
break;
}
}
Map<String, Serializable> panelOptions = new HashMap<>();
panelOptions.put("your_turn", true);
String playerName;
if (gameView.getActivePlayerId().equals(playerId)) {
playerName = "Your turn";
} else {
playerName = gameView.getActivePlayerName();
}
String messageToDisplay = message + "<div style='font-size:11pt'>" + playerName +" / " + gameView.getStep().toString() + "</div>";
this.feedbackPanel.getFeedback(FeedbackMode.SELECT, messageToDisplay, gameView.getSpecial(), panelOptions, messageId);
}

View file

@ -148,7 +148,7 @@ public class TablesPanel extends javax.swing.JPanel {
UUID gameId = (UUID)tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 2);
String action = (String)tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN);
String deckType = (String)tableModel.getValueAt(modelRow, TableTableModel.COLUMN_DECK_TYPE);
String info = (String)tableModel.getValueAt(modelRow, TableTableModel.COLUMN_INFO);
String status = (String)tableModel.getValueAt(modelRow, TableTableModel.COLUMN_STATUS);
boolean isTournament = (Boolean)tableModel.getValueAt(modelRow, TableTableModel.ACTION_COLUMN + 1);
String owner = (String)tableModel.getValueAt(modelRow, 1);
switch (action) {
@ -177,7 +177,7 @@ public class TablesPanel extends javax.swing.JPanel {
if (isTournament) {
logger.info("Joining tournament " + tableId);
if (deckType.startsWith("Limited")) {
if (!info.startsWith("PW")) {
if (!status.endsWith("PW")) {
session.joinTournamentTable(roomId, tableId, session.getUserName(), "Human", 1, null, "");
} else {
joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited"));
@ -712,6 +712,7 @@ class TableTableModel extends AbstractTableModel {
public static final int COLUMN_DECK_TYPE = 0; // column the deck type is located (starting with 0) Start string is used to check for Limited
public static final int COLUMN_INFO = 3;
public static final int COLUMN_STATUS = 4;
public static final int ACTION_COLUMN = 6; // column the action is located (starting with 0)
private final String[] columnNames = new String[]{"Deck Type", "Owner / Players", "Game Type", "Info", "Status", "Created / Started", "Action"};

View file

@ -88,8 +88,14 @@ public class ConstructedFormats {
"Duel Decks: Heroes vs. Monsters",
"Duel Decks: Jace vs. Vraska",
"Duel Decks: Speed vs. Cunning",
"Friday Night Magic",
"Game Day",
"Grand Prix",
"Guru",
"Judge Promo",
"Launch Party",
"Unhinged",
"World Magic Cup Qualifier",
};
private ConstructedFormats() {
@ -445,9 +451,27 @@ public class ConstructedFormats {
if (format.equals("Vintage Masters")) {
return Arrays.asList("VMA");
}
if (format.equals("Friday Night Magic")) {
return Arrays.asList("FNMP");
}
if (format.equals("Game Day")) {
return Arrays.asList("MGDC");
}
if (format.equals("Grand Prix")) {
return Arrays.asList("GPX");
}
if (format.equals("Launch Party")) {
return Arrays.asList("MLP");
}
if (format.equals("World Magic Cup Qualifier")) {
return Arrays.asList("WMCQ");
}
if (format.equals("Guru")) {
return Arrays.asList("GUR");
}
if (format.equals("Judge Promo")) {
return Arrays.asList("JR");
}
if (format.equals("Unhinged")) {
return Arrays.asList("UNH");
}

View file

@ -16,6 +16,12 @@ public class MagicCardsImageSource implements CardImageSource {
private static final Map<String, String> setNameTokenReplacement = new HashMap<String, String>() {
{
put("MLP", "launch-party");
put("WMCQ", "world-magic-cup-qualifier");
put("GPX", "grand-prix");
put("JR", "judge-gift-program");
put("MGDC", "magic-game-day-cards");
put("FNMP", "friday-night-magic");
put("FRF", "fate-reforged");
put("C14", "commander-2014-edition");
put("KTK", "khans-of-tarkir");

View file

@ -1,192 +1,203 @@
package org.mage.plugins.card.dl.sources;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.mage.plugins.card.images.CardDownloadData;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author North
*/
public class WizardCardsImageSource implements CardImageSource {
private static CardImageSource instance;
private static Map<String, String> setsAliases;
private final Map<String, Map<String, String>> sets;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new WizardCardsImageSource();
}
return instance;
}
public WizardCardsImageSource() {
sets = new HashMap<>();
setsAliases = new HashMap<>();
setsAliases.put("FRF", "fatereforged/cig");
setsAliases.put("KTK", "khansoftarkir/cig");
setsAliases.put("M15", "magic2015coreset/cig");
setsAliases.put("CNS", "vintagemasters/cig");
setsAliases.put("CNS", "conspiracy/cig");
setsAliases.put("JOU", "journeyintonyx/cig");
setsAliases.put("BNG", "bornofthegods/cig");
setsAliases.put("C13", "commander2013/cig");
setsAliases.put("THS", "theros/cig");
setsAliases.put("M14", "magic2014coreset/cig");
setsAliases.put("MMA", "modernmasters/cig");
setsAliases.put("DGM", "dragonsmaze/cig");
setsAliases.put("GTC", "gatecrash/cig");
setsAliases.put("RTR", "returntoravnica/cig");
setsAliases.put("M13", "magic2013/cig");
setsAliases.put("AVR", "avacynrestored/cig");
setsAliases.put("DKA", "darkascension/cig");
setsAliases.put("ISD", "innistrad/cig");
setsAliases.put("M12", "magic2012/cig");
setsAliases.put("CMD", "commander/cig");
setsAliases.put("NPH", "newphyrexia/spoiler");
setsAliases.put("MBS", "mirrodinbesieged/spoiler");
setsAliases.put("SOM", "scarsofmirrodin/spoiler");
setsAliases.put("M11", "magic2011/spoiler");
setsAliases.put("ROE", "riseoftheeldrazi/spoiler");
setsAliases.put("WWK", "worldwake/spoiler");
setsAliases.put("ZEN", "zendikar/spoiler");
setsAliases.put("M10", "magic2010/spoiler");
setsAliases.put("ARB", "alarareborn/spoiler");
setsAliases.put("CON", "conflux/spoiler");
setsAliases.put("ALA", "shardsofalara/spoiler");
setsAliases.put("PC2", "planechase2012edition/cig");
setsAliases.put("PTK", "portalthreekingdoms/cig");
setsAliases.put("EVG", "elvesvsgoblins/cig");
setsAliases.put("DD2", "jacevschandra/cig");
setsAliases.put("DDC", "divinevsdemonic/cig");
setsAliases.put("DDD", "garrukvsliliana/cig");
}
private Map<String, String> getSetLinks(String cardSet) {
Map<String, String> setLinks = new HashMap<>();
try {
String urlDocument;
if (cardSet.equals("M15")) {
urlDocument = "http://magic.wizards.com/en/content/magic-2015-core-set-card-set-archive-products-game-info";
Document doc = Jsoup.connect(urlDocument).get();
Elements cardsImages = doc.select("div.advanced-card img");
for (int i = 0; i < cardsImages.size(); i++) {
String cardName = normalizeName(cardsImages.get(i).attr("alt"));
if (cardName != null && !cardName.isEmpty()) {
if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) {
int landNumber = 1;
while (setLinks.get((cardName + landNumber).toLowerCase()) != null) {
landNumber++;
}
cardName += landNumber;
}
setLinks.put(cardName.toLowerCase(), cardsImages.get(i).attr("src"));
} else {
setLinks.put(Integer.toString(i), cardsImages.get(i).attr("src"));
}
}
} else {
urlDocument = "http://www.wizards.com/magic/tcg/article.aspx?x=mtg/tcg/" + setsAliases.get(cardSet);
Document doc = Jsoup.connect(urlDocument).get();
Elements cardsImages = doc.select("img[height$=370]");
for (int i = 0; i < cardsImages.size(); i++) {
String cardName = normalizeName(cardsImages.get(i).attr("title"));
if (cardName != null && !cardName.isEmpty()) {
if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) {
int landNumber = 1;
while (setLinks.get((cardName + landNumber).toLowerCase()) != null) {
landNumber++;
}
cardName += landNumber;
}
setLinks.put(cardName.toLowerCase(), cardsImages.get(i).attr("src"));
} else {
setLinks.put(Integer.toString(i), cardsImages.get(i).attr("src"));
}
}
cardsImages = doc.select("img[height$=470]");
for (int i = 0; i < cardsImages.size(); i++) {
String cardName = normalizeName(cardsImages.get(i).attr("title"));
if (cardName != null && !cardName.isEmpty()) {
String[] cardNames = cardName.replace(")", "").split(" \\(");
for (String name : cardNames) {
setLinks.put(name.toLowerCase(), cardsImages.get(i).attr("src"));
}
} else {
setLinks.put(Integer.toString(i), cardsImages.get(i).attr("src"));
}
}
}
} catch (IOException ex) {
System.out.println("Exception when parsing the wizards page: " + ex.getMessage());
}
return setLinks;
}
private String normalizeName(String name) {
return name.replace("\u2014", "-").replace("\u2019", "'")
.replace("\u00C6", "AE").replace("\u00E6", "ae")
.replace("\u00C1", "A").replace("\u00E1", "a")
.replace("\u00C2", "A").replace("\u00E2", "a")
.replace("\u00D6", "O").replace("\u00F6", "o")
.replace("\u00DB", "U").replace("\u00FB", "u")
.replace("\u00DC", "U").replace("\u00FC", "u")
.replace("\u00E9", "e").replace("&", "//")
.replace("Hintreland Scourge", "Hinterland Scourge");
}
@Override
public String generateURL(CardDownloadData card) throws Exception {
Integer collectorId = card.getCollectorId();
String cardSet = card.getSet();
if (collectorId == null || cardSet == null) {
throw new Exception("Wrong parameters for image: collector id: " + collectorId + ",card set: " + cardSet);
}
if (card.isFlippedSide()) { //doesn't support rotated images
return null;
}
if (setsAliases.get(cardSet) != null) {
Map<String, String> setLinks = sets.get(cardSet);
if (setLinks == null) {
setLinks = getSetLinks(cardSet);
sets.put(cardSet, setLinks);
}
String link = setLinks.get(card.getDownloadName().toLowerCase());
if (link == null) {
if (setLinks.size() >= collectorId) {
link = setLinks.get(Integer.toString(collectorId - 1));
} else {
link = setLinks.get(Integer.toString(collectorId - 21));
if (link != null) {
link = link.replace(Integer.toString(collectorId - 20), (Integer.toString(collectorId - 20) + "a"));
}
}
}
if (link != null && !link.startsWith("http://")) {
link = "http://www.wizards.com" + link;
}
return link;
}
return null;
}
@Override
public String generateTokenUrl(CardDownloadData card) {
return null;
}
@Override
public Float getAverageSize() {
return 60.0f;
}
}
package org.mage.plugins.card.dl.sources;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.mage.plugins.card.images.CardDownloadData;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author North
*/
public class WizardCardsImageSource implements CardImageSource {
private static CardImageSource instance;
private static Map<String, String> setsAliases;
private final Map<String, Map<String, String>> sets;
public static CardImageSource getInstance() {
if (instance == null) {
instance = new WizardCardsImageSource();
}
return instance;
}
public WizardCardsImageSource() {
sets = new HashMap<>();
setsAliases = new HashMap<>();
setsAliases.put("FRF", "fatereforged/cig");
setsAliases.put("C14", "commander2014/cig");
setsAliases.put("KTK", "khansoftarkir/cig");
setsAliases.put("M15", "magic2015coreset/cig");
setsAliases.put("CNS", "vintagemasters/cig");
setsAliases.put("CNS", "conspiracy/cig");
setsAliases.put("JOU", "journeyintonyx/cig");
setsAliases.put("BNG", "bornofthegods/cig");
setsAliases.put("C13", "commander2013/cig");
setsAliases.put("THS", "theros/cig");
setsAliases.put("M14", "magic2014coreset/cig");
setsAliases.put("MMA", "modernmasters/cig");
setsAliases.put("DGM", "dragonsmaze/cig");
setsAliases.put("GTC", "gatecrash/cig");
setsAliases.put("RTR", "returntoravnica/cig");
setsAliases.put("M13", "magic2013/cig");
setsAliases.put("AVR", "avacynrestored/cig");
setsAliases.put("DKA", "darkascension/cig");
setsAliases.put("ISD", "innistrad/cig");
setsAliases.put("M12", "magic2012/cig");
setsAliases.put("CMD", "commander/cig");
setsAliases.put("NPH", "newphyrexia/spoiler");
setsAliases.put("MBS", "mirrodinbesieged/spoiler");
setsAliases.put("SOM", "scarsofmirrodin/spoiler");
setsAliases.put("M11", "magic2011/spoiler");
setsAliases.put("ROE", "riseoftheeldrazi/spoiler");
setsAliases.put("WWK", "worldwake/spoiler");
setsAliases.put("ZEN", "zendikar/spoiler");
setsAliases.put("M10", "magic2010/spoiler");
setsAliases.put("ARB", "alarareborn/spoiler");
setsAliases.put("CON", "conflux/spoiler");
setsAliases.put("ALA", "shardsofalara/spoiler");
setsAliases.put("PC2", "planechase2012edition/cig");
setsAliases.put("PTK", "portalthreekingdoms/cig");
setsAliases.put("EVG", "elvesvsgoblins/cig");
setsAliases.put("DD2", "jacevschandra/cig");
setsAliases.put("DDC", "divinevsdemonic/cig");
setsAliases.put("DDD", "garrukvsliliana/cig");
setsAliases.put("DDE", "phyrexiavsthecoalition/cig");
setsAliases.put("DDF", "elspethvstezzeret/cig");
setsAliases.put("DDG", "knightsvsdragons/cig");
setsAliases.put("DDH", "ajanivsnicolbolas/cig");
setsAliases.put("DDI", "venservskoth/cig");
setsAliases.put("DDJ", "izzetvsgolgari/cig");
setsAliases.put("DDK", "sorinvstibalt/cig");
setsAliases.put("DDL", "heroesvsmonsters/cig");
setsAliases.put("DDM", "jacevsvraska/cig");
setsAliases.put("DDN", "speedvscunning/cig");
}
private Map<String, String> getSetLinks(String cardSet) {
Map<String, String> setLinks = new HashMap<>();
try {
String urlDocument;
if (cardSet.equals("M15")) {
urlDocument = "http://magic.wizards.com/en/content/magic-2015-core-set-card-set-archive-products-game-info";
Document doc = Jsoup.connect(urlDocument).get();
Elements cardsImages = doc.select("div.advanced-card img");
for (int i = 0; i < cardsImages.size(); i++) {
String cardName = normalizeName(cardsImages.get(i).attr("alt"));
if (cardName != null && !cardName.isEmpty()) {
if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) {
int landNumber = 1;
while (setLinks.get((cardName + landNumber).toLowerCase()) != null) {
landNumber++;
}
cardName += landNumber;
}
setLinks.put(cardName.toLowerCase(), cardsImages.get(i).attr("src"));
} else {
setLinks.put(Integer.toString(i), cardsImages.get(i).attr("src"));
}
}
} else {
urlDocument = "http://www.wizards.com/magic/tcg/article.aspx?x=mtg/tcg/" + setsAliases.get(cardSet);
Document doc = Jsoup.connect(urlDocument).get();
Elements cardsImages = doc.select("img[height$=370]");
for (int i = 0; i < cardsImages.size(); i++) {
String cardName = normalizeName(cardsImages.get(i).attr("title"));
if (cardName != null && !cardName.isEmpty()) {
if (cardName.equals("Forest") || cardName.equals("Swamp") || cardName.equals("Mountain") || cardName.equals("Island") || cardName.equals("Plains")) {
int landNumber = 1;
while (setLinks.get((cardName + landNumber).toLowerCase()) != null) {
landNumber++;
}
cardName += landNumber;
}
setLinks.put(cardName.toLowerCase(), cardsImages.get(i).attr("src"));
} else {
setLinks.put(Integer.toString(i), cardsImages.get(i).attr("src"));
}
}
cardsImages = doc.select("img[height$=470]");
for (int i = 0; i < cardsImages.size(); i++) {
String cardName = normalizeName(cardsImages.get(i).attr("title"));
if (cardName != null && !cardName.isEmpty()) {
String[] cardNames = cardName.replace(")", "").split(" \\(");
for (String name : cardNames) {
setLinks.put(name.toLowerCase(), cardsImages.get(i).attr("src"));
}
} else {
setLinks.put(Integer.toString(i), cardsImages.get(i).attr("src"));
}
}
}
} catch (IOException ex) {
System.out.println("Exception when parsing the wizards page: " + ex.getMessage());
}
return setLinks;
}
private String normalizeName(String name) {
return name.replace("\u2014", "-").replace("\u2019", "'")
.replace("\u00C6", "AE").replace("\u00E6", "ae")
.replace("\u00C1", "A").replace("\u00E1", "a")
.replace("\u00C2", "A").replace("\u00E2", "a")
.replace("\u00D6", "O").replace("\u00F6", "o")
.replace("\u00DB", "U").replace("\u00FB", "u")
.replace("\u00DC", "U").replace("\u00FC", "u")
.replace("\u00E9", "e").replace("&", "//")
.replace("Hintreland Scourge", "Hinterland Scourge");
}
@Override
public String generateURL(CardDownloadData card) throws Exception {
Integer collectorId = card.getCollectorId();
String cardSet = card.getSet();
if (collectorId == null || cardSet == null) {
throw new Exception("Wrong parameters for image: collector id: " + collectorId + ",card set: " + cardSet);
}
if (card.isFlippedSide()) { //doesn't support rotated images
return null;
}
if (setsAliases.get(cardSet) != null) {
Map<String, String> setLinks = sets.get(cardSet);
if (setLinks == null) {
setLinks = getSetLinks(cardSet);
sets.put(cardSet, setLinks);
}
String link = setLinks.get(card.getDownloadName().toLowerCase());
if (link == null) {
if (setLinks.size() >= collectorId) {
link = setLinks.get(Integer.toString(collectorId - 1));
} else {
link = setLinks.get(Integer.toString(collectorId - 21));
if (link != null) {
link = link.replace(Integer.toString(collectorId - 20), (Integer.toString(collectorId - 20) + "a"));
}
}
}
if (link != null && !link.startsWith("http://")) {
link = "http://www.wizards.com" + link;
}
return link;
}
return null;
}
@Override
public String generateTokenUrl(CardDownloadData card) {
return null;
}
@Override
public Float getAverageSize() {
return 60.0f;
}
}

View file

@ -589,7 +589,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
temporaryFile.delete();
}
} else {
logger.warn("Image download failed - responseCode: " + responseCode + " url: " + url.toString());
logger.warn("Image download for " + card.getName() + "("+card.getSet()+") failed - responseCode: " + responseCode + " url: " + url.toString());
if (logger.isDebugEnabled()) { // Shows the returned html from the request to the web server
logger.debug("Return ed HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream()));
}

View file

@ -1,343 +1,363 @@
|Generate|TOK:DDN|Goblin|
#|Generate|TOK:KTK|Bear|
#|Generate|TOK:KTK|Bird|
#|Generate|TOK:KTK|Goblin|
#|Generate|TOK:KTK|Morph|
#|Generate|TOK:KTK|Snake|
#|Generate|TOK:KTK|Spirit Warrior|
#|Generate|TOK:KTK|Spirit|
#|Generate|TOK:KTK|Vampire|
#|Generate|TOK:KTK|Warrior 1|
#|Generate|TOK:KTK|Warrior 2|
#|Generate|TOK:KTK|Zombie|
#|Generate|EMBLEM!:KTK|Emblem Sarkhan, the Dragonspeaker|
#|Generate|EMBLEM!:KTK|Emblem Sorin, Solemn Visitor|
|Generate|TOK:M15|Sliver|
|Generate|TOK:M15|Soldier|
|Generate|TOK:M15|Zombie|
|Generate|TOK:M15|Goblin|
|Generate|TOK:M15|Beast 1|
|Generate|TOK:M15|Insect|
|Generate|TOK:M15|Spirit|
|Generate|TOK:M15|Squid|
|Generate|TOK:M15|Beast 2|
|Generate|TOK:M15|Dragon|
|Generate|TOK:M15|Treefolk Warrior|
|Generate|TOK:M15|Land Mine|
|Generate|EMBLEM!:M15|Emblem Ajani|
|Generate|EMBLEM!:M15|Emblem Garruk|
|Generate|TOK:CNS|Zombie|
|Generate|TOK:CNS|Spirit|
|Generate|TOK:CNS|Demon|
|Generate|TOK:CNS|Ogre|
|Generate|TOK:CNS|Elephant|
|Generate|TOK:CNS|Squirrel|
|Generate|TOK:CNS|Wolf|
|Generate|TOK:CNS|Construct|
|Generate|EMBLEM!:CNS|Emblem Dack Fayden|
|Generate|TOK:JOU|Sphinx|
|Generate|TOK:JOU|Zombie|
|Generate|TOK:JOU|Minotaur|
|Generate|TOK:JOU|Hydra|
|Generate|TOK:JOU|Spider|
|Generate|TOK:JOU|Snake|
|Generate|TOK:DDM|Assassin|
|Generate|TOK:BNG|Bird 1|
|Generate|TOK:BNG|Cat Soldier|
|Generate|TOK:BNG|Soldier|
|Generate|TOK:BNG|Bird 2|
|Generate|TOK:BNG|Kraken|
|Generate|TOK:BNG|Zombie|
|Generate|TOK:BNG|Elemental|
|Generate|TOK:BNG|Centaur|
|Generate|TOK:BNG|Wolf|
|Generate|TOK:BNG|Gold|
|Generate|EMBLEM:BNG|Kiora, the Crashing Wave|
|Generate|TOK:M14|Sliver|
|Generate|TOK:M14|Angel|
|Generate|TOK:M14|Cat|
|Generate|TOK:M14|Goat|
|Generate|TOK:M14|Zombie|
|Generate|TOK:M14|Dragon|
|Generate|TOK:M14|Elemental 1|
|Generate|TOK:M14|Elemental 2|
|Generate|TOK:M14|Beast|
|Generate|TOK:M14|Saproling|
|Generate|TOK:M14|Wolf|
|Generate|EMBLEM:M14|Liliana of the Dark Realms|
|Generate|EMBLEM:M14|Garruk, Caller of Beasts|
|Generate|TOK:THS|Cleric|
|Generate|TOK:THS|Soldier 1|
|Generate|TOK:THS|Soldier 2|
|Generate|TOK:THS|Bird|
|Generate|TOK:THS|Elemental|
|Generate|TOK:THS|Harpy|
|Generate|TOK:THS|Soldier 3|
|Generate|TOK:THS|Boar|
|Generate|TOK:THS|Satyr|
|Generate|TOK:THS|Golem|
|Generate|EMBLEM-:THS|Elspeth, Suns Champion|
|Generate|TOK:DDL|Griffin|
|Generate|TOK:DDL|Beast|
|Generate|TOK:MMA|Giant Warrior|
|Generate|TOK:MMA|Kithkin Soldier|
|Generate|TOK:MMA|Soldier|
|Generate|TOK:MMA|Illusion|
|Generate|TOK:MMA|Bat|
|Generate|TOK:MMA|Goblin Rogue|
|Generate|TOK:MMA|Spider|
|Generate|TOK:MMA|Zombie|
|Generate|TOK:MMA|Dragon|
|Generate|TOK:MMA|Goblin|
|Generate|TOK:MMA|Elemental|
|Generate|TOK:MMA|Saproling|
|Generate|TOK:MMA|Treefolk Shaman|
|Generate|TOK:MMA|Faerie Rogue|
|Generate|TOK:MMA|Worm|
|Generate|EMBLEM:MMA|Elspeth, Knight Errant|
|Generate|TOK:DGM|Elemental|
|Generate|TOK:DDK|Spirit|
|Generate|TOK:GTC|Angel|
|Generate|TOK:GTC|Rat|
|Generate|TOK:GTC|Frog Lizard|
|Generate|TOK:GTC|Cleric|
|Generate|TOK:GTC|Horror|
|Generate|TOK:GTC|Soldier|
|Generate|TOK:GTC|Spirit|
|Generate|EMBLEM:GTC|Domri Rade|
|Generate|TOK:RTR|Bird|
|Generate|TOK:RTR|Knight|
|Generate|TOK:RTR|Soldier|
|Generate|TOK:RTR|Assassin|
|Generate|TOK:RTR|Dragon|
|Generate|TOK:RTR|Goblin|
|Generate|TOK:RTR|Ooze|
|Generate|TOK:RTR|Rhino|
|Generate|TOK:RTR|Saproling|
|Generate|TOK:RTR|Wurm|
|Generate|TOK:RTR|Elemental|
|Generate|TOK:RTR|Centaur 2|
|Generate|EMBLEM-:M13|Liliana of the Dark Realms|
|Generate|TOK:DDJ|Saproling|
|Generate|TOK:M13|Cat|
|Generate|TOK:M13|Goat|
|Generate|TOK:M13|Soldier|
|Generate|TOK:M13|Drake|
|Generate|TOK:M13|Zombie|
|Generate|TOK:M13|Goblin|
|Generate|TOK:M13|Hellion|
|Generate|TOK:M13|Beast|
|Generate|TOK:M13|Saproling|
|Generate|TOK:M13|Wurm|
|Generate|EMBLEM:AVR|Tamiyo, the Moon Sage|
|Generate|TOK:AVR|Angel|
|Generate|TOK:AVR|Human 1|
|Generate|TOK:AVR|Spirit 1|
|Generate|TOK:AVR|Spirit 2|
|Generate|TOK:AVR|Demon|
|Generate|TOK:AVR|Zombie|
|Generate|TOK:AVR|Human 2|
|Generate|EMBLEM:DDI|Venser, the Sojourner|
|Generate|EMBLEM:DDI|Koth of the Hammer|
|Generate|TOK:DKA|Human|
|Generate|TOK:DKA|Vampire|
|Generate|TOK:ISD|Angel|
|Generate|TOK:ISD|Spirit|
|Generate|TOK:ISD|Homunculus|
|Generate|TOK:ISD|Demon|
|Generate|TOK:ISD|Vampire|
|Generate|TOK:ISD|Wolf 1|
|Generate|TOK:ISD|Zombie 1|
|Generate|TOK:ISD|Zombie 2|
|Generate|TOK:ISD|Zombie 3|
|Generate|TOK:ISD|Ooze|
|Generate|TOK:ISD|Spider|
|Generate|TOK:ISD|Wolf 2|
|Generate|TOK:DDH|Griffin|
|Generate|TOK:DDH|Saproling|
|Generate|TOK:M12|Bird|
|Generate|TOK:M12|Soldier|
|Generate|TOK:M12|Zombie|
|Generate|TOK:M12|Beast|
|Generate|TOK:M12|Saproling|
|Generate|TOK:M12|Wurm|
|Generate|TOK:M12|Pentavite|
|Generate|TOK:NPH|Beast|
|Generate|TOK:NPH|Beast|
|Generate|TOK:NPH|Goblin|
|Generate|TOK:NPH|Golem|
|Generate|TOK:NPH|Myr|
|Generate|TOK:DDG|Goblin|
|Generate|TOK:MBS|Germ|
|Generate|TOK:MBS|Zombie|
|Generate|TOK:MBS|Golem|
|Generate|TOK:MBS|Horror|
|Generate|TOK:MBS|Thopter|
|Generate|TOK:MBS|Zombie|
|Generate|TOK:MBS|Zombie|
|Generate|TOK:DDF|Soldier|
|Generate|TOK:SOM|Cat|
|Generate|TOK:SOM|Soldier|
|Generate|TOK:SOM|Goblin|
|Generate|TOK:SOM|Insect|
|Generate|TOK:SOM|Wolf|
|Generate|TOK:SOM|Golem|
|Generate|TOK:SOM|Myr|
|Generate|TOK:SOM|Wurm 1|
|Generate|TOK:SOM|Wurm 2|
|Generate|TOK:M11|Avatar|
|Generate|TOK:M11|Bird|
|Generate|TOK:M11|Zombie|
|Generate|TOK:M11|Beast|
|Generate|TOK:M11|Ooze 1|
|Generate|TOK:M11|Ooze 2|
|Generate|TOK:ROE|Eldrazi Spawn 1|
|Generate|TOK:ROE|Eldrazi Spawn 2|
|Generate|TOK:ROE|Eldrazi Spawn 3|
|Generate|TOK:ROE|Elemental|
|Generate|TOK:ROE|Ooze|
|Generate|TOK:ROE|Tuktuk the Returned|
|Generate|TOK:DDE|Saproling|
|Generate|TOK:DDE|Hornet|
|Generate|TOK:DDE|Minion|
|Generate|TOK:WWK|Soldier Ally|
|Generate|TOK:WWK|Dragon|
|Generate|TOK:WWK|Ogre|
|Generate|TOK:WWK|Elephant|
|Generate|TOK:WWK|Plant|
|Generate|TOK:WWK|Construct|
|Generate|TOK:ZEN|Angel|
|Generate|TOK:ZEN|Bird|
|Generate|TOK:ZEN|Kor Soldier|
|Generate|TOK:ZEN|Illusion|
|Generate|TOK:ZEN|Merfolk|
|Generate|TOK:ZEN|Vampire|
|Generate|TOK:ZEN|Zombie Giant|
|Generate|TOK:ZEN|Elemental|
|Generate|TOK:ZEN|Beast|
|Generate|TOK:ZEN|Snake|
|Generate|TOK:ZEN|Wolf|
|Generate|TOK:M10|Avatar|
|Generate|TOK:M10|Beast|
|Generate|TOK:M10|Gargoyle|
|Generate|TOK:M10|Goblin|
|Generate|TOK:M10|Insect|
|Generate|TOK:M10|Soldier|
|Generate|TOK:M10|Wolf|
|Generate|TOK:M10|Zombie|
|Generate|TOK:DDD|Beast 1|
|Generate|TOK:DDD|Beast 2|
|Generate|TOK:DDD|Elephant|
|Generate|TOK:ARB|Bird Soldier|
|Generate|TOK:ARB|Lizard|
|Generate|TOK:ARB|Dragon|
|Generate|TOK:ARB|Zombie Wizard|
|Generate|TOK:DDC|Spirit|
|Generate|TOK:DDC|Demon|
|Generate|TOK:DDC|Thrull|
|Generate|TOK:CON|Angel|
|Generate|TOK:CON|Elemental|
|Generate|TOK:DD2|Elemental Shaman|
|Generate|TOK:ALA|Soldier|
|Generate|TOK:ALA|Beast|
|Generate|TOK:ALA|Homunculus|
|Generate|TOK:ALA|Thopter|
|Generate|TOK:ALA|Skeleton|
|Generate|TOK:ALA|Zombie|
|Generate|TOK:ALA|Dragon|
|Generate|TOK:ALA|Goblin|
|Generate|TOK:ALA|Ooze|
|Generate|TOK:ALA|Saproling|
|Generate|TOK:EVE|Goat|
|Generate|TOK:EVE|Bird|
|Generate|TOK:EVE|Beast|
|Generate|TOK:EVE|Spirit|
|Generate|TOK:EVE|Elemental|
|Generate|TOK:EVE|Worm|
|Generate|TOK:EVE|Goblin Soldier|
|Generate|TOK:SHM|Kithkin Soldier|
|Generate|TOK:SHM|Spirit|
|Generate|TOK:SHM|Rat|
|Generate|TOK:SHM|Elemental 1|
|Generate|TOK:SHM|Elf Warrior 1|
|Generate|TOK:SHM|Spider|
|Generate|TOK:SHM|Wolf|
|Generate|TOK:SHM|Faerie Rogue|
|Generate|TOK:SHM|Elemental 2|
|Generate|TOK:SHM|Giant Warrior|
|Generate|TOK:SHM|Goblin Warrior|
|Generate|TOK:SHM|Elf Warrior 2|
|Generate|TOK:EVG|Elemental|
|Generate|TOK:EVG|Elf Warrior|
|Generate|TOK:EVG|Goblin|
|Generate|TOK:MOR|Giant Warrior|
|Generate|TOK:MOR|Faerie Rogue|
|Generate|TOK:MOR|Treefolk Shaman|
|Generate|TOK:LRW|Avatar|
|Generate|TOK:LRW|Elemental 1|
|Generate|TOK:LRW|Kithkin Soldier|
|Generate|TOK:LRW|Merfolk Wizard|
|Generate|TOK:LRW|Goblin Rogue|
|Generate|TOK:LRW|Elemental Shaman|
|Generate|TOK:LRW|Beast|
|Generate|TOK:LRW|Elemental 2|
|Generate|TOK:LRW|Elf Warrior|
|Generate|TOK:LRW|Wolf|
|Generate|TOK:LRW|Shapeshifter|
|Generate|TOK:10E|Soldier|
|Generate|TOK:10E|Zombie|
|Generate|TOK:10E|Dragon|
|Generate|TOK:10E|Goblin|
|Generate|TOK:10E|Saproling|
|Generate|TOK:10E|Wasp|
|Generate|TOK:CSP|Marit Lage|
$|Generate|TOK:MLP|Thopter|
#|Generate|TOK:WMCQ|Angel|
#|Generate|TOK:GPX|Elephant|
#|Generate|TOK:GPX|Germ|
#|Generate|TOK:JR|Angel|
#|Generate|TOK:JR|Faerie Rogue|
#|Generate|TOK:JR|Soldier|
#|Generate|TOK:JR|Squirrel|
#|Generate|TOK:MGDC|Centaur|
#|Generate|TOK:MGDC|Knight|
#|Generate|TOK:MGDC|Rhino|
#|Generate|TOK:MGDC|Sliver|
#|Generate|TOK:FNMP|Centaur|
#|Generate|TOK:FNMP|Wurm|
|Generate|TOK:DDN|Goblin|
#|Generate|TOK:KTK|Bear|
#|Generate|TOK:KTK|Bird|
#|Generate|TOK:KTK|Goblin|
#|Generate|TOK:KTK|Morph|
#|Generate|TOK:KTK|Snake|
#|Generate|TOK:KTK|Spirit Warrior|
#|Generate|TOK:KTK|Spirit|
#|Generate|TOK:KTK|Vampire|
#|Generate|TOK:KTK|Warrior 1|
#|Generate|TOK:KTK|Warrior 2|
#|Generate|TOK:KTK|Zombie|
#|Generate|EMBLEM!:KTK|Emblem Sarkhan, the Dragonspeaker|
#|Generate|EMBLEM!:KTK|Emblem Sorin, Solemn Visitor|
|Generate|TOK:M15|Sliver|
|Generate|TOK:M15|Soldier|
|Generate|TOK:M15|Zombie|
|Generate|TOK:M15|Goblin|
|Generate|TOK:M15|Beast 1|
|Generate|TOK:M15|Insect|
|Generate|TOK:M15|Spirit|
|Generate|TOK:M15|Squid|
|Generate|TOK:M15|Beast 2|
|Generate|TOK:M15|Dragon|
|Generate|TOK:M15|Treefolk Warrior|
|Generate|TOK:M15|Land Mine|
|Generate|EMBLEM!:M15|Emblem Ajani|
|Generate|EMBLEM!:M15|Emblem Garruk|
|Generate|TOK:CNS|Zombie|
|Generate|TOK:CNS|Spirit|
|Generate|TOK:CNS|Demon|
|Generate|TOK:CNS|Ogre|
|Generate|TOK:CNS|Elephant|
|Generate|TOK:CNS|Squirrel|
|Generate|TOK:CNS|Wolf|
|Generate|TOK:CNS|Construct|
|Generate|EMBLEM!:CNS|Emblem Dack Fayden|
|Generate|TOK:JOU|Sphinx|
|Generate|TOK:JOU|Zombie|
|Generate|TOK:JOU|Minotaur|
|Generate|TOK:JOU|Hydra|
|Generate|TOK:JOU|Spider|
|Generate|TOK:JOU|Snake|
|Generate|TOK:DDM|Assassin|
|Generate|TOK:BNG|Bird 1|
|Generate|TOK:BNG|Cat Soldier|
|Generate|TOK:BNG|Soldier|
|Generate|TOK:BNG|Bird 2|
|Generate|TOK:BNG|Kraken|
|Generate|TOK:BNG|Zombie|
|Generate|TOK:BNG|Elemental|
|Generate|TOK:BNG|Centaur|
|Generate|TOK:BNG|Wolf|
|Generate|TOK:BNG|Gold|
|Generate|EMBLEM:BNG|Kiora, the Crashing Wave|
|Generate|TOK:M14|Sliver|
|Generate|TOK:M14|Angel|
|Generate|TOK:M14|Cat|
|Generate|TOK:M14|Goat|
|Generate|TOK:M14|Zombie|
|Generate|TOK:M14|Dragon|
|Generate|TOK:M14|Elemental 1|
|Generate|TOK:M14|Elemental 2|
|Generate|TOK:M14|Beast|
|Generate|TOK:M14|Saproling|
|Generate|TOK:M14|Wolf|
|Generate|EMBLEM:M14|Liliana of the Dark Realms|
|Generate|EMBLEM:M14|Garruk, Caller of Beasts|
|Generate|TOK:THS|Cleric|
|Generate|TOK:THS|Soldier 1|
|Generate|TOK:THS|Soldier 2|
|Generate|TOK:THS|Bird|
|Generate|TOK:THS|Elemental|
|Generate|TOK:THS|Harpy|
|Generate|TOK:THS|Soldier 3|
|Generate|TOK:THS|Boar|
|Generate|TOK:THS|Satyr|
|Generate|TOK:THS|Golem|
|Generate|EMBLEM-:THS|Elspeth, Suns Champion|
|Generate|TOK:DDL|Griffin|
|Generate|TOK:DDL|Beast|
|Generate|TOK:MMA|Giant Warrior|
|Generate|TOK:MMA|Kithkin Soldier|
|Generate|TOK:MMA|Soldier|
|Generate|TOK:MMA|Illusion|
|Generate|TOK:MMA|Bat|
|Generate|TOK:MMA|Goblin Rogue|
|Generate|TOK:MMA|Spider|
|Generate|TOK:MMA|Zombie|
|Generate|TOK:MMA|Dragon|
|Generate|TOK:MMA|Goblin|
|Generate|TOK:MMA|Elemental|
|Generate|TOK:MMA|Saproling|
|Generate|TOK:MMA|Treefolk Shaman|
|Generate|TOK:MMA|Faerie Rogue|
|Generate|TOK:MMA|Worm|
|Generate|EMBLEM:MMA|Elspeth, Knight Errant|
|Generate|TOK:DGM|Elemental|
|Generate|TOK:DDK|Spirit|
|Generate|TOK:GTC|Angel|
|Generate|TOK:GTC|Rat|
|Generate|TOK:GTC|Frog Lizard|
|Generate|TOK:GTC|Cleric|
|Generate|TOK:GTC|Horror|
|Generate|TOK:GTC|Soldier|
|Generate|TOK:GTC|Spirit|
|Generate|EMBLEM:GTC|Domri Rade|
|Generate|TOK:RTR|Bird|
|Generate|TOK:RTR|Knight|
|Generate|TOK:RTR|Soldier|
|Generate|TOK:RTR|Assassin|
|Generate|TOK:RTR|Dragon|
|Generate|TOK:RTR|Goblin|
|Generate|TOK:RTR|Ooze|
|Generate|TOK:RTR|Rhino|
|Generate|TOK:RTR|Saproling|
|Generate|TOK:RTR|Wurm|
|Generate|TOK:RTR|Elemental|
|Generate|TOK:RTR|Centaur 2|
|Generate|EMBLEM-:M13|Liliana of the Dark Realms|
|Generate|TOK:DDJ|Saproling|
|Generate|TOK:M13|Cat|
|Generate|TOK:M13|Goat|
|Generate|TOK:M13|Soldier|
|Generate|TOK:M13|Drake|
|Generate|TOK:M13|Zombie|
|Generate|TOK:M13|Goblin|
|Generate|TOK:M13|Hellion|
|Generate|TOK:M13|Beast|
|Generate|TOK:M13|Saproling|
|Generate|TOK:M13|Wurm|
|Generate|EMBLEM:AVR|Tamiyo, the Moon Sage|
|Generate|TOK:AVR|Angel|
|Generate|TOK:AVR|Human 1|
|Generate|TOK:AVR|Spirit 1|
|Generate|TOK:AVR|Spirit 2|
|Generate|TOK:AVR|Demon|
|Generate|TOK:AVR|Zombie|
|Generate|TOK:AVR|Human 2|
|Generate|EMBLEM:DDI|Venser, the Sojourner|
|Generate|EMBLEM:DDI|Koth of the Hammer|
|Generate|TOK:DKA|Human|
|Generate|TOK:DKA|Vampire|
|Generate|TOK:ISD|Angel|
|Generate|TOK:ISD|Spirit|
|Generate|TOK:ISD|Homunculus|
|Generate|TOK:ISD|Demon|
|Generate|TOK:ISD|Vampire|
|Generate|TOK:ISD|Wolf 1|
|Generate|TOK:ISD|Zombie 1|
|Generate|TOK:ISD|Zombie 2|
|Generate|TOK:ISD|Zombie 3|
|Generate|TOK:ISD|Ooze|
|Generate|TOK:ISD|Spider|
|Generate|TOK:ISD|Wolf 2|
|Generate|TOK:DDH|Griffin|
|Generate|TOK:DDH|Saproling|
|Generate|TOK:M12|Bird|
|Generate|TOK:M12|Soldier|
|Generate|TOK:M12|Zombie|
|Generate|TOK:M12|Beast|
|Generate|TOK:M12|Saproling|
|Generate|TOK:M12|Wurm|
|Generate|TOK:M12|Pentavite|
|Generate|TOK:NPH|Beast|
|Generate|TOK:NPH|Beast|
|Generate|TOK:NPH|Goblin|
|Generate|TOK:NPH|Golem|
|Generate|TOK:NPH|Myr|
|Generate|TOK:DDG|Goblin|
|Generate|TOK:MBS|Germ|
|Generate|TOK:MBS|Zombie|
|Generate|TOK:MBS|Golem|
|Generate|TOK:MBS|Horror|
|Generate|TOK:MBS|Thopter|
|Generate|TOK:MBS|Zombie|
|Generate|TOK:MBS|Zombie|
|Generate|TOK:DDF|Soldier|
|Generate|TOK:SOM|Cat|
|Generate|TOK:SOM|Soldier|
|Generate|TOK:SOM|Goblin|
|Generate|TOK:SOM|Insect|
|Generate|TOK:SOM|Wolf|
|Generate|TOK:SOM|Golem|
|Generate|TOK:SOM|Myr|
|Generate|TOK:SOM|Wurm 1|
|Generate|TOK:SOM|Wurm 2|
|Generate|TOK:M11|Avatar|
|Generate|TOK:M11|Bird|
|Generate|TOK:M11|Zombie|
|Generate|TOK:M11|Beast|
|Generate|TOK:M11|Ooze 1|
|Generate|TOK:M11|Ooze 2|
|Generate|TOK:ROE|Eldrazi Spawn 1|
|Generate|TOK:ROE|Eldrazi Spawn 2|
|Generate|TOK:ROE|Eldrazi Spawn 3|
|Generate|TOK:ROE|Elemental|
|Generate|TOK:ROE|Ooze|
|Generate|TOK:ROE|Tuktuk the Returned|
|Generate|TOK:DDE|Saproling|
|Generate|TOK:DDE|Hornet|
|Generate|TOK:DDE|Minion|
|Generate|TOK:WWK|Soldier Ally|
|Generate|TOK:WWK|Dragon|
|Generate|TOK:WWK|Ogre|
|Generate|TOK:WWK|Elephant|
|Generate|TOK:WWK|Plant|
|Generate|TOK:WWK|Construct|
|Generate|TOK:ZEN|Angel|
|Generate|TOK:ZEN|Bird|
|Generate|TOK:ZEN|Kor Soldier|
|Generate|TOK:ZEN|Illusion|
|Generate|TOK:ZEN|Merfolk|
|Generate|TOK:ZEN|Vampire|
|Generate|TOK:ZEN|Zombie Giant|
|Generate|TOK:ZEN|Elemental|
|Generate|TOK:ZEN|Beast|
|Generate|TOK:ZEN|Snake|
|Generate|TOK:ZEN|Wolf|
|Generate|TOK:M10|Avatar|
|Generate|TOK:M10|Beast|
|Generate|TOK:M10|Gargoyle|
|Generate|TOK:M10|Goblin|
|Generate|TOK:M10|Insect|
|Generate|TOK:M10|Soldier|
|Generate|TOK:M10|Wolf|
|Generate|TOK:M10|Zombie|
|Generate|TOK:DDD|Beast 1|
|Generate|TOK:DDD|Beast 2|
|Generate|TOK:DDD|Elephant|
|Generate|TOK:ARB|Bird Soldier|
|Generate|TOK:ARB|Lizard|
|Generate|TOK:ARB|Dragon|
|Generate|TOK:ARB|Zombie Wizard|
|Generate|TOK:DDC|Spirit|
|Generate|TOK:DDC|Demon|
|Generate|TOK:DDC|Thrull|
|Generate|TOK:CON|Angel|
|Generate|TOK:CON|Elemental|
|Generate|TOK:DD2|Elemental Shaman|
|Generate|TOK:ALA|Soldier|
|Generate|TOK:ALA|Beast|
|Generate|TOK:ALA|Homunculus|
|Generate|TOK:ALA|Thopter|
|Generate|TOK:ALA|Skeleton|
|Generate|TOK:ALA|Zombie|
|Generate|TOK:ALA|Dragon|
|Generate|TOK:ALA|Goblin|
|Generate|TOK:ALA|Ooze|
|Generate|TOK:ALA|Saproling|
|Generate|TOK:EVE|Goat|
|Generate|TOK:EVE|Bird|
|Generate|TOK:EVE|Beast|
|Generate|TOK:EVE|Spirit|
|Generate|TOK:EVE|Elemental|
|Generate|TOK:EVE|Worm|
|Generate|TOK:EVE|Goblin Soldier|
|Generate|TOK:SHM|Kithkin Soldier|
|Generate|TOK:SHM|Spirit|
|Generate|TOK:SHM|Rat|
|Generate|TOK:SHM|Elemental 1|
|Generate|TOK:SHM|Elf Warrior 1|
|Generate|TOK:SHM|Spider|
|Generate|TOK:SHM|Wolf|
|Generate|TOK:SHM|Faerie Rogue|
|Generate|TOK:SHM|Elemental 2|
|Generate|TOK:SHM|Giant Warrior|
|Generate|TOK:SHM|Goblin Warrior|
|Generate|TOK:SHM|Elf Warrior 2|
|Generate|TOK:EVG|Elemental|
|Generate|TOK:EVG|Elf Warrior|
|Generate|TOK:EVG|Goblin|
|Generate|TOK:MOR|Giant Warrior|
|Generate|TOK:MOR|Faerie Rogue|
|Generate|TOK:MOR|Treefolk Shaman|
|Generate|TOK:LRW|Avatar|
|Generate|TOK:LRW|Elemental 1|
|Generate|TOK:LRW|Kithkin Soldier|
|Generate|TOK:LRW|Merfolk Wizard|
|Generate|TOK:LRW|Goblin Rogue|
|Generate|TOK:LRW|Elemental Shaman|
|Generate|TOK:LRW|Beast|
|Generate|TOK:LRW|Elemental 2|
|Generate|TOK:LRW|Elf Warrior|
|Generate|TOK:LRW|Wolf|
|Generate|TOK:LRW|Shapeshifter|
|Generate|TOK:10E|Soldier|
|Generate|TOK:10E|Zombie|
|Generate|TOK:10E|Dragon|
|Generate|TOK:10E|Goblin|
|Generate|TOK:10E|Saproling|
|Generate|TOK:10E|Wasp|
|Generate|TOK:CSP|Marit Lage|
|Generate|TOK:CHK|Spirit|

View file

@ -31,7 +31,6 @@ package mage.view;
import mage.abilities.Ability;
import mage.abilities.common.TurnFaceUpAbility;
import mage.cards.Card;
import mage.constants.Rarity;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
@ -135,6 +134,14 @@ public class PermanentView extends CardView {
}
} else{
if (controlled && card != null) {
for (Ability permanentAbility : permanent.getAbilities()) {
if (permanentAbility instanceof TurnFaceUpAbility && !permanentAbility.getRuleVisible()) {
this.rules.add(permanentAbility.getRule(true));
}
if (permanentAbility.getWorksFaceDown()) {
this.rules.add(permanentAbility.getRule());
}
}
this.name = card.getName();
this.displayName = card.getName();
}

View file

@ -45,7 +45,7 @@ public class CommanderFreeForAllMatch extends MatchImpl {
public void startGame() throws GameException {
int startLife = 40;
boolean alsoLibrary = false;
if (options.getDeckType().equals("Duel Commander")) {
if (options.getDeckType().equals("Variant Magic - Duel Commander")) {
startLife = 30;
alsoLibrary = true;
}

View file

@ -1112,24 +1112,24 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
if (attacker.getToughness().getValue() == blocker.getPower().getValue()
&& attacker.getPower().getValue() == blocker.getToughness().getValue()) {
if (attackerValue > blockerValue
|| blocker.getAbilities(game).containsKey(FirstStrikeAbility.getInstance().getId())
|| blocker.getAbilities(game).containsKey(DoubleStrikeAbility.getInstance().getId())
|| blocker.getAbilities(game).contains(new ExaltedAbility())
|| blocker.getAbilities(game).containsKey(DeathtouchAbility.getInstance().getId())
|| blocker.getAbilities(game).containsKey(IndestructibleAbility.getInstance().getId())
|| !attacker.getAbilities(game).containsKey(FirstStrikeAbility.getInstance().getId())
|| !attacker.getAbilities(game).containsKey(DoubleStrikeAbility.getInstance().getId())
|| !attacker.getAbilities(game).contains(new ExaltedAbility())) {
|| blocker.hasAbility(FirstStrikeAbility.getInstance().getId(), game)
|| blocker.hasAbility(DoubleStrikeAbility.getInstance().getId(), game)
|| blocker.hasAbility(new ExaltedAbility(), game)
|| blocker.hasAbility(DeathtouchAbility.getInstance().getId(), game)
|| blocker.hasAbility(IndestructibleAbility.getInstance().getId(), game)
|| !attacker.hasAbility(FirstStrikeAbility.getInstance().getId(), game)
|| !attacker.hasAbility(DoubleStrikeAbility.getInstance().getId(), game)
|| !attacker.hasAbility(new ExaltedAbility(), game)) {
safeToAttack = false;
}
}
if (attacker.getAbilities(game).containsKey(DeathtouchAbility.getInstance().getId())
|| attacker.getAbilities(game).containsKey(IndestructibleAbility.getInstance().getId())) {
if (attacker.hasAbility(DeathtouchAbility.getInstance().getId(), game)
|| attacker.hasAbility(IndestructibleAbility.getInstance().getId(), game)) {
safeToAttack = true;
}
if (attacker.getAbilities(game).containsKey(FlyingAbility.getInstance().getId())
&& !blocker.getAbilities(game).containsKey(FlyingAbility.getInstance().getId())
&& !blocker.getAbilities(game).containsKey(ReachAbility.getInstance().getId())) {
if (attacker.hasAbility(FlyingAbility.getInstance().getId(), game)
&& !blocker.hasAbility(FlyingAbility.getInstance().getId(), game)
&& !blocker.hasAbility(ReachAbility.getInstance().getId(), game)) {
safeToAttack = true;
}
}

View file

@ -68,7 +68,7 @@ public class ArtificialScoringSystem {
int score = permanent.getCounters().getCount(CounterType.CHARGE) * 30;
score += permanent.getCounters().getCount(CounterType.LEVEL) * 30;
score -= permanent.getDamage() * 2;
if (!canTap(permanent)) {
if (!canTap(permanent, game)) {
score += getTappedScore(permanent);
}
if (permanent.getCardType().contains(CardType.CREATURE)) {
@ -114,11 +114,11 @@ public class ArtificialScoringSystem {
return score;
}
private static boolean canTap(Permanent permanent) {
private static boolean canTap(Permanent permanent, Game game) {
return !permanent.isTapped()
&&(!permanent.hasSummoningSickness()
||!permanent.getCardType().contains(CardType.CREATURE)
||permanent.getAbilities().contains(HasteAbility.getInstance()));
||permanent.hasAbility(HasteAbility.getInstance(), game));
}
private static int getPositive(int value) {

View file

@ -51,13 +51,13 @@ public class CombatUtil {
// now count if it is possible to win the game by this attack using unblockable attackers and
// those attackers that won't be blocked for sure (as player will block other creatures)
if (sumDamage(attackersThatWontBeBlocked, defender) >= defender.getLife() && defender.isLifeTotalCanChange()
if (sumDamage(attackersThatWontBeBlocked, defender, game) >= defender.getLife() && defender.isLifeTotalCanChange()
&& defender.canLose(game) && defender.getLife() > 0) {
blockableAttackers.addAll(unblockableAttackers);
return blockableAttackers;
}
if (sumPoisonDamage(attackersThatWontBeBlocked, defender) >= 10 - defender.getCounters().getCount(CounterType.POISON)) {
if (sumPoisonDamage(attackersThatWontBeBlocked, defender, game) >= 10 - defender.getCounters().getCount(CounterType.POISON)) {
blockableAttackers.addAll(unblockableAttackers);
return blockableAttackers;
}
@ -108,12 +108,12 @@ public class CombatUtil {
return creatures.get(0);
}
private static int sumDamage(List<Permanent> attackersThatWontBeBlocked, Player defender) {
private static int sumDamage(List<Permanent> attackersThatWontBeBlocked, Player defender, Game game) {
int damage = 0;
for (Permanent attacker : attackersThatWontBeBlocked) {
if (!attacker.getAbilities().contains(InfectAbility.getInstance())) {
if (!attacker.hasAbility(InfectAbility.getInstance(), game)) {
damage += attacker.getPower().getValue();
if (attacker.getAbilities().contains(DoubleStrikeAbility.getInstance())) {
if (attacker.hasAbility(DoubleStrikeAbility.getInstance(), game)) {
damage += attacker.getPower().getValue();
}
}
@ -121,12 +121,12 @@ public class CombatUtil {
return damage;
}
private static int sumPoisonDamage(List<Permanent> attackersThatWontBeBlocked, Player defender) {
private static int sumPoisonDamage(List<Permanent> attackersThatWontBeBlocked, Player defender, Game game) {
int damage = 0;
for (Permanent attacker : attackersThatWontBeBlocked) {
if (attacker.getAbilities().contains(InfectAbility.getInstance())) {
if (attacker.hasAbility(InfectAbility.getInstance(), game)) {
damage += attacker.getPower().getValue();
if (attacker.getAbilities().contains(DoubleStrikeAbility.getInstance())) {
if (attacker.hasAbility(DoubleStrikeAbility.getInstance(), game)) {
damage += attacker.getPower().getValue();
}
}

View file

@ -1007,9 +1007,16 @@ public class ComputerPlayer extends PlayerImpl implements Player {
log.debug("findPlayables: " + playableInstant.toString() + "---" + playableNonInstant.toString() + "---" + playableAbilities.toString() );
}
}
@Override
public boolean playMana(ManaCost unpaid, Game game) {
payManaMode = true;
boolean result = playManaHandling(unpaid, game);
payManaMode = false;
return result;
}
protected boolean playManaHandling(ManaCost unpaid, Game game) {
// log.info("paying for " + unpaid.getText());
ManaCost cost;
List<Permanent> producers;

View file

@ -604,8 +604,17 @@ public class HumanPlayer extends PlayerImpl {
return null;
}
@Override
public boolean playMana(ManaCost unpaid, Game game) {
payManaMode = true;
boolean result = playManaHandling(unpaid, game);
payManaMode = false;
return result;
}
protected boolean playManaHandling(ManaCost unpaid, Game game) {
updateGameStatePriority("playMana", game);
game.firePlayManaEvent(playerId, "Pay " + unpaid.getText());
waitForResponse(game);

View file

@ -47,6 +47,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPOutputStream;
import mage.MageException;
@ -100,6 +101,9 @@ public class GameController implements GameCallback {
protected ScheduledExecutorService joinWaitingExecutor = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> futureTimeout;
protected static ScheduledExecutorService timeoutIdleExecutor = ThreadExecutor.getInstance().getTimeoutIdleExecutor();
private ConcurrentHashMap<UUID, GameSessionPlayer> gameSessions = new ConcurrentHashMap<>();
private ConcurrentHashMap<UUID, GameSessionWatcher> watchers = new ConcurrentHashMap<>();
private ConcurrentHashMap<UUID, PriorityTimer> timers = new ConcurrentHashMap<>();
@ -123,7 +127,7 @@ public class GameController implements GameCallback {
this.choosingPlayerId = choosingPlayerId;
for (Player player: game.getPlayers().values()) {
if (!player.isHuman()) {
useTimeout = false; // no timeout because of beeing idle if playing against AI
useTimeout = false; // no timeout for AI players because of beeing idle
break;
}
}
@ -132,6 +136,10 @@ public class GameController implements GameCallback {
}
public void cleanUp() {
cancelTimeout();
for (GameSessionPlayer gameSessionPlayer: gameSessions.values()) {
gameSessionPlayer.CleanUp();
}
ChatManager.getInstance().destroyChatSession(chatId);
}
@ -318,7 +326,7 @@ public class GameController implements GameCallback {
GameSessionPlayer gameSession = gameSessions.get(playerId);
String joinType;
if (gameSession == null) {
gameSession = new GameSessionPlayer(game, userId, playerId, useTimeout);
gameSession = new GameSessionPlayer(game, userId, playerId);
gameSessions.put(playerId, gameSession);
gameSession.setUserData(user.getUserData());
joinType = "joined";
@ -568,13 +576,14 @@ public class GameController implements GameCallback {
}
}
public void timeout(UUID userId) {
if (userPlayerMap.containsKey(userId)) {
String sb = game.getPlayer(userPlayerMap.get(userId)).getName() +
public void idleTimeout(UUID playerId) {
Player player = game.getPlayer(playerId);
if (player != null) {
String sb = player.getName() +
" has timed out (player had priority and was not active for " +
ConfigSettings.getInstance().getMaxSecondsIdle() + " seconds ) - Auto concede.";
ChatManager.getInstance().broadcast(chatId, "", sb, MessageColor.BLACK, true, MessageType.STATUS);
game.idleTimeout(getPlayerId(userId));
game.idleTimeout(playerId);
}
}
@ -600,7 +609,7 @@ public class GameController implements GameCallback {
public void sendPlayerUUID(UUID userId, final UUID data) {
sendMessage(userId, new Command() {
@Override
public void execute(UUID playerId) {
public void execute(UUID playerId) {
getGameSession(playerId).sendPlayerUUID(data);
}
});
@ -670,16 +679,13 @@ public class GameController implements GameCallback {
}
}
}
// TODO: inform watchers
// for (final GameWatcher gameWatcher: watchers.values()) {
// gameWatcher.update();
// }
// TODO: inform watchers about game end and who won
}
private synchronized void ask(UUID playerId, final String question) throws MageException {
perform(playerId, new Command() {
@Override
public void execute(UUID playerId) {
public void execute(UUID playerId) {
getGameSession(playerId).ask(question);
}
});
@ -893,13 +899,20 @@ public class GameController implements GameCallback {
SystemUtil.addCardsForTesting(game);
}
/**
* Performas a request to a player
* @param playerId
* @param command
* @throws MageException
*/
private void perform(UUID playerId, Command command) throws MageException {
perform(playerId, command, true);
}
private void perform(UUID playerId, Command command, boolean informOthers) throws MageException {
if (game.getPlayer(playerId).isGameUnderControl()) {
if (game.getPlayer(playerId).isGameUnderControl()) { // is the player controlling it's own turn
if (gameSessions.containsKey(playerId)) {
setupTimeout(playerId);
command.execute(playerId);
}
if (informOthers) {
@ -909,6 +922,7 @@ public class GameController implements GameCallback {
List<UUID> players = Splitter.split(game, playerId);
for (UUID uuid : players) {
if (gameSessions.containsKey(uuid)) {
setupTimeout(uuid);
command.execute(uuid);
}
}
@ -918,6 +932,11 @@ public class GameController implements GameCallback {
}
}
/**
* A player has send an answer / request
* @param userId
* @param command
*/
private void sendMessage(UUID userId, Command command) {
final UUID playerId = userPlayerMap.get(userId);
// player has game under control (is not cotrolled by other player)
@ -926,6 +945,7 @@ public class GameController implements GameCallback {
// then execute only your action
if (game.getPriorityPlayerId() == null || game.getPriorityPlayerId().equals(playerId)) {
if (gameSessions.containsKey(playerId)) {
cancelTimeout();
command.execute(playerId);
}
} else {
@ -934,6 +954,7 @@ public class GameController implements GameCallback {
if (player != null) {
for (UUID controlled : player.getPlayersUnderYourControl()) {
if (gameSessions.containsKey(controlled) && game.getPriorityPlayerId().equals(controlled)) {
cancelTimeout();
command.execute(controlled);
}
}
@ -941,11 +962,35 @@ public class GameController implements GameCallback {
// else player has no priority to do something, so ignore the command
// e.g. you click at one of your cards, but you can't play something at that moment
}
} else {
// ignore - no control over the turn
}
}
private synchronized void setupTimeout(final UUID playerId) {
if (!useTimeout) {
return;
}
cancelTimeout();
futureTimeout = timeoutIdleExecutor.schedule(
new Runnable() {
@Override
public void run() {
idleTimeout(playerId);
}
},
Main.isTestMode() ? 3600 :ConfigSettings.getInstance().getMaxSecondsIdle(),
TimeUnit.SECONDS
);
}
private synchronized void cancelTimeout() {
if (futureTimeout != null) {
futureTimeout.cancel(false);
}
}
interface Command {
void execute(UUID player);
}

View file

@ -163,13 +163,6 @@ public class GameManager {
return false;
}
public void timeout(UUID gameId, UUID userId) {
GameController gameController = gameControllers.get(gameId);
if (gameController != null) {
gameController.timeout(userId);
}
}
public void removeGame(UUID gameId) {
GameController gameController = gameControllers.get(gameId);
if (gameController != null) {

View file

@ -37,9 +37,6 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import mage.cards.Cards;
import mage.choices.Choice;
import mage.constants.ManaType;
@ -49,10 +46,8 @@ import mage.game.Table;
import mage.interfaces.callback.ClientCallback;
import mage.players.Player;
import mage.players.net.UserData;
import mage.server.Main;
import mage.server.User;
import mage.server.UserManager;
import mage.server.util.ConfigSettings;
import mage.server.util.ThreadExecutor;
import mage.view.AbilityPickerView;
import mage.view.CardsView;
@ -72,23 +67,23 @@ public class GameSessionPlayer extends GameSessionWatcher {
private static final Logger logger = Logger.getLogger(GameSessionPlayer.class);
private final UUID playerId;
private final boolean useTimeout;
private ScheduledFuture<?> futureTimeout;
protected static ScheduledExecutorService timeoutExecutor = ThreadExecutor.getInstance().getTimeoutExecutor();
private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor();
private UserData userData;
public GameSessionPlayer(Game game, UUID userId, UUID playerId, boolean useTimeout) {
public GameSessionPlayer(Game game, UUID userId, UUID playerId) {
super(userId, game, true);
this.playerId = playerId;
this.useTimeout = useTimeout;
}
@Override
public void CleanUp() {
super.CleanUp();
}
public void ask(final String question) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameAsk", game.getId(), new GameClientMessage(getGameView(), question)));
@ -98,7 +93,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void target(final String question, final CardsView cardView, final Set<UUID> targets, final boolean required, final Map<String, Serializable> options) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameTarget", game.getId(), new GameClientMessage(getGameView(), question, cardView, targets, required, options)));
@ -108,7 +102,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void select(final String message, final Map<String, Serializable> options) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameSelect", game.getId(), new GameClientMessage(getGameView(), message, options)));
@ -118,7 +111,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void chooseAbility(final AbilityPickerView abilities) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameChooseAbility", game.getId(), abilities));
@ -128,7 +120,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void choosePile(final String message, final CardsView pile1, final CardsView pile2) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameChoosePile", game.getId(), new GameClientMessage(message, pile1, pile2)));
@ -138,7 +129,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void chooseChoice(final Choice choice) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameChooseChoice", game.getId(), new GameClientMessage(choice)));
@ -148,7 +138,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void playMana(final String message) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gamePlayMana", game.getId(), new GameClientMessage(getGameView(), message)));
@ -158,7 +147,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void playXMana(final String message) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gamePlayXMana", game.getId(), new GameClientMessage(getGameView(), message)));
@ -168,7 +156,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void getAmount(final String message, final int min, final int max) {
if (!killed) {
setupTimeout();
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
user.fireCallback(new ClientCallback("gameSelectAmount", game.getId(), new GameClientMessage(message, min, max)));
@ -204,64 +191,23 @@ public class GameSessionPlayer extends GameSessionWatcher {
}
}
/**
* Reset the timeout counter after priority in game changed
*
*/
public void signalPriorityChange() {
setupTimeout();
}
private synchronized void setupTimeout() {
if (!useTimeout) {
return;
}
cancelTimeout();
futureTimeout = timeoutExecutor.schedule(
new Runnable() {
@Override
public void run() {
// if player has no priority, he does not get timeout
if(game.getPriorityPlayerId().equals(playerId)) {
GameManager.getInstance().timeout(game.getId(), userId);
} else {
setupTimeout();
}
}
},
Main.isTestMode() ? 3600 :ConfigSettings.getInstance().getMaxSecondsIdle(),
TimeUnit.SECONDS
);
}
private synchronized void cancelTimeout() {
if (futureTimeout != null) {
futureTimeout.cancel(false);
}
}
public void sendPlayerUUID(UUID data) {
cancelTimeout();
game.getPlayer(playerId).setResponseUUID(data);
}
public void sendPlayerString(String data) {
cancelTimeout();
game.getPlayer(playerId).setResponseString(data);
}
public void sendPlayerManaType(ManaType manaType, UUID manaTypePlayerId) {
cancelTimeout();
game.getPlayer(playerId).setResponseManaType(manaTypePlayerId, manaType);
}
public void sendPlayerBoolean(Boolean data) {
cancelTimeout();
game.getPlayer(playerId).setResponseBoolean(data);
}
public void sendPlayerInteger(Integer data) {
cancelTimeout();
game.getPlayer(playerId).setResponseInteger(data);
}
@ -338,7 +284,6 @@ public class GameSessionPlayer extends GameSessionWatcher {
} else {
logger.debug("- ex: " + ex.toString());
}
ex.printStackTrace();
}else {
logger.fatal("Game session game quit exception - null gameId:" + game.getId() +" playerId: " + playerId);
}

View file

@ -110,6 +110,14 @@ public class GameSessionWatcher {
}
}
/**
* Cleanup if Session ends
*
*/
public void CleanUp() {
}
public void gameError(final String message) {
if (!killed) {
User user = UserManager.getInstance().getUser(userId);

View file

@ -1,11 +1,10 @@
package mage.server.util;
import mage.game.Game;
import mage.players.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.game.Game;
import mage.players.Player;
/**
* @author nantuko
@ -13,7 +12,7 @@ import java.util.UUID;
public class Splitter {
public static List<UUID> split(Game game, UUID playerId) {
List<UUID> players = new ArrayList<UUID>();
List<UUID> players = new ArrayList<>();
//players.add(playerId); // add original player
Player player = game.getPlayer(playerId);
if (player != null && player.getTurnControlledBy() != null) {

View file

@ -43,7 +43,8 @@ public class ThreadExecutor {
private static final ExecutorService callExecutor = Executors.newCachedThreadPool();
private static final ExecutorService gameExecutor = Executors.newFixedThreadPool(ConfigSettings.getInstance().getMaxGameThreads());
private static final ScheduledExecutorService timeoutExecutor = Executors.newScheduledThreadPool(5);
private static final ScheduledExecutorService timeoutExecutor = Executors.newScheduledThreadPool(4);
private static final ScheduledExecutorService timeoutIdleExecutor = Executors.newScheduledThreadPool(4);
/**
* noxx: what the settings below do is setting the ability to keep OS threads for new games for 60 seconds
@ -62,7 +63,10 @@ public class ThreadExecutor {
((ThreadPoolExecutor)gameExecutor).setThreadFactory(new XMageThreadFactory("GAME"));
((ThreadPoolExecutor)timeoutExecutor).setKeepAliveTime(60, TimeUnit.SECONDS);
((ThreadPoolExecutor)timeoutExecutor).allowCoreThreadTimeOut(true);
((ThreadPoolExecutor)timeoutExecutor).setThreadFactory(new XMageThreadFactory("TIME"));
((ThreadPoolExecutor)timeoutExecutor).setThreadFactory(new XMageThreadFactory("TIMEOUT"));
((ThreadPoolExecutor)timeoutIdleExecutor).setKeepAliveTime(60, TimeUnit.SECONDS);
((ThreadPoolExecutor)timeoutIdleExecutor).allowCoreThreadTimeOut(true);
((ThreadPoolExecutor)timeoutIdleExecutor).setThreadFactory(new XMageThreadFactory("TIMEOUT_IDLE"));
}
private static final ThreadExecutor INSTANCE = new ThreadExecutor();
@ -91,6 +95,10 @@ public class ThreadExecutor {
public ScheduledExecutorService getTimeoutExecutor() {
return timeoutExecutor;
}
public ScheduledExecutorService getTimeoutIdleExecutor() {
return timeoutIdleExecutor;
}
}

View file

@ -0,0 +1,53 @@
/*
* 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.sets;
import java.util.GregorianCalendar;
import mage.cards.ExpansionSet;
import mage.constants.SetType;
/**
*
* @author fireshoes
*/
public class FridayNightMagic extends ExpansionSet {
private static final FridayNightMagic fINSTANCE = new FridayNightMagic();
public static FridayNightMagic getInstance() {
return fINSTANCE;
}
private FridayNightMagic() {
super("Friday Night Magic", "FNMP", "mage.sets.fridaynightmagic", new GregorianCalendar(2011, 6, 17).getTime(), SetType.REPRINT);
this.hasBoosters = false;
this.hasBasicLands = false;
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets;
import java.util.GregorianCalendar;
import mage.constants.SetType;
import mage.cards.ExpansionSet;
/**
*
* @author fireshoes
*/
public class GameDay extends ExpansionSet {
private static final GameDay fINSTANCE = new GameDay();
public static GameDay getInstance() {
return fINSTANCE;
}
private GameDay() {
super("Game Day", "MGDC", "mage.sets.gameday", new GregorianCalendar(2011, 6, 17).getTime(), SetType.REPRINT);
this.hasBoosters = false;
this.hasBasicLands = false;
}
}

View file

@ -0,0 +1,53 @@
/*
* 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.sets;
import java.util.GregorianCalendar;
import mage.constants.SetType;
import mage.cards.ExpansionSet;
/**
*
* @author fireshoes
*/
public class GrandPrix extends ExpansionSet {
private static final GrandPrix fINSTANCE = new GrandPrix();
public static GrandPrix getInstance() {
return fINSTANCE;
}
private GrandPrix() {
super("Grand Prix", "GPX", "mage.sets.grandprix", new GregorianCalendar(2011, 6, 17).getTime(), SetType.REPRINT);
this.hasBoosters = false;
this.hasBasicLands = false;
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets;
import java.util.GregorianCalendar;
import mage.constants.SetType;
import mage.cards.ExpansionSet;
/**
*
* @author fireshoes
*/
public class JudgePromo extends ExpansionSet {
private static final JudgePromo fINSTANCE = new JudgePromo();
public static JudgePromo getInstance() {
return fINSTANCE;
}
private JudgePromo() {
super("Judge Promo", "JR", "mage.sets.judgepromo", new GregorianCalendar(2011, 6, 17).getTime(), SetType.REPRINT);
this.hasBoosters = false;
}
}

View file

@ -0,0 +1,53 @@
/*
* 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.sets;
import java.util.GregorianCalendar;
import mage.constants.SetType;
import mage.cards.ExpansionSet;
/**
*
* @author fireshoes
*/
public class LaunchParty extends ExpansionSet {
private static final LaunchParty fINSTANCE = new LaunchParty();
public static LaunchParty getInstance() {
return fINSTANCE;
}
private LaunchParty() {
super("Launch Party", "MLP", "mage.sets.launchparty", new GregorianCalendar(2011, 6, 17).getTime(), SetType.REPRINT);
this.hasBoosters = false;
this.hasBasicLands = false;
}
}

View file

@ -0,0 +1,53 @@
/*
* 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.sets;
import java.util.GregorianCalendar;
import mage.constants.SetType;
import mage.cards.ExpansionSet;
/**
*
* @author fireshoes
*/
public class WorldMagicCupQualifier extends ExpansionSet {
private static final WorldMagicCupQualifier fINSTANCE = new WorldMagicCupQualifier();
public static WorldMagicCupQualifier getInstance() {
return fINSTANCE;
}
private WorldMagicCupQualifier() {
super("World Magic Cup Qualifier", "WMCQ", "mage.sets.worldmagiccupqualifier", new GregorianCalendar(2011, 6, 17).getTime(), SetType.REPRINT);
this.hasBoosters = false;
this.hasBasicLands = false;
}
}

View file

@ -40,6 +40,7 @@ import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.counters.CounterType;
import mage.filter.common.FilterArtifactCard;
import mage.filter.predicate.mageobject.AnotherCardPredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -57,9 +58,6 @@ public class ArsenalThresher extends CardImpl {
this.expansionSetCode = "ARB";
this.subtype.add("Construct");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
@ -100,7 +98,7 @@ class ArsenalThresherEffect extends OneShotEffect {
}
Permanent arsenalThresher = game.getPermanent(source.getSourceId());
FilterArtifactCard filter = new FilterArtifactCard();
filter.add(new AnotherPredicate());
filter.add(new AnotherCardPredicate());
if (you.chooseUse(Outcome.Benefit, "Do you want to reveal other artifacts in your hand?", game)) {
Cards cards = new CardsImpl();
if (you.getHand().count(filter, source.getSourceId(), source.getControllerId(), game) > 0) {

View file

@ -149,7 +149,7 @@ class AvenEffect2 extends ContinuousEffectImpl {
public boolean apply(Game game, Ability source) {
Permanent target = game.getPermanent(source.getFirstTarget());
if (target != null) {
if (!target.getAbilities(game).contains(FlyingAbility.getInstance())) {
if (!target.hasAbility(FlyingAbility.getInstance(), game)) {
target.addAbility(FlyingAbility.getInstance(), source.getSourceId(), game);
return true;
}

View file

@ -28,8 +28,10 @@
package mage.sets.apocalypse;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.continious.BoostTargetEffect;
@ -106,18 +108,20 @@ class DayEffect extends ContinuousEffectImpl {
if (this.affectedObjectsSet) {
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getFirstTarget(), game);
for (Permanent creature : creatures) {
objects.add(creature.getId());
affectedObjectList.add(new MageObjectReference(creature, game));
}
}
}
@Override
public boolean apply(Game game, Ability source) {
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(new FilterCreaturePermanent(), source.getFirstTarget(), game);
for (Permanent creature : creatures) {
if (!this.affectedObjectsSet || objects.contains(creature.getId())) {
creature.addPower(1);
creature.addToughness(1);
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
permanent.addPower(1);
permanent.addToughness(1);
} else {
it.remove();
}
}
return true;

View file

@ -1,205 +1,202 @@
/*
* 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.sets.arabiannights;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.EmptyEffect;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SkipUntapOptionalAbility;
import mage.abilities.condition.CompoundCondition;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceTappedCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.decorator.ConditionalContinousEffect;
import mage.abilities.effects.common.FlipSourceEffect;
import mage.abilities.effects.common.continious.GainControlTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.ObjectPlayer;
import mage.filter.predicate.ObjectPlayerPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class OldManOfTheSea extends CardImpl {
public OldManOfTheSea(UUID ownerId) {
super(ownerId, 24, "Old Man of the Sea", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
this.expansionSetCode = "ARN";
this.subtype.add("Djinn");
this.color.setBlue(true);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// You may choose not to untap Old Man of the Sea during your untap step.
this.addAbility(new SkipUntapOptionalAbility());
// {tap}: Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power.
FilterCreaturePermanent controllableCreatures = new FilterCreaturePermanent("creature with power less than or equal to Old Man of the Sea 's power");
controllableCreatures.add(new PowerLowerEqualSourcePredicate(this.getId()));
ConditionalContinousEffect effect = new ConditionalContinousEffect(
new OldManOfTheSeaGainControlTargetEffect(Duration.Custom, true), new CompoundCondition(SourceTappedCondition.getInstance(), new SourcePowerGreaterEqualTargetCondition()),
"Gain control of target creature with power less than or equal to {this}'s power for as long as {this} remains tapped and that creature's power remains less than or equal to {this}'s power");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(controllableCreatures));
this.addAbility(ability);
// internal ability to check condition
this.addAbility(new OldManOfTheSeaStateBasedTriggeredAbility());
}
public OldManOfTheSea(final OldManOfTheSea card) {
super(card);
}
@Override
public OldManOfTheSea copy() {
return new OldManOfTheSea(this);
}
}
class OldManOfTheSeaGainControlTargetEffect extends GainControlTargetEffect {
public OldManOfTheSeaGainControlTargetEffect(Duration duration, boolean fixedControl) {
super(duration, fixedControl);
}
public OldManOfTheSeaGainControlTargetEffect(final OldManOfTheSeaGainControlTargetEffect effect) {
super(effect);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
// save target id to be available for hidden state based triggered effect
game.getState().setValue("target" + source.getSourceId(), getTargetPointer().getFirst(game, source));
}
@Override
public OldManOfTheSeaGainControlTargetEffect copy() {
return new OldManOfTheSeaGainControlTargetEffect(this);
}
}
/*
used a state based triggered effect here (not going to stack, so running hidden) to compare power of the controlled
creature to Old Man of the seas power. It's not possible to do this as condition of continuous effect, because the
time the effect checks its condition, the layered effects that modify power are not applied yet.
result is save to a state value to be available for the condition of the continuous effect
*/
class OldManOfTheSeaStateBasedTriggeredAbility extends StateTriggeredAbility {
public OldManOfTheSeaStateBasedTriggeredAbility() {
super(Zone.BATTLEFIELD, new EmptyEffect(""));
this.setRuleVisible(false);
this.usesStack = false;
}
public OldManOfTheSeaStateBasedTriggeredAbility(final OldManOfTheSeaStateBasedTriggeredAbility ability) {
super(ability);
}
@Override
public OldManOfTheSeaStateBasedTriggeredAbility copy() {
return new OldManOfTheSeaStateBasedTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent sourcePermanent = game.getPermanent(getSourceId());
if (sourcePermanent != null && sourcePermanent.isTapped()) {
UUID controlledCreatureId = (UUID) game.getState().getValue("target" + getSourceId());
if (controlledCreatureId != null) {
Permanent controlledCreature = game.getPermanent(controlledCreatureId);
if (controlledCreature != null) {
if (controlledCreature.getPower().getValue() > sourcePermanent.getPower().getValue()) {
game.getState().setValue("powerCondition" + getSourceId(), Boolean.TRUE);
}
}
}
}
return false;
}
}
class SourcePowerGreaterEqualTargetCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
Object object = game.getState().getValue("powerCondition" + source.getSourceId());
if (object != null && (Boolean) object) {
// reset the values
game.getState().setValue("powerCondition" + source.getSourceId(), Boolean.FALSE);
game.getState().setValue("target" + source.getSourceId(), null);
// stop controlling target
return false;
}
return true;
}
}
class PowerLowerEqualSourcePredicate implements ObjectPlayerPredicate<ObjectPlayer<Permanent>> {
UUID sourceId;
public PowerLowerEqualSourcePredicate(UUID sourceId) {
this.sourceId = sourceId;
}
@Override
public boolean apply(ObjectPlayer<Permanent> input, Game game) {
Permanent sourcePermanent = game.getPermanent(sourceId);
Permanent permanent = input.getObject();
if (permanent != null && sourcePermanent != null) {
if (permanent.getPower().getValue() <= sourcePermanent.getPower().getValue()) {
return true;
}
}
return false;
}
@Override
public String toString() {
return "creature with power less than or equal to {source}'s power";
}
}
/*
* 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.sets.arabiannights;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.StateTriggeredAbility;
import mage.abilities.common.EmptyEffect;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SkipUntapOptionalAbility;
import mage.abilities.condition.CompoundCondition;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceTappedCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.decorator.ConditionalContinousEffect;
import mage.abilities.effects.common.continious.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.ObjectPlayer;
import mage.filter.predicate.ObjectPlayerPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class OldManOfTheSea extends CardImpl {
public OldManOfTheSea(UUID ownerId) {
super(ownerId, 24, "Old Man of the Sea", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}{U}");
this.expansionSetCode = "ARN";
this.subtype.add("Djinn");
this.color.setBlue(true);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// You may choose not to untap Old Man of the Sea during your untap step.
this.addAbility(new SkipUntapOptionalAbility());
// {tap}: Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power.
FilterCreaturePermanent controllableCreatures = new FilterCreaturePermanent("creature with power less than or equal to Old Man of the Sea's power");
controllableCreatures.add(new PowerLowerEqualSourcePredicate(this.getId()));
ConditionalContinousEffect effect = new ConditionalContinousEffect(
new OldManOfTheSeaGainControlTargetEffect(Duration.Custom, true), new CompoundCondition(SourceTappedCondition.getInstance(), new SourcePowerGreaterEqualTargetCondition()),
"Gain control of target creature with power less than or equal to {this}'s power for as long as {this} remains tapped and that creature's power remains less than or equal to {this}'s power");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(controllableCreatures));
this.addAbility(ability);
// internal ability to check condition
this.addAbility(new OldManOfTheSeaStateBasedTriggeredAbility());
}
public OldManOfTheSea(final OldManOfTheSea card) {
super(card);
}
@Override
public OldManOfTheSea copy() {
return new OldManOfTheSea(this);
}
}
class OldManOfTheSeaGainControlTargetEffect extends GainControlTargetEffect {
public OldManOfTheSeaGainControlTargetEffect(Duration duration, boolean fixedControl) {
super(duration, fixedControl);
}
public OldManOfTheSeaGainControlTargetEffect(final OldManOfTheSeaGainControlTargetEffect effect) {
super(effect);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
// save target id to be available for hidden state based triggered effect
game.getState().setValue("target" + source.getSourceId(), getTargetPointer().getFirst(game, source));
}
@Override
public OldManOfTheSeaGainControlTargetEffect copy() {
return new OldManOfTheSeaGainControlTargetEffect(this);
}
}
/*
used a state based triggered effect here (not going to stack, so running hidden) to compare power of the controlled
creature to Old Man of the seas power. It's not possible to do this as condition of continuous effect, because the
time the effect checks its condition, the layered effects that modify power are not applied yet.
result is save to a state value to be available for the condition of the continuous effect
*/
class OldManOfTheSeaStateBasedTriggeredAbility extends StateTriggeredAbility {
public OldManOfTheSeaStateBasedTriggeredAbility() {
super(Zone.BATTLEFIELD, new EmptyEffect(""));
this.setRuleVisible(false);
this.usesStack = false;
}
public OldManOfTheSeaStateBasedTriggeredAbility(final OldManOfTheSeaStateBasedTriggeredAbility ability) {
super(ability);
}
@Override
public OldManOfTheSeaStateBasedTriggeredAbility copy() {
return new OldManOfTheSeaStateBasedTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent sourcePermanent = game.getPermanent(getSourceId());
if (sourcePermanent != null && sourcePermanent.isTapped()) {
UUID controlledCreatureId = (UUID) game.getState().getValue("target" + getSourceId());
if (controlledCreatureId != null) {
Permanent controlledCreature = game.getPermanent(controlledCreatureId);
if (controlledCreature != null) {
if (controlledCreature.getPower().getValue() > sourcePermanent.getPower().getValue()) {
game.getState().setValue("powerCondition" + getSourceId(), Boolean.TRUE);
}
}
}
}
return false;
}
}
class SourcePowerGreaterEqualTargetCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
Object object = game.getState().getValue("powerCondition" + source.getSourceId());
if (object != null && (Boolean) object) {
// reset the values
game.getState().setValue("powerCondition" + source.getSourceId(), Boolean.FALSE);
game.getState().setValue("target" + source.getSourceId(), null);
// stop controlling target
return false;
}
return true;
}
}
class PowerLowerEqualSourcePredicate implements ObjectPlayerPredicate<ObjectPlayer<Permanent>> {
UUID sourceId;
public PowerLowerEqualSourcePredicate(UUID sourceId) {
this.sourceId = sourceId;
}
@Override
public boolean apply(ObjectPlayer<Permanent> input, Game game) {
Permanent sourcePermanent = game.getPermanent(sourceId);
Permanent permanent = input.getObject();
if (permanent != null && sourcePermanent != null) {
if (permanent.getPower().getValue() <= sourcePermanent.getPower().getValue()) {
return true;
}
}
return false;
}
@Override
public String toString() {
return "creature with power less than or equal to {source}'s power";
}
}

View file

@ -89,7 +89,7 @@ class BowerPassageEffect extends RestrictionEffect {
@Override
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
if (attacker != null && attacker.getControllerId().equals(source.getControllerId()) && blocker.getAbilities(game).contains(FlyingAbility.getInstance())) {
if (attacker != null && attacker.getControllerId().equals(source.getControllerId()) && blocker.hasAbility(FlyingAbility.getInstance(), game)) {
return false;
}
return true;

View file

@ -29,7 +29,7 @@ package mage.sets.avacynrestored;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
@ -54,7 +54,7 @@ public class DruidsRepository extends CardImpl {
this.color.setGreen(true);
// Whenever a creature you control attacks, put a charge counter on Druids' Repository.
this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new AddCountersSourceEffect(CounterType.CHARGE.createInstance())));
this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new AddCountersSourceEffect(CounterType.CHARGE.createInstance())));
// Remove a charge counter from Druids' Repository: Add one mana of any color to your mana pool.
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect(), new RemoveCountersSourceCost(CounterType.CHARGE.createInstance()));

View file

@ -88,7 +88,7 @@ class FloweringLumberknotEffect extends RestrictionEffect {
return true; // not paired => can't attack or block
}
Permanent paired = game.getPermanent(permanent.getPairedCard());
if (paired != null && paired.getAbilities(game).contains(SoulbondAbility.getInstance())) {
if (paired != null && paired.hasAbility(SoulbondAbility.getInstance(), game)) {
return false; // paired => can attack or block
}
// can't attack or block otherwise

View file

@ -76,7 +76,7 @@ class VexingDevilEffect extends OneShotEffect {
public VexingDevilEffect() {
super(Outcome.Neutral);
staticText = "any opponent may have it deal 4 damage to him or her. If a player does, sacrifice Vexing Devil";
staticText = "any opponent may have it deal 4 damage to him or her. If a player does, sacrifice {this}";
}
VexingDevilEffect(final VexingDevilEffect effect) {
@ -85,28 +85,19 @@ class VexingDevilEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
StringBuilder sb = new StringBuilder();
sb.append("Make ").append(permanent.getName()).append(" deal 4 damage to you?");
Set<UUID> opponents = game.getOpponents(source.getControllerId());
for (UUID opponentUuid : opponents) {
if (controller != null && permanent != null) {
for (UUID opponentUuid : game.getOpponents(source.getControllerId())) {
Player opponent = game.getPlayer(opponentUuid);
if (opponent != null && opponent.chooseUse(Outcome.LoseLife, sb.toString(), game)) {
if (opponent != null && opponent.chooseUse(Outcome.LoseLife, "Make " + permanent.getName() + " deal 4 damage to you?", game)) {
game.informPlayers(opponent.getName() + " has chosen to receive 4 damage from " + permanent.getName());
int dealt = opponent.damage(4, permanent.getId(), game, false, true);
if (dealt == 4) {
game.informPlayers(opponent.getName() + " was dealt 4 damage so " + permanent.getName() + " will be sacrificed.");
permanent.sacrifice(source.getSourceId(), game);
return true;
} else {
game.informPlayers("4 damage wasn't dealt so " + permanent.getName() + " won't be sacrificed.");
}
opponent.damage(4, permanent.getId(), game, false, true);
permanent.sacrifice(source.getSourceId(), game);
return true;
}
}
game.informPlayers("4 damage wasn't dealt so " + permanent.getName() + " won't be sacrificed.");
return true;
}
return false;

View file

@ -28,6 +28,7 @@
package mage.sets.bornofthegods;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.common.continious.BoostAllEffect;
import mage.cards.CardImpl;
@ -79,17 +80,17 @@ class BileBlightEffect extends BoostAllEffect {
@Override
public void init(Ability source, Game game) {
super.init(source, game);
affectedObjectList.clear();
if (this.affectedObjectsSet) {
this.objects.clear();
Permanent target = game.getPermanent(getTargetPointer().getFirst(game, source));
if (target != null) {
if (target.getName().isEmpty()) { // face down creature
this.objects.add(target.getId());
affectedObjectList.add(new MageObjectReference(target, game));
} else {
String name = target.getLogName();
for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
if (perm.getLogName().equals(name)) {
this.objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm, game));
}
}
}

View file

@ -43,6 +43,7 @@ import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.players.Player;
import mage.target.common.TargetControlledPermanent;
@ -116,9 +117,15 @@ class FloodtideSerpentReplacementEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.DECLARE_ATTACKER;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getType() == GameEvent.EventType.DECLARE_ATTACKER && event.getSourceId().equals(source.getSourceId());
return event.getSourceId().equals(source.getSourceId());
}
@Override

View file

@ -33,7 +33,6 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;

View file

@ -30,17 +30,18 @@
package mage.sets.championsofkamigawa;
import java.util.UUID;
import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.common.EmptyEffect;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continious.BoostAllEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SupertypePredicate;
@ -53,7 +54,6 @@ import mage.util.CardUtil;
*
* @author LevelX
*/
public class KondasBanner extends CardImpl {
private static final FilterControlledCreaturePermanent legendaryFilter = new FilterControlledCreaturePermanent("Legendary creatures");
@ -80,8 +80,8 @@ public class KondasBanner extends CardImpl {
// Equip {2}
this.addAbility(new EquipAbility(
Outcome.AddAbility,
new GenericManaCost(2),
new TargetControlledCreaturePermanent(1,1, legendaryFilter, false)));
new GenericManaCost(2),
new TargetControlledCreaturePermanent(1, 1, legendaryFilter, false)));
}
@ -92,15 +92,15 @@ public class KondasBanner extends CardImpl {
@Override
public KondasBanner copy() {
return new KondasBanner(this);
}
}
}
class KondasBannerTypeBoostEffect extends BoostAllEffect {
class KondasBannerTypeBoostEffect extends BoostAllEffect {
private static final String effectText = "Creatures that share a creature type with equipped creature get +1/+1";
KondasBannerTypeBoostEffect() {
super(1,1, Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false);
super(1, 1, Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false);
staticText = effectText;
}
@ -109,27 +109,24 @@ class KondasBannerTypeBoostEffect extends BoostAllEffect {
}
@Override
public boolean apply(Game game, Ability source) {
// Check if the equipment is attached
Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null)
{
Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo());
if (equipedCreature != null) {
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (CardUtil.shareSubtypes(perm, equipedCreature)) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
perm.addPower(power.calculate(game, source, this));
perm.addToughness(toughness.calculate(game, source, this));
}
public boolean apply(Game game, Ability source) {
// Check if the equipment is attached
Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) {
Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo());
if (equipedCreature != null) {
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (CardUtil.shareSubtypes(perm, equipedCreature)) {
perm.addPower(power.calculate(game, source, this));
perm.addToughness(toughness.calculate(game, source, this));
}
}
return true;
}
return true;
}
return false;
}
return false;
}
@Override
public KondasBannerTypeBoostEffect copy() {
@ -138,13 +135,12 @@ class KondasBannerTypeBoostEffect extends BoostAllEffect {
}
class KondasBannerColorBoostEffect extends BoostAllEffect {
class KondasBannerColorBoostEffect extends BoostAllEffect {
private static final String effectText = "Creatures that share a color with equipped creature get +1/+1.";
KondasBannerColorBoostEffect() {
super(1,1, Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false);
super(1, 1, Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false);
staticText = effectText;
}
@ -153,25 +149,22 @@ class KondasBannerColorBoostEffect extends BoostAllEffect {
}
@Override
public boolean apply(Game game, Ability source) {
// Check if the equipment is attached
Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null)
{
Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo());
for (Permanent perm: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (equipedCreature.getColor().shares(perm.getColor())) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
public boolean apply(Game game, Ability source) {
// Check if the equipment is attached
Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) {
Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo());
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (equipedCreature.getColor().shares(perm.getColor())) {
perm.addPower(power.calculate(game, source, this));
perm.addToughness(toughness.calculate(game, source, this));
}
}
}
return true;
}
}
return false;
return true;
}
return false;
}
@Override
public KondasBannerColorBoostEffect copy() {

View file

@ -95,7 +95,7 @@ class StudentOfElementsHasFlyingAbility extends StateTriggeredAbility {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(getSourceId());
if(permanent != null && permanent.getAbilities().contains(FlyingAbility.getInstance())){
if(permanent != null && permanent.hasAbility(FlyingAbility.getInstance(), game)){
return true;
}
return false;

View file

@ -28,6 +28,7 @@
package mage.sets.championsofkamigawa;
import java.util.Iterator;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -41,6 +42,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
import mage.MageObjectReference;
/**
* @author Loki
@ -101,7 +103,7 @@ class TakenoSamuraiGeneralEffect extends ContinuousEffectImpl {
if (!perm.getId().equals(source.getSourceId())) {
for (Ability ability : perm.getAbilities(game)) {
if (ability instanceof BushidoAbility) {
objects.add(perm.getId());
affectedObjectList.add(new MageObjectReference(perm, game));
}
}
}
@ -111,8 +113,23 @@ class TakenoSamuraiGeneralEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!this.affectedObjectsSet || objects.contains(perm.getId())) {
if (this.affectedObjectsSet) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { // filter may not be used again, because object can have changed filter relevant attributes but still geets boost
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
for (Ability ability : permanent.getAbilities()) {
if (ability instanceof BushidoAbility) {
int value = ((BushidoAbility) ability).getValue(source, game, this);
permanent.addPower(value);
permanent.addToughness(value);
}
}
} else {
it.remove(); // no longer on the battlefield, remove reference to object
}
}
} else {
for (Permanent perm: game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!perm.getId().equals(source.getSourceId())) {
for (Ability ability : perm.getAbilities(game)) {
if (ability instanceof BushidoAbility) {

View file

@ -119,7 +119,7 @@ class ChorusOfTheConclaveReplacementEffect extends ReplacementEffectImpl {
if (xCost > 0) {
Ability ability = new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(xCost)));
ability.setRuleVisible(false);
game.getState().addOtherAbility(card.getId(), ability);
game.getState().addOtherAbility(card, ability);
//card.addAbility(ability);
ability.setControllerId(source.getControllerId());
ability.setSourceId(card.getId());

View file

@ -0,0 +1,52 @@
/*
* 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.sets.commander;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class EvincarsJustice extends mage.sets.tempest.EvincarsJustice {
public EvincarsJustice(UUID ownerId) {
super(ownerId);
this.cardNumber = 80;
this.expansionSetCode = "CMD";
}
public EvincarsJustice(final EvincarsJustice card) {
super(card);
}
@Override
public EvincarsJustice copy() {
return new EvincarsJustice(this);
}
}

View file

@ -142,13 +142,15 @@ class StrangleholdSkipExtraTurnsEffect extends ReplacementEffectImpl {
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType().equals(GameEvent.EventType.EXTRA_TURN);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (EventType.EXTRA_TURN.equals(event.getType())) {
Player controller = game.getPlayer(source.getControllerId());
return controller != null && controller.hasOpponent(event.getPlayerId(), game);
}
return false;
Player controller = game.getPlayer(source.getControllerId());
return controller != null && controller.hasOpponent(event.getPlayerId(), game);
}
}

View file

@ -27,10 +27,10 @@
*/
package mage.sets.commander2013;
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl;
@ -42,7 +42,6 @@ import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.SubLayer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
@ -112,7 +111,7 @@ class BroodingSaurianControlEffect extends ContinuousEffectImpl {
FilterPermanent playerFilter = filter.copy();
playerFilter.add(new OwnerIdPredicate(playerId));
for (Permanent permanent :game.getBattlefield().getActivePermanents(playerFilter, playerId, game)) {
objects.add(permanent.getId());
affectedObjectList.add(new MageObjectReference(permanent, game));
}
}
}
@ -120,19 +119,17 @@ class BroodingSaurianControlEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Set<UUID> toRemove = new HashSet<UUID>();
for (UUID creatureId :objects) {
Permanent creature = game.getPermanent(creatureId);
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent creature = it.next().getPermanent(game);
if (creature != null) {
if (!creature.getControllerId().equals(creature.getOwnerId())) {
creature.changeControllerId(creature.getOwnerId(), game);
}
} else {
toRemove.add(creatureId);
it.remove();
}
}
objects.removeAll(toRemove);
if (objects.isEmpty()) {
if (affectedObjectList.isEmpty()) {
this.discard();
}
return true;

View file

@ -28,8 +28,10 @@
package mage.sets.commander2013;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
@ -105,7 +107,7 @@ class HomewardPathControlEffect extends ContinuousEffectImpl {
FilterPermanent playerFilter = filter.copy();
playerFilter.add(new OwnerIdPredicate(playerId));
for (Permanent permanent :game.getBattlefield().getActivePermanents(playerFilter, playerId, game)) {
objects.add(permanent.getId());
affectedObjectList.add(new MageObjectReference(permanent, game));
}
}
}
@ -113,19 +115,17 @@ class HomewardPathControlEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Game game, Ability source) {
Set<UUID> toRemove = new HashSet<UUID>();
for (UUID creatureId :objects) {
Permanent creature = game.getPermanent(creatureId);
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent creature = it.next().getPermanent(game);
if (creature != null) {
if (!creature.getControllerId().equals(creature.getOwnerId())) {
creature.changeControllerId(creature.getOwnerId(), game);
}
} else {
toRemove.add(creatureId);
it.remove();
}
}
objects.removeAll(toRemove);
if (objects.isEmpty()) {
if (affectedObjectList.isEmpty()) {
this.discard();
}
return true;

View file

@ -37,8 +37,6 @@ import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@ -88,13 +86,14 @@ class PrimalVigorTokenEffect extends ReplacementEffectImpl {
return new PrimalVigorTokenEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CREATE_TOKEN;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
switch (event.getType()) {
case CREATE_TOKEN:
return true;
}
return false;
return true;
}
@Override
@ -112,8 +111,6 @@ class PrimalVigorTokenEffect extends ReplacementEffectImpl {
class PrimalVigorCounterEffect extends ReplacementEffectImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
PrimalVigorCounterEffect() {
super(Duration.WhileOnBattlefield, Outcome.BoostCreature, false);
staticText = "If one or more +1/+1 counters would be placed on a creature, twice that many +1/+1 counters are placed on that creature instead";
@ -129,14 +126,17 @@ class PrimalVigorCounterEffect extends ReplacementEffectImpl {
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ADD_COUNTERS;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ADD_COUNTERS) {
Permanent target = game.getPermanent(event.getTargetId());
if (target != null && filter.match(target, game)
&& event.getData() != null && event.getData().equals("+1/+1")) {
return true;
}
Permanent target = game.getPermanent(event.getTargetId());
if (target != null && target.getCardType().contains(CardType.CREATURE)
&& event.getData() != null && event.getData().equals("+1/+1")) {
return true;
}
return false;
}

View file

@ -136,6 +136,18 @@ class BitterFeudEffect extends ReplacementEffectImpl {
return new BitterFeudEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
switch(event.getType()) {
case DAMAGE_CREATURE:
case DAMAGE_PLAYER:
case DAMAGE_PLANESWALKER:
return true;
default:
return false;
}
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
player1 = (Player) game.getState().getValue(source.getSourceId() + "_player1");
@ -147,7 +159,7 @@ class BitterFeudEffect extends ReplacementEffectImpl {
targetPlayerId = event.getTargetId();
break;
case DAMAGE_CREATURE:
case DAMAGED_PLANESWALKER:
case DAMAGE_PLANESWALKER:
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
targetPlayerId = permanent.getControllerId();

View file

@ -126,11 +126,16 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl {
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& ((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
Card card = game.getCard(event.getTargetId());
if (card.getCardType().contains(CardType.CREATURE)) { // TODO: Bestow Card cast as Enchantment probably not handled correctly
CreatureCastWatcher watcher = (CreatureCastWatcher) game.getState().getWatchers().get("CreatureWasCast");

View file

@ -48,7 +48,6 @@ import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterPlayer;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.other.OwnerPredicate;
import mage.filter.predicate.other.PlayerPredicate;
import mage.game.Game;
import mage.players.Player;
@ -64,7 +63,7 @@ public class CrownOfDoom extends CardImpl {
private static final FilterPlayer filter = new FilterPlayer("player other than Crown of Doom's owner");
static {
filter.add(new OwnerPredicate(TargetController.NOT_YOU));
filter.add(new PlayerPredicate(TargetController.NOT_YOU));
}
public CrownOfDoom(UUID ownerId) {

View file

@ -76,7 +76,7 @@ public class FreyaliseLlanowarsFury extends CardImpl {
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false));
// +2: Put a 1/1 green Elf Druid creature token onto the battlefield with "{tap}: Add {G} to your mana pool."
// +2: Put a 1/1 green Elf Druid creature token onto the battlefield with "{T}: Add {G} to your mana pool."
this.addAbility(new LoyaltyAbility(new CreateTokenEffect(new FreyaliseLlanowarsFuryToken()), 2));
// -2: Destroy target artifact or enchantment.
LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DestroyTargetEffect(), -2);
@ -103,7 +103,7 @@ public class FreyaliseLlanowarsFury extends CardImpl {
class FreyaliseLlanowarsFuryToken extends Token {
FreyaliseLlanowarsFuryToken() {
super("Elf Druid", "1/1 green Elf Druid creature token onto the battlefield with \"{t}: Add {G} to your mana pool.\"");
super("Elf Druid", "1/1 green Elf Druid creature token with \"{t}: Add {G} to your mana pool.\"");
this.setOriginalExpansionSetCode("C14");
this.cardType.add(CardType.CREATURE);
this.color = ObjectColor.GREEN;

View file

@ -0,0 +1,52 @@
/*
* 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.sets.conspiracy;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class OrcishCannonade extends mage.sets.speedvscunning.OrcishCannonade {
public OrcishCannonade(UUID ownerId) {
super(ownerId);
this.cardNumber = 148;
this.expansionSetCode = "CNS";
}
public OrcishCannonade(final OrcishCannonade card) {
super(card);
}
@Override
public OrcishCannonade copy() {
return new OrcishCannonade(this);
}
}

View file

@ -0,0 +1,107 @@
/*
* 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.sets.darksteel;
import java.util.UUID;
import mage.abilities.Ability;
import mage.constants.Outcome;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
/**
*
* @author fireshoes
*/
public class EchoingRuin extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("artifact");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
}
public EchoingRuin(UUID ownerId) {
super(ownerId, 59, "Echoing Ruin", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{1}{R}");
this.expansionSetCode = "DST";
// Destroy target artifact and all other artifacts with the same name as that artifact.
this.getSpellAbility().addTarget(new TargetPermanent(filter));
this.getSpellAbility().addEffect(new EchoingRuinEffect());
}
public EchoingRuin(final EchoingRuin card) {
super(card);
}
@Override
public EchoingRuin copy() {
return new EchoingRuin(this);
}
}
class EchoingRuinEffect extends OneShotEffect {
EchoingRuinEffect() {
super(Outcome.DestroyPermanent);
staticText = "Destroy target artifact and all other artifacts with the same name as that artifact";
}
EchoingRuinEffect(final EchoingRuinEffect effect) {
super(effect);
}
@Override
public EchoingRuinEffect copy() {
return new EchoingRuinEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller != null && permanent != null) {
permanent.destroy(source.getSourceId(), game, false);
if (!permanent.getName().isEmpty()) { // in case of face down artifact creature
for (Permanent perm : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
if (!perm.getId().equals(permanent.getId()) && perm.getName().equals(permanent.getName()) && perm.getCardType().contains(CardType.ARTIFACT)) {
perm.destroy(source.getSourceId(), game, false);
}
}
}
return true;
}
return false;
}
}

View file

@ -28,6 +28,7 @@
package mage.sets.dissension;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.condition.common.HellbentCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
@ -41,6 +42,7 @@ import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
@ -99,8 +101,8 @@ class InfernalTutorEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
if (controller != null) {
MageObject sourceObject = game.getObject(source.getSourceId());
if (controller != null && sourceObject != null) {
if (controller.getHand().size() > 0) {
Card cardToReveal = null;
if (controller.getHand().size() > 1) {
@ -112,11 +114,16 @@ class InfernalTutorEffect extends OneShotEffect {
} else {
cardToReveal = controller.getHand().getRandom(game);
}
FilterCard filterCard;
if (cardToReveal != null) {
controller.revealCards(sourceCard.getName(), new CardsImpl(cardToReveal), game);
FilterCard filterCard = new FilterCard(new StringBuilder("card named ").append(cardToReveal.getName()).toString());
return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true, true).apply(game, source);
}
controller.revealCards("from hand :" + sourceObject.getName(), new CardsImpl(cardToReveal), game);
filterCard = new FilterCard("card named " + cardToReveal.getName());
filterCard.add(new NamePredicate(cardToReveal.getName()));
} else {
filterCard = new FilterCard();
}
return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true, true).apply(game, source);
}
return true;
}

View file

@ -64,7 +64,7 @@ public class RiseFall extends SplitCard {
// Rise
// Return target creature card from a graveyard and target creature on the battlefield to their owners' hands.
getLeftHalfCard().getSpellAbility().addEffect(new RiseEffect());
getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard()));
getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card from a graveyard")));
getLeftHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent());
getLeftHalfCard().getColor().setBlue(true);
getLeftHalfCard().getColor().setBlack(true);
@ -151,7 +151,7 @@ class FallEffect extends OneShotEffect {
if (targetPlayer.getHand().size() > 1) {
do {
card = targetPlayer.getHand().getRandom(game);
} while (!cards.contains(card.getId()));
} while (cards.contains(card.getId()));
cards.add(card);
}
targetPlayer.revealCards(sourceObject.getLogName(), cards, game);

View file

@ -30,7 +30,7 @@ package mage.sets.dragonsmaze;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.counters.CounterType;
@ -49,7 +49,7 @@ public class GleamOfBattle extends CardImpl {
this.color.setWhite(true);
// Whenever a creature you control attacks, put a +1/+1 counter on it.
this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false, true));
this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance()), false, true));
}
public GleamOfBattle(final GleamOfBattle card) {

View file

@ -115,7 +115,7 @@ class VarolzTheScarStripedEffect extends ContinuousEffectImpl {
ScavengeAbility ability = new ScavengeAbility(new ManaCostsImpl(card.getManaCost().getText()));
ability.setSourceId(cardId);
ability.setControllerId(card.getOwnerId());
game.getState().addOtherAbility(cardId, ability);
game.getState().addOtherAbility(card, ability);
}
}
return true;

View file

@ -67,7 +67,11 @@ public class Pentavus extends CardImpl {
this.subtype.add("Construct");
this.power = new MageInt(0);
this.toughness = new MageInt(0);
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(5))));
// Pentavus enters the battlefield with five +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(5)),
"with five +1/+1 counters on it"));
Ability firstAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new PentaviteToken(), 1), new GenericManaCost(1));
firstAbility.addCost(new RemoveCountersSourceCost(CounterType.P1P1.createInstance(1)));
this.addAbility(firstAbility);

View file

@ -55,8 +55,6 @@ public class GilderBairn extends CardImpl {
this.expansionSetCode = "EVE";
this.subtype.add("Ouphe");
this.color.setBlue(true);
this.color.setGreen(true);
this.power = new MageInt(1);
this.toughness = new MageInt(3);

View file

@ -70,7 +70,7 @@ public class WickerboughElder extends CardImpl {
this.toughness = new MageInt(4);
// Wickerbough Elder enters the battlefield with a -1/-1 counter on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(1)), false));
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.M1M1.createInstance(1))));
// {G}, Remove a -1/-1 counter from Wickerbough Elder: Destroy target artifact or enchantment.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ColoredManaCost(ColoredManaSymbol.G));
ability.addCost(new RemoveCountersSourceCost(CounterType.M1M1.createInstance(1)));

View file

@ -0,0 +1,81 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalContinousEffect;
import mage.abilities.effects.common.continious.GainAbilitySourceEffect;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
/**
*
* @author LevelX2
*/
public class AbzanKinGuard extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("as long as you control a white or black permanent");
static {
filter.add(Predicates.or(new ColorPredicate(ObjectColor.WHITE), new ColorPredicate(ObjectColor.BLACK)));
}
public AbzanKinGuard(UUID ownerId) {
super(ownerId, 120, "Abzan Kin-Guard", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{G}");
this.expansionSetCode = "FRF";
this.subtype.add("Human");
this.subtype.add("Warrior");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Abzan Kin-Guard has lifelink as long as you control a white or black permanent.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new ConditionalContinousEffect(new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield),
new PermanentsOnTheBattlefieldCondition(filter), "{this} has lifelink as long as you control a white or black permanent")));
}
public AbzanKinGuard(final AbzanKinGuard card) {
super(card);
}
@Override
public AbzanKinGuard copy() {
return new AbzanKinGuard(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class BloodfellCaves extends mage.sets.khansoftarkir.BloodfellCaves {
public BloodfellCaves(UUID ownerId) {
super(ownerId);
this.cardNumber = 165;
this.expansionSetCode = "FRF";
}
public BloodfellCaves(final BloodfellCaves card) {
super(card);
}
@Override
public BloodfellCaves copy() {
return new BloodfellCaves(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class BlossomingSands extends mage.sets.khansoftarkir.BlossomingSands {
public BlossomingSands(UUID ownerId) {
super(ownerId);
this.cardNumber = 166;
this.expansionSetCode = "FRF";
}
public BlossomingSands(final BlossomingSands card) {
super(card);
}
@Override
public BlossomingSands copy() {
return new BlossomingSands(this);
}
}

View file

@ -0,0 +1,103 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.TapTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class CitadelSiege extends CardImpl {
private final static String ruleTrigger1 = "&bull Khans &mdash; At the beginning of combat on your turn, put two +1/+1 counters on target creature you control.";
private final static String ruleTrigger2 = "&bull Dragons &mdash; At the beginning of combat on each opponent's turn, tap target creature that player controls.";
public CitadelSiege(UUID ownerId) {
super(ownerId, 8, "Citadel Siege", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
this.expansionSetCode = "FRF";
// As Citadel Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true,
"As {this} enters the battlefield, choose Khans or Dragons.",""));
// * Khans - At the beginning of combat on your turn, put two +1/+1 counters on target creature you control.
Ability ability = new ConditionalTriggeredAbility(
new BeginningOfCombatTriggeredAbility(new AddCountersTargetEffect(CounterType.P1P1.createInstance(2)), TargetController.YOU, false),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1);
ability.addTarget(new TargetControlledCreaturePermanent());
this.addAbility(ability);
// * Dragons - At the beginning of combat on each opponent's turn, tap target creature that player controls.
ability = new ConditionalTriggeredAbility(
new BeginningOfCombatTriggeredAbility(new TapTargetEffect(), TargetController.OPPONENT, false),
new ModeChoiceSourceCondition("Dragons"),
ruleTrigger2);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (this.hasAbility(ability, game) && ability.getRule().startsWith("&bull Dragons")) {
FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that player controls");
filter.add(new ControllerIdPredicate(game.getCombat().getAttackerId()));
ability.getTargets().clear();
ability.addTarget(new TargetCreaturePermanent(filter));
}
}
public CitadelSiege(final CitadelSiege card) {
super(card);
}
@Override
public CitadelSiege copy() {
return new CitadelSiege(this);
}
}

View file

@ -0,0 +1,126 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class DaghatarTheAdamant extends CardImpl {
public DaghatarTheAdamant(UUID ownerId) {
super(ownerId, 9, "Daghatar the Adamant", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.expansionSetCode = "FRF";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Warrior");
this.power = new MageInt(0);
this.toughness = new MageInt(0);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Daghatar the Adamant enters the battlefield with four +1/+1 counters on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance(4)),
"with four +1/+1 counters on it"));
// {1}{B/G}{B/G}: Move a +1/+1 counter from target creature onto a second target creature.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MoveCounterFromTargetToTargetEffect(),new ManaCostsImpl("{1}{B/G}{B/G}"));
ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature the +1/+1 counter is moved from")));
ability.addTarget(new TargetCreaturePermanent(new FilterCreaturePermanent("creature the +1/+1 counter is moved to")));
this.addAbility(ability);
}
public DaghatarTheAdamant(final DaghatarTheAdamant card) {
super(card);
}
@Override
public DaghatarTheAdamant copy() {
return new DaghatarTheAdamant(this);
}
}
class MoveCounterFromTargetToTargetEffect extends OneShotEffect {
public MoveCounterFromTargetToTargetEffect() {
super(Outcome.Detriment);
this.staticText = "Move a +1/+1 counter from target creature onto a second target creature";
}
public MoveCounterFromTargetToTargetEffect(final MoveCounterFromTargetToTargetEffect effect) {
super(effect);
}
@Override
public MoveCounterFromTargetToTargetEffect copy() {
return new MoveCounterFromTargetToTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source.getSourceId());
if (sourceObject != null && controller != null) {
Permanent fromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (fromPermanent != null && fromPermanent.getCounters().getCount(CounterType.P1P1) > 0) {
Permanent toPermanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (toPermanent != null) {
fromPermanent.removeCounters(CounterType.P1P1.createInstance(), game);
toPermanent.addCounters(CounterType.P1P1.createInstance(), game);
game.informPlayers(sourceObject.getLogName() + ": Moved a +1/+1 counter from " + fromPermanent.getLogName() +" to " + toPermanent.getLogName());
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class DismalBackwater extends mage.sets.khansoftarkir.DismalBackwater {
public DismalBackwater(UUID ownerId) {
super(ownerId);
this.cardNumber = 168;
this.expansionSetCode = "FRF";
}
public DismalBackwater(final DismalBackwater card) {
super(card);
}
@Override
public DismalBackwater copy() {
return new DismalBackwater(this);
}
}

View file

@ -0,0 +1,76 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.keyword.BolsterEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.TappedPredicate;
/**
*
* @author LevelX2
*/
public class DragonscaleGeneral extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("tapped creatures you control");
static {
filter.add(new TappedPredicate());
filter.add(new ControllerPredicate(TargetController.YOU));
}
public DragonscaleGeneral(UUID ownerId) {
super(ownerId, 11, "Dragonscale General", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{W}");
this.expansionSetCode = "FRF";
this.subtype.add("Human");
this.subtype.add("Warrior");
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// At the beginning of your end step, bolster X, where X is the number of tapped creatures you control.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new BolsterEffect(new PermanentsOnBattlefieldCount(filter)), TargetController.YOU, false));
}
public DragonscaleGeneral(final DragonscaleGeneral card) {
super(card);
}
@Override
public DragonscaleGeneral copy() {
return new DragonscaleGeneral(this);
}
}

View file

@ -0,0 +1,69 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
import mage.abilities.effects.keyword.BolsterEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.filter.common.FilterControlledCreaturePermanent;
/**
*
* @author LevelX2
*/
public class DromokaTheEternal extends CardImpl {
public DromokaTheEternal(UUID ownerId) {
super(ownerId, 151, "Dromoka, the Eternal", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{G}{W}");
this.expansionSetCode = "FRF";
this.supertype.add("Legendary");
this.subtype.add("Dragon");
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever a Dragon you control attacks, bolster 2.
this.addAbility(new AttacksCreatureYouControlTriggeredAbility(
new BolsterEffect(2), false, new FilterControlledCreaturePermanent("Dragon", "Dragon you control")));
}
public DromokaTheEternal(final DromokaTheEternal card) {
super(card);
}
@Override
public DromokaTheEternal copy() {
return new DromokaTheEternal(this);
}
}

View file

@ -0,0 +1,58 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.abilities.effects.keyword.ManifestEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LevelX2
*/
public class EtherealAmbush extends CardImpl {
public EtherealAmbush(UUID ownerId) {
super(ownerId, 152, "Ethereal Ambush", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{3}{G}{U}");
this.expansionSetCode = "FRF";
// Manifest the top two cards of your library.
this.getSpellAbility().addEffect(new ManifestEffect(2));
}
public EtherealAmbush(final EtherealAmbush card) {
super(card);
}
@Override
public EtherealAmbush copy() {
return new EtherealAmbush(this);
}
}

View file

@ -0,0 +1,126 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.keyword.DashAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.filter.predicate.permanent.AttackingPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.EmptyToken;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
*
* @author LevelX2
*/
public class FlamerushRider extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("another target attacking creature");
static {
filter.add(new AnotherPredicate());
filter.add(new AttackingPredicate());
}
public FlamerushRider(UUID ownerId) {
super(ownerId, 99, "Flamerush Rider", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{R}");
this.expansionSetCode = "FRF";
this.subtype.add("Human");
this.subtype.add("Warrior");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever Flamerush Rider attacks, put a token onto the battlefield tapped and attacking that's a copy of another target attacking creature. Exile the token at end of combat.
Ability ability = new AttacksTriggeredAbility(new FlamerushRiderEffect(), false);
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
// Dash {2}{R}{R}
this.addAbility(new DashAbility(this, "{2}{R}{R}"));
}
public FlamerushRider(final FlamerushRider card) {
super(card);
}
@Override
public FlamerushRider copy() {
return new FlamerushRider(this);
}
}
class FlamerushRiderEffect extends OneShotEffect {
public FlamerushRiderEffect() {
super(Outcome.Copy);
this.staticText = "put a token onto the battlefield tapped and attacking that's a copy of another target attacking creature. Exile the token at end of combat";
}
public FlamerushRiderEffect(final FlamerushRiderEffect effect) {
super(effect);
}
@Override
public FlamerushRiderEffect copy() {
return new FlamerushRiderEffect(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) {
EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from(permanent);
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId(), true, true);
Effect effect = new ExileTargetEffect();
effect.setTargetPointer(new FixedTarget(token.getLastAddedToken()));
new CreateDelayedTriggeredAbilityEffect(new AtTheEndOfCombatDelayedTriggeredAbility(effect), false).apply(game, source);
return true;
}
return false;
}
}

View file

@ -0,0 +1,87 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksEachTurnStaticAbility;
import mage.abilities.common.BeginningOfCombatTriggeredAbility;
import mage.abilities.condition.common.FerociousCondition;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DoIfCostPaid;
import mage.abilities.effects.common.ReturnToBattlefieldUnderOwnerControlSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public class FlamewakePhoenix extends CardImpl {
public FlamewakePhoenix(UUID ownerId) {
super(ownerId, 100, "Flamewake Phoenix", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{R}{R}");
this.expansionSetCode = "FRF";
this.subtype.add("Phoenix");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Haste
this.addAbility(HasteAbility.getInstance());
// Flamewake Phoenix attacks each turn if able.
this.addAbility(new AttacksEachTurnStaticAbility());
// <i>Ferocious</i> - At the beginning of combat on your turn, if you control a creature with power 4 or greater, you may pay {R}. If you do, return Flamewake Phoenix from your graveyard to the battlefield.
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfCombatTriggeredAbility(
Zone.GRAVEYARD,
new DoIfCostPaid(new ReturnToBattlefieldUnderOwnerControlSourceEffect(), new ManaCostsImpl("{R")),
TargetController.YOU, false, false),
FerociousCondition.getInstance(),
"<i>Ferocious</i> &mdash; At the beginning of combat on your turn, if you control a creature with power 4 or greater, you may pay {R}. If you do, return {this} from your graveyard to the battlefield.",
false
));
}
public FlamewakePhoenix(final FlamewakePhoenix card) {
super(card);
}
@Override
public FlamewakePhoenix copy() {
return new FlamewakePhoenix(this);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Forest1 extends mage.cards.basiclands.Forest {
public Forest1(UUID ownerId) {
super(ownerId, 184);
this.expansionSetCode = "FRF";
}
public Forest1(final Forest1 card) {
super(card);
}
@Override
public Forest1 copy() {
return new Forest1(this);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Forest2 extends mage.cards.basiclands.Forest {
public Forest2(UUID ownerId) {
super(ownerId, 185);
this.expansionSetCode = "FRF";
}
public Forest2(final Forest2 card) {
super(card);
}
@Override
public Forest2 copy() {
return new Forest2(this);
}
}

View file

@ -0,0 +1,69 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.FerociousCondition;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.counters.CounterType;
/**
*
* @author LevelX2
*/
public class FrontierMastodon extends CardImpl {
public FrontierMastodon(UUID ownerId) {
super(ownerId, 130, "Frontier Mastodon", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{G}");
this.expansionSetCode = "FRF";
this.subtype.add("Elephant");
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// <i>Ferocious</i> - Frontier Mastodon enters the battlefield with a +1/+1 counter on it if you control a creature with power 4 or greater.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(CounterType.P1P1.createInstance(1)),
FerociousCondition.getInstance(), true,
"<i>Ferocious</i> &mdash; {this} enters the battlefield with a +1/+1 counter on it if you control a creature with power 4 or greater.",""
));
}
public FrontierMastodon(final FrontierMastodon card) {
super(card);
}
@Override
public FrontierMastodon copy() {
return new FrontierMastodon(this);
}
}

View file

@ -0,0 +1,167 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AddManaToManaPoolSourceControllerEffect;
import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.SetTargetPointer;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class FrontierSiege extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("a creature with flying");
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("a creature you don't control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
filter.add(new AbilityPredicate(FlyingAbility.class));
filter2.add(new ControllerPredicate(TargetController.NOT_YOU));
}
private final static String ruleTrigger1 = "&bull Khans &mdash; At the beginning of each of your main phases, add {G}{G} to your mana pool.";
private final static String ruleTrigger2 = "&bull Dragons &mdash; Whenever a creature with flying enters the battlefield under your control, you may have it fight target creature you don't control.";
public FrontierSiege(UUID ownerId) {
super(ownerId, 131, "Frontier Siege", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
this.expansionSetCode = "FRF";
// As Frontier Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true,
"As {this} enters the battlefield, choose Khans or Dragons.",""));
// * Khans - At the beginning of each of your main phases, add {G}{G} to your mana pool.
this.addAbility(new ConditionalTriggeredAbility(
new FrontierSiegeKhansTriggeredAbility(),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1));
// * Dragons - Whenever a creature with flying enters the battlefield under your control, you may have it fight target creature you don't control.
Ability ability2 = new ConditionalTriggeredAbility(
new EntersBattlefieldControlledTriggeredAbility(Zone.BATTLEFIELD, new FrontierSiegeFightEffect(), filter, true, SetTargetPointer.PERMANENT, ""),
new ModeChoiceSourceCondition("Dragons"),
ruleTrigger2);
ability2.addTarget(new TargetCreaturePermanent(filter2));
this.addAbility(ability2);
}
public FrontierSiege(final FrontierSiege card) {
super(card);
}
@Override
public FrontierSiege copy() {
return new FrontierSiege(this);
}
}
class FrontierSiegeKhansTriggeredAbility extends TriggeredAbilityImpl {
public FrontierSiegeKhansTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddManaToManaPoolSourceControllerEffect(new Mana(0,2,0,0,0,0,0)), false);
}
public FrontierSiegeKhansTriggeredAbility(final FrontierSiegeKhansTriggeredAbility ability) {
super(ability);
}
@Override
public FrontierSiegeKhansTriggeredAbility copy() {
return new FrontierSiegeKhansTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return (event.getType() == GameEvent.EventType.PRECOMBAT_MAIN_PHASE_PRE
|| event.getType() == GameEvent.EventType.POSTCOMBAT_MAIN_PHASE_PRE)
&& event.getPlayerId().equals(this.controllerId);
}
@Override
public String getRule() {
return "At the beginning of each of your main phases, " + super.getRule();
}
}
class FrontierSiegeFightEffect extends OneShotEffect {
FrontierSiegeFightEffect() {
super(Outcome.Damage);
}
FrontierSiegeFightEffect(final FrontierSiegeFightEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent triggeredCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
Permanent target = game.getPermanent(source.getFirstTarget());
if (triggeredCreature != null
&& target != null
&& triggeredCreature.getCardType().contains(CardType.CREATURE)
&& target.getCardType().contains(CardType.CREATURE)) {
triggeredCreature.damage(target.getPower().getValue(), target.getId(), game, false, true);
target.damage(triggeredCreature.getPower().getValue(), triggeredCreature.getId(), game, false, true);
return true;
}
return false;
}
@Override
public FrontierSiegeFightEffect copy() {
return new FrontierSiegeFightEffect(this);
}
}

View file

@ -0,0 +1,74 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.combat.CantBlockTargetEffect;
import mage.abilities.keyword.DashAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class GoblinHeelcutter extends CardImpl {
public GoblinHeelcutter(UUID ownerId) {
super(ownerId, 102, "Goblin Heelcutter", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{3}{R}");
this.expansionSetCode = "FRF";
this.subtype.add("Goblin");
this.subtype.add("Berserker");
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Whenever Goblin Heelcutter attacks, target creature can't block this turn.
Ability ability = new AttacksTriggeredAbility(new CantBlockTargetEffect(Duration.EndOfTurn), false);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// Dash {2}{R} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)
this.addAbility(new DashAbility(this, "{2}{R}"));
}
public GoblinHeelcutter(final GoblinHeelcutter card) {
super(card);
}
@Override
public GoblinHeelcutter copy() {
return new GoblinHeelcutter(this);
}
}

View file

@ -0,0 +1,63 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.DelveAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class GurmagAngler extends CardImpl {
public GurmagAngler(UUID ownerId) {
super(ownerId, 72, "Gurmag Angler", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{6}{B}");
this.expansionSetCode = "FRF";
this.subtype.add("Zombie");
this.subtype.add("Fish");
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Delve
this.addAbility(new DelveAbility());
}
public GurmagAngler(final GurmagAngler card) {
super(card);
}
@Override
public GurmagAngler copy() {
return new GurmagAngler(this);
}
}

View file

@ -0,0 +1,61 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.keyword.BolsterEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class HonorsReward extends CardImpl {
public HonorsReward(UUID ownerId) {
super(ownerId, 14, "Honor's Reward", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{2}{W}");
this.expansionSetCode = "FRF";
// You gain 4 life.
this.getSpellAbility().addEffect(new GainLifeEffect(4));
// Bolster 2.
this.getSpellAbility().addEffect(new BolsterEffect(2));
}
public HonorsReward(final HonorsReward card) {
super(card);
}
@Override
public HonorsReward copy() {
return new HonorsReward(this);
}
}

View file

@ -0,0 +1,88 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.counters.CounterType;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.WasDealtDamageThisTurnPredicate;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.common.TargetCreaturePermanent;
import mage.target.common.TargetOpponent;
/**
*
* @author LevelX2
*/
public class HoodedAssassin extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature that was dealt damage this turn");
static {
filter.add(new WasDealtDamageThisTurnPredicate());
}
public HoodedAssassin(UUID ownerId) {
super(ownerId, 73, "Hooded Assassin", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.expansionSetCode = "FRF";
this.subtype.add("Human");
this.subtype.add("Assassin");
this.power = new MageInt(1);
this.toughness = new MageInt(2);
// When Hooded Assassin enters the battlefield, choose one -
// * Put a +1/+1 counter on Hooded Assassin.
Ability ability = new EntersBattlefieldTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false);
ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard("creature card from your graveyard")));
// * Destroy target creature that was dealt damage this turn.
Mode mode = new Mode();
mode.getEffects().add(new DestroyTargetEffect());
mode.getTargets().add(new TargetCreaturePermanent(filter));
ability.addMode(mode);
this.addAbility(ability);
}
public HoodedAssassin(final HoodedAssassin card) {
super(card);
}
@Override
public HoodedAssassin copy() {
return new HoodedAssassin(this);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Island1 extends mage.cards.basiclands.Island {
public Island1(UUID ownerId) {
super(ownerId, 178);
this.expansionSetCode = "FRF";
}
public Island1(final Island1 card) {
super(card);
}
@Override
public Island1 copy() {
return new Island1(this);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Island2 extends mage.cards.basiclands.Island {
public Island2(UUID ownerId) {
super(ownerId, 179);
this.expansionSetCode = "FRF";
}
public Island2(final Island2 card) {
super(card);
}
@Override
public Island2 copy() {
return new Island2(this);
}
}

View file

@ -0,0 +1,68 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.keyword.ProwessAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author fireshoes
*/
public class JeskaiSage extends CardImpl {
public JeskaiSage(UUID ownerId) {
super(ownerId, 38, "Jeskai Sage", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.expansionSetCode = "FRF";
this.subtype.add("Human");
this.subtype.add("Monk");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Prowess
this.addAbility(new ProwessAbility());
// When Jeskai Sage dies, draw a card.
this.addAbility(new DiesTriggeredAbility(new DrawCardSourceControllerEffect(1), false));
}
public JeskaiSage(final JeskaiSage card) {
super(card);
}
@Override
public JeskaiSage copy() {
return new JeskaiSage(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class JungleHollow extends mage.sets.khansoftarkir.JungleHollow {
public JungleHollow(UUID ownerId) {
super(ownerId);
this.cardNumber = 169;
this.expansionSetCode = "FRF";
}
public JungleHollow(final JungleHollow card) {
super(card);
}
@Override
public JungleHollow copy() {
return new JungleHollow(this);
}
}

View file

@ -0,0 +1,77 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BecomesAuraAttachToManifestSourceEffect;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continious.GainAbilityAttachedEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public class Lightform extends CardImpl {
public Lightform(UUID ownerId) {
super(ownerId, 16, "Lightform", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}");
this.expansionSetCode = "FRF";
// When Lightform enters the battlefield, it becomes an Aura with enchant creature. Manifest the top card of your library and attach Lightform to it.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BecomesAuraAttachToManifestSourceEffect()));
// Enchanted creature has flying and lifelink.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield));
Effect effect = new GainAbilityAttachedEffect(LifelinkAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield);
effect.setText("and lifelink");
ability.addEffect(effect);
this.addAbility(ability);
}
public Lightform(final Lightform card) {
super(card);
}
@Override
public Lightform copy() {
return new Lightform(this);
}
}

View file

@ -0,0 +1,72 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.keyword.DashAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.players.Player;
import mage.players.Players;
/**
*
* @author fireshoes
*/
public class MarduShadowspear extends CardImpl {
public MarduShadowspear(UUID ownerId) {
super(ownerId, 74, "Mardu Shadowspear", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{B}");
this.expansionSetCode = "FRF";
this.subtype.add("Human");
this.subtype.add("Warrior");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Whenever Mardu Shadowspear attacks, each opponent loses 1 life.
this.addAbility(new AttacksTriggeredAbility(new LoseLifeOpponentsEffect(1),false));
// Dash {1}{B}
this.addAbility(new DashAbility(this, "{1}{B}"));
}
public MarduShadowspear(final MarduShadowspear card) {
super(card);
}
@Override
public MarduShadowspear copy() {
return new MarduShadowspear(this);
}
}

View file

@ -0,0 +1,82 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.ProwessAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.game.permanent.token.Token;
/**
*
* @author fireshoes
*/
public class MonasteryMentor extends CardImpl {
public MonasteryMentor(UUID ownerId) {
super(ownerId, 20, "Monastery Mentor", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.expansionSetCode = "FRF";
this.subtype.add("Human");
this.subtype.add("Monk");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Prowess
this.addAbility(new ProwessAbility());
// Whenever you cast a noncreature spell, put a 1/1 white Monk creature token with prowess onto the battlefield.
this.addAbility(new SpellCastControllerTriggeredAbility(new CreateTokenEffect(new MonasteryMentorToken()), false));
}
public MonasteryMentor(final MonasteryMentor card) {
super(card);
}
@Override
public MonasteryMentor copy() {
return new MonasteryMentor(this);
}
}
class MonasteryMentorToken extends Token {
MonasteryMentorToken() {
super("Monk", "1/1 white Monk creature token with prowess");
cardType.add(CardType.CREATURE);
color.setBlack(true);
subtype.add("Monk");
power = new MageInt(1);
toughness = new MageInt(1);
this.addAbility(new ProwessAbility());
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Mountain1 extends mage.cards.basiclands.Mountain {
public Mountain1(UUID ownerId) {
super(ownerId, 182);
this.expansionSetCode = "FRF";
}
public Mountain1(final Mountain1 card) {
super(card);
}
@Override
public Mountain1 copy() {
return new Mountain1(this);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Mountain2 extends mage.cards.basiclands.Mountain {
public Mountain2(UUID ownerId) {
super(ownerId, 183);
this.expansionSetCode = "FRF";
}
public Mountain2(final Mountain2 card) {
super(card);
}
@Override
public Mountain2 copy() {
return new Mountain2(this);
}
}

View file

@ -0,0 +1,168 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.ZoneChangeAllTriggeredAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCreatureOrPlayer;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author LevelX2
*/
public class OutpostSiege extends CardImpl {
private final static String ruleTrigger1 = "&bull Khans &mdash; At the beginning of your upkeep, exile the top card of your library. Until end of turn, you may play that card.";
private final static String ruleTrigger2 = "&bull Dragons &mdash; Whenever a creature you control leaves the battlefield, {this} deals 1 damage to target creature or player.";
public OutpostSiege(UUID ownerId) {
super(ownerId, 110, "Outpost Siege", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}");
this.expansionSetCode = "FRF";
// As Outpost Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true,
"As {this} enters the battlefield, choose Khans or Dragons.",""));
// * Khans - At the beginning of your upkeep, exile the top card of your library. Until end of turn, you may play that card.
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new OutpostSiegeExileEffect(), TargetController.YOU, false),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1));
// * Dragons - Whenever a creature you control leaves the battlefield, Outpost Siege deals 1 damage to target creature or player.
Ability ability2 = new ConditionalTriggeredAbility(
new ZoneChangeAllTriggeredAbility(Zone.BATTLEFIELD, Zone.BATTLEFIELD, null, new DamageTargetEffect(1),
new FilterControlledCreaturePermanent(), "", false),
new ModeChoiceSourceCondition("Dragons"),
ruleTrigger2);
ability2.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability2);
}
public OutpostSiege(final OutpostSiege card) {
super(card);
}
@Override
public OutpostSiege copy() {
return new OutpostSiege(this);
}
}
class OutpostSiegeExileEffect extends OneShotEffect {
public OutpostSiegeExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile the top card of your library. Until end of turn, you may play that card";
}
public OutpostSiegeExileEffect(final OutpostSiegeExileEffect effect) {
super(effect);
}
@Override
public OutpostSiegeExileEffect copy() {
return new OutpostSiegeExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = controller.getLibrary().getFromTop(game);
if (card != null) {
controller.moveCardToExileWithInfo(card, null, "", source.getSourceId(), game, Zone.LIBRARY);
if (game.getState().getZone(card.getId()) == Zone.EXILED) {
ContinuousEffect effect = new CastFromNonHandZoneTargetEffect(Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
}
}
return true;
}
return false;
}
}
class CastFromNonHandZoneTargetEffect extends AsThoughEffectImpl {
public CastFromNonHandZoneTargetEffect(Duration duration) {
super(AsThoughEffectType.PLAY_FROM_NON_HAND_ZONE, duration, Outcome.Benefit);
staticText = "until end of turn, you may play that card";
}
public CastFromNonHandZoneTargetEffect(final CastFromNonHandZoneTargetEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public CastFromNonHandZoneTargetEffect copy() {
return new CastFromNonHandZoneTargetEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (getTargetPointer().getTargets(game, source).contains(objectId) &&
source.getControllerId().equals(affectedControllerId)) {
Card card = game.getCard(objectId);
if (card != null) {
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,93 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.condition.common.ModeChoiceSourceCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ChooseModeEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterCreatureCard;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author LevelX2
*/
public class PalaceSiege extends CardImpl {
private final static String ruleTrigger1 = "&bull Khans &mdash; At the beginning of your upkeep, return target creature card from your graveyard to your hand.";
private final static String ruleTrigger2 = "&bull Dragons &mdash; At the beginning of your upkeep, each opponent loses 2 life and you gain 2 life.";
public PalaceSiege(UUID ownerId) {
super(ownerId, 79, "Palace Siege", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
this.expansionSetCode = "FRF";
// As Palace Siege enters the battlefield, choose Khans or Dragons.
this.addAbility(new EntersBattlefieldAbility(new ChooseModeEffect("Khans or Dragons?","Khans", "Dragons"),null, true,
"As {this} enters the battlefield, choose Khans or Dragons.",""));
// * Khans - At the beginning of your upkeep, return target creature card from your graveyard to your hand.
Ability ability1 = new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new ReturnFromGraveyardToHandTargetEffect(), TargetController.YOU, false),
new ModeChoiceSourceCondition("Khans"),
ruleTrigger1);
ability1.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
this.addAbility(ability1);
// * Dragons - At the beginning of your upkeep, each opponent loses 2 life and you gain 2 life.
Ability ability2 = new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new LoseLifeOpponentsEffect(2), TargetController.YOU, false),
new ModeChoiceSourceCondition("Dragons"),
ruleTrigger2);
Effect effect = new GainLifeEffect(2);
effect.setText("and you gain 2 life");
ability2.addEffect(effect);
this.addAbility(ability2);
}
public PalaceSiege(final PalaceSiege card) {
super(card);
}
@Override
public PalaceSiege copy() {
return new PalaceSiege(this);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Plains1 extends mage.cards.basiclands.Plains {
public Plains1(UUID ownerId) {
super(ownerId, 176);
this.expansionSetCode = "FRF";
}
public Plains1(final Plains1 card) {
super(card);
}
@Override
public Plains1 copy() {
return new Plains1(this);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class Plains2 extends mage.cards.basiclands.Plains {
public Plains2(UUID ownerId) {
super(ownerId, 177);
this.expansionSetCode = "FRF";
}
public Plains2(final Plains2 card) {
super(card);
}
@Override
public Plains2 copy() {
return new Plains2(this);
}
}

View file

@ -0,0 +1,73 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BecomesAuraAttachToManifestSourceEffect;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continious.GainAbilityAttachedEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public class Rageform extends CardImpl {
public Rageform(UUID ownerId) {
super(ownerId, 112, "Rageform", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{R}");
this.expansionSetCode = "FRF";
// When Rageform enters the battlefield, it becomes an Aura with enchant creature. Manifest the top card of your library and attach Rageform to it.
this.addAbility(new EntersBattlefieldTriggeredAbility(new BecomesAuraAttachToManifestSourceEffect()));
// Enchanted creature has double strike.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new GainAbilityAttachedEffect(DoubleStrikeAbility.getInstance(), AttachmentType.AURA, Duration.WhileOnBattlefield)));
}
public Rageform(final Rageform card) {
super(card);
}
@Override
public Rageform copy() {
return new Rageform(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class RuggedHighlands extends mage.sets.khansoftarkir.RuggedHighlands {
public RuggedHighlands(UUID ownerId) {
super(ownerId);
this.cardNumber = 170;
this.expansionSetCode = "FRF";
}
public RuggedHighlands(final RuggedHighlands card) {
super(card);
}
@Override
public RuggedHighlands copy() {
return new RuggedHighlands(this);
}
}

View file

@ -0,0 +1,68 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.keyword.BolsterEffect;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
/**
*
* @author LevelX2
*/
public class SandsteppeMastodon extends CardImpl {
public SandsteppeMastodon(UUID ownerId) {
// TODO: Fix collector number
super(ownerId, 9901, "Sandsteppe Mastodon", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{G}{G}");
this.expansionSetCode = "FRF";
this.subtype.add("Elephant");
this.power = new MageInt(5);
this.toughness = new MageInt(5);
// Reach
this.addAbility(ReachAbility.getInstance());
// When Sandsteppe Mastodon enters the battlefield, bolster 5. (Choose a creature with the least toughness or tied with the least toughness among creatures you control. Put 5 +1/+1 counters on it.)
this.addAbility(new EntersBattlefieldTriggeredAbility(new BolsterEffect(5), false));
}
public SandsteppeMastodon(final SandsteppeMastodon card) {
super(card);
}
@Override
public SandsteppeMastodon copy() {
return new SandsteppeMastodon(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sets.fatereforged;
import java.util.UUID;
/**
*
* @author fireshoes
*/
public class ScouredBarrens extends mage.sets.khansoftarkir.ScouredBarrens {
public ScouredBarrens(UUID ownerId) {
super(ownerId);
this.cardNumber = 171;
this.expansionSetCode = "FRF";
}
public ScouredBarrens(final ScouredBarrens card) {
super(card);
}
@Override
public ScouredBarrens copy() {
return new ScouredBarrens(this);
}
}

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