This commit is contained in:
Goudt 2017-01-28 10:42:42 +01:00
commit ac283b02f6
75 changed files with 1639 additions and 379 deletions

View file

@ -38,9 +38,12 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JTextField;
import mage.client.MageFrame;
import mage.client.SessionHandler;
import mage.client.dialog.PreferencesDialog;
import mage.client.util.GUISizeHelper;
import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType;
@ -184,6 +187,45 @@ public class ChatPanelBasic extends javax.swing.JPanel {
}
}
Pattern profanityPattern = Pattern.compile(".*(1ab1a|1d1ot|13p3r|13sb1ans|13sbo|13s13|13sb1an|13sbo|13sy|1nbr3d|1nc3st|1njun|1ub3|\\Wbj|\\Wcum|\\Wdum|\\Wfag|\\Wfap|\\W[sf]uk|\\Wj1s|\\Wp3do|\\Wp33|\\Wpoo\\W|\\Wt1t|aho13|an1ngu|ana1|anus|ar3o1a|ar3o13|ary1an|axyx|axyxhat|axyxho13|axyxmast3r|axyxmunch|axyxw1p3|b1atch|b1gt1t|b1mbo|b1ow|b1tch|ba1s|bab3|bang|barf|bastard|bawdy|b3an3r|b3ard3dc1am|b3ast1a1ty|b3atch|b3at3r|b3av3r|b3otch|b3yotch|bo1nk|bod1y|bon3d|bon3r|bon3|bob|bot13|boty|bow31|br3ast|bug3r|bukak3|bung|busty|buxyx|c1t|caca|cahon3|cam31to3|carp3tmunch3r|cawk|c3rv1x|ch1nc|ch1nk|chod3|co1ta1|cockb1ock|cockho1st3r|cocknock3r|cocksmok3r|cocksuck3r|cock|condom|corksuck3r|crabs|cums1ut|cumshot|cumsta1n|cnt|cun1ngus|cuntfac3|cunthunt3r|cunt|d1ck|d1k3|d1do|d1mw1t|d1ng13|d1psh1p|dago|dam1t|damn1t|damn3d|damn|dawg13sty13|dog13sty13|dogysty13|dong|dop3y|douch3|drunk|dumb|dumas|dum|dumbas|dumy|dyk3|3jacu1at3|3n1arg3m3nt|3r3ct1on|3r3ct|3rot1c|3xtacy|3xtasy|f.ck|f1osy|f1st3d|f1st1ng|f1sty|fa1gt|fa1g|fack|fag1t|fag3d|fagot|fag|[sf]cuk|f31at1o|f31at3|f31ch1ng|f31ch3r|f31ch|f31tch3r|f31tch|foad|fobar|fond13|for3sk1n|fu.k|fudg3pack3r|[sf]uk|g1ans|g1go1o|ganja|ghay|gh3y|go1d3nshow3r|gonad|gok|gr1ngo|h1t13r|handjob|hardon|hokah|hok3r|homo|honky|hor|hotch|hot3r|horny|hump1ng|hump3d|hump|hym3n|j1sm|j1s3d|j1sm|j1s|jackas|jackho13|jackof|j3rk3d|j3rkof|j3rk|junk13|junky|k1an|k1k3|k1nky|knob3nd|kyk3|mams|masa|mast3rba|masturba|max1|m3ns3s|m3nstruat|m[sf]uck1ng|mofo|moron|moth3rf|mthrf|muf|n1ger|n1ga|n1mrod|n1ny|n1p13|nak3d|napa1m|napy|nas1|n3gro|noky|nympho|op1at3|op1um|ora1y|ora1|org13s|organ|orgasm|orgy|ovary|ovum|p1owb1t3r|p1mp|p1nko|p1s3d|p1sof|p1s|pak1|pant13|panty|past13|pasty|p3ck3r|p3doph1|p3p3|p3n1a1|p3n13|p3n1s|p3n3trat1on|p3n3trat3|p3rv3rs1on|p3yot3|pha1c|phuck|po1ack|po1ock|pontang|pop|pr1ck|pr1g|pron|pub1|pub3|punkas|punky|pus1|pusy|puto|qu1cky|qu1ck13|qu1m|qu3af|qu3ro|qu3rs|qu3r|r1mjob|r1tard|racy|rap1st|rap3d|rap3r|rap3|raunch|r31ch|r3cta1|r3ctum|r3ctus|r3tard|r3tar|rtard|rumpram3r|rump|s1av3|s13as|s1ut|sack|sad1s|scag|sch1ong|sch1so|scr3w|scrog|scrot|scrud|scum|s3aman|s3am3n|s3duc3|s3m3n|s3xua1|sh1t|skag|skank|sm3gma|smut|sn1p3r|snatch|sodom|sp1ck|sp1c|sp1k|sp3rm|spunk|st3amy|stfu|ston3d|str1p|strok3|stup1d|suck|sumofab1atch|t1nk13|t1t[sf]uck|tampon|tard|t3abag1ng|t3at|t3st1|t3st3|t3urd|thrust|tramp|trans|trashy|twat|ug1y|unw3d|ur1n3a|ut3rus|vag1na|vu1gar|vu1va|w1g3r|wang|wank3r|wank|w31n3r|w31rdo|w3dg13|w3n13|w3tback|w3w3|wh1t3y|wh1s|whor3).*");
Pattern profanity2Pattern = Pattern.compile(".*(1ab1a|1d1ot|13p3r|13sb1ans|13sbo|13s13|13sb1an|13sbo|13sy|1nbr3d|1nc3st|1njun|1ub3|\\Wbj|\\Wcum|\\Wdum|\\Wfag|\\Wfap|\\W[sf]uk|\\Wj1s|\\Wp3do|\\Wp3|\\Wpo\\W|\\Wt1t|aho13|an1ngu|ana1|anus|ar3o1a|ar3o13|ary1an|axyx|axyxhat|axyxho13|axyxmast3r|axyxmunch|axyxw1p3|b1atch|b1gt1t|b1mbo|b1ow|b1tch|ba1s|bab3|bang|barf|bastard|bawdy|b3an3r|b3ard3dc1am|b3ast1a1ty|b3atch|b3at3r|b3av3r|b3otch|b3yotch|bo1nk|bod1y|bon3d|bon3r|bon3|bob|bot13|boty|bow31|br3ast|bug3r|bukak3|bung|busty|buxyx|c1t|caca|cahon3|cam31to3|carp3tmunch3r|cawk|c3rv1x|ch1nc|ch1nk|chod3|co1ta1|cockb1ock|cockho1st3r|cocknock3r|cocksmok3r|cocksuck3r|cock|condom|corksuck3r|crabs|cums1ut|cumshot|cumsta1n|cnt|cun1ngus|cuntfac3|cunthunt3r|cunt|d1ck|d1k3|d1do|d1mw1t|d1ng13|d1psh1p|dago|dam1t|damn1t|damn3d|damn|dawg13sty13|dog13sty13|dogysty13|dong|dop3y|douch3|drunk|dumb|dum|dumas|dumbas|dumy|dyk3|3jacu1at3|3n1arg3m3nt|3r3ct1on|3r3ct|3rot1c|3xtacy|3xtasy|f.ck|f1osy|f1st3d|f1st1ng|f1sty|fa1gt|fa1g|fack|fag1t|fag3d|fagot|fag|[sf]cuk|f31at1o|f31at3|f31ch1ng|f31ch3r|f31ch|f31tch3r|f31tch|foad|fobar|fond13|for3sk1n|fu.k|fudg3pack3r|[sf]uk|g1ans|g1go1o|ganja|ghay|gh3y|go1d3nshow3r|gonad|gr1ngo|h1t13r|handjob|hardon|hokah|hok3r|homo|honky|hor|hotch|hot3r|horny|hump1ng|hump3d|hump|hym3n|j1sm|j1s3d|j1sm|j1s|jackas|jackho13|jackof|j3rk3d|j3rkof|j3rk|junk13|junky|k1an|k1k3|k1nky|knob3nd|kyk3|mams|masa|mast3rba|masturba|max1|m3ns3s|m3nstruat|m[sf]uck1ng|mofo|moron|moth3rf|mthrf|muf|n1ga|n1ger|n1mrod|n1ny|n1p13|nak3d|napa1m|napy|nas1|n3gro|noky|nympho|op1at3|op1um|ora1y|ora1|org13s|organ|orgasm|orgy|ovary|ovum|p1owb1t3r|p1mp|p1nko|p1s3d|p1sof|p1s|pak1|pant13|panty|past13|pasty|p3ck3r|p3doph1|p3p3|p3n1a1|p3n13|p3n1s|p3n3trat1on|p3n3trat3|p3rv3rs1on|p3yot3|pha1c|phuck|po1ack|po1ock|pontang|pop|porno|porn|pr1ck|pr1g|pron|pub1|pub3|punkas|punky|pus1|pusy|puto|qu1cky|qu1ck13|qu1m|qu3af|qu3ro|qu3rs|qu3r|r1mjob|r1tard|racy|rap1st|rap3d|rap3r|rap3|raunch|r31ch|r3cta1|r3ctum|r3ctus|r3tard|r3tar|rtard|rumpram3r|rump|s1av3|s13as|s1ut|sack|sad1s|scag|sch1ong|sch1so|scr3w|scrog|scrot|scrud|scum|s3aman|s3am3n|s3duc3|s3m3n|s3xua1|sh1t|skag|skank|sm3gma|smut|sn1p3r|snatch|sodom|sp1ck|sp1c|sp1k|sp3rm|spunk|st3amy|stfu|ston3d|str1p|strok3|stup1d|suck|sumofab1atch|t1nk13|t1t[sf]uck|tampon|tard|t3abag1ng|t3at|t3st1|t3st3|t3urd|thrust|tramp|trans|trashy|twat|ug1y|unw3d|ur1n3a|ut3rus|vag1na|vu1gar|vu1va|w1g3r|wang|wank3r|wank|w31n3r|w31rdo|w3dg13|w3n13|w3tback|w3w3|wh1t3y|wh1s|whor3).*");
private boolean containsSwearing(String message, String level) {
if (level.equals("0")) {
return false;
}
message = "." + message + ".";
message = message.toLowerCase();
message = message.replaceAll("[a@]([s5][s5]+)", "axyx");
message = message.replaceAll("b.([t\\+][t\\+]+)", "buxyx");
message = message.replaceAll("(.)(\\1{1,})", "$1");
message = message.replaceAll("[@]", "a");
message = message.replaceAll("[il]", "1");
message = message.replaceAll("[e]", "3");
message = message.replaceAll("[0]", "o");
message = message.replaceAll("[5z]", "s");
message = message.replaceAll("\\W", ".");
message = message.replaceAll("(.)(\\1{1,})", "$1");
message = message.replaceAll("\\.", "");
Matcher matchPattern = profanityPattern.matcher(message);
if (matchPattern.find()) {
return true;
}
if (level.equals("2")) {
message = message.replaceAll("\\.", "");
message = "." + message + ".";
matchPattern = profanity2Pattern.matcher(message);
if (matchPattern.find()) {
return true;
}
}
return false;
}
/**
* Display message in the chat. Use different colors for timestamp, username
* and message.
@ -194,6 +236,8 @@ public class ChatPanelBasic extends javax.swing.JPanel {
* @param messageType
* @param color Preferred color. Not used.
*/
Pattern cardNamePattern = Pattern.compile(".*<font bgcolor=orange.*?</font>.*");
public void receiveMessage(String username, String message, String time, MessageType messageType, MessageColor color) {
StringBuilder text = new StringBuilder();
if (time != null) {
@ -227,11 +271,42 @@ public class ChatPanelBasic extends javax.swing.JPanel {
if (color.equals(MessageColor.YELLOW)) {
textColor = "Yellow";
}
if (username != null && !username.isEmpty()) {
text.append(getColoredText(userColor, username + userSeparator));
if (messageType == MessageType.WHISPER) {
if (username.equalsIgnoreCase("Whisper from " + SessionHandler.getUserName())) {
if (message.toLowerCase().startsWith("profanity 0")) {
PreferencesDialog.saveValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "0");
} else if (message.toLowerCase().startsWith("profanity 1")) {
PreferencesDialog.saveValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "1");
} else if (message.toLowerCase().startsWith("profanity 2")) {
PreferencesDialog.saveValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "2");
}
}
}
Matcher matchPattern = cardNamePattern.matcher(message);
String messageToTest = message;
while (matchPattern.find()) {
messageToTest = message.replaceFirst("<font bgcolor=orange.*?</font>", "");
}
if (messageType == MessageType.USER_INFO || messageType == MessageType.GAME || messageType == MessageType.STATUS
|| PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "0").equals("0")
|| !PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "0").equals("0") && !containsSwearing(messageToTest, PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "0"))) {
if (username != null && !username.isEmpty()) {
text.append(getColoredText(userColor, username + userSeparator));
}
text.append(getColoredText(textColor, ManaSymbols.replaceSymbolsWithHTML(message, ManaSymbols.Type.CHAT)));
this.txtConversation.append(text.toString());
} else if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "0").equals("1")) {
if (username != null && !username.isEmpty()) {
text.append(getColoredText("black", username + userSeparator));
}
text.append(getColoredText(textColor, ManaSymbols.replaceSymbolsWithHTML("<font color=black size=-2>" + message + "</font> <font size=-2>Profanity detected. Type: <font color=green>/w " + SessionHandler.getUserName() + " profanity 0</font>' to turn the filter off</font></font>", ManaSymbols.Type.CHAT)));
this.txtConversation.append(text.toString());
} else if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_GAME_USE_PROFANITY_FILTER, "0").equals("2")) {
text.append(getColoredText(textColor, ManaSymbols.replaceSymbolsWithHTML("<font color=black size=-2>" + username + ": Profanity detected. To make it less strict, type: </font> <font color=green size=-2>/w " + SessionHandler.getUserName() + " profanity 1</font>", ManaSymbols.Type.CHAT)));
this.txtConversation.append(text.toString());
}
text.append(getColoredText(textColor, ManaSymbols.replaceSymbolsWithHTML(message, ManaSymbols.Type.CHAT)));
this.txtConversation.append(text.toString());
}
protected String getColoredText(String color, String text) {

View file

@ -98,6 +98,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_GAME_SHOW_STORM_COUNTER = "gameShowStormCounter";
public static final String KEY_GAME_CONFIRM_EMPTY_MANA_POOL = "gameConfirmEmptyManaPool";
public static final String KEY_GAME_ASK_MOVE_TO_GRAVE_ORDER = "gameAskMoveToGraveORder";
public static final String KEY_GAME_USE_PROFANITY_FILTER = "gameUseProfanityFilter";
public static final String KEY_GUI_TABLE_FONT_SIZE = "guiTableFontSize";
public static final String KEY_GUI_CHAT_FONT_SIZE = "guiChatFontSize";

View file

@ -421,7 +421,8 @@ public class CallbackClientImpl implements CallbackClient {
case TABLES:
usedPanel.receiveMessage("", new StringBuilder("Download card images by using the \"Images\" menu to the top right .")
.append("<br/>Download icons and symbols by using the \"Symbols\" menu to the top right.")
.append("<br/>\\list - Show a list of available chat commands.").toString(),
.append("<br/>\\list - Show a list of available chat commands.")
.append("<br/>Type <font color=green>\\w yourUserName profanity 0 (or 1 or 2)</font> to turn off/on the profanity filter").toString(),
null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
break;

View file

@ -21,7 +21,6 @@ import mage.utils.CardUtil;
import mage.view.CardView;
import mage.view.CounterView;
import mage.view.PermanentView;
import org.apache.log4j.Logger;
/**
* @author stravant@gmail.com
@ -56,8 +55,6 @@ import org.apache.log4j.Logger;
*/
public abstract class CardRenderer {
private static final Logger LOGGER = Logger.getLogger(CardPanel.class);
///////////////////////////////////////////////////////////////////////////
// Common layout metrics between all cards
// The card to be rendered

View file

@ -17,6 +17,7 @@ import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
@ -38,6 +39,23 @@ public class ManaSymbols {
private static boolean mediumSymbolsFound = false;
private static final Map<String, Map<String, Image>> setImages = new HashMap<>();
private static final HashSet<String> onlyMythics = new HashSet<>();
private static final HashSet<String> withoutSymbols = new HashSet<>();
static {
onlyMythics.add("DRB");
onlyMythics.add("V09");
onlyMythics.add("V12");
onlyMythics.add("V13");
onlyMythics.add("V14");
onlyMythics.add("V15");
onlyMythics.add("V16");
onlyMythics.add("EXP");
onlyMythics.add("MPS");
withoutSymbols.add("MPRP");
}
private static final Map<String, Dimension> setImagesExist = new HashMap<>();
private static final Pattern REPLACE_SYMBOLS_PATTERN = Pattern.compile("\\{([^}/]*)/?([^}]*)\\}");
private static String cachedPath;
@ -57,7 +75,15 @@ public class ManaSymbols {
return;
}
for (String set : setCodes) {
String[] codes = new String[]{"C", "U", "R", "M"};
if (withoutSymbols.contains(set)) {
continue;
}
String[] codes;
if (onlyMythics.contains(set)) {
codes = new String[]{"M"};
} else {
codes = new String[]{"C", "U", "R", "M"};
}
Map<String, Image> rarityImages = new HashMap<>();
setImages.put(set, rarityImages);
@ -72,7 +98,7 @@ public class ManaSymbols {
if (h > 0) {
Rectangle r = new Rectangle(21, (int) (h * 21.0f / width));
BufferedImage resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
rarityImages.put(set, resized);
rarityImages.put(rarityCode, resized);
}
} else {
rarityImages.put(rarityCode, image);

View file

@ -58,13 +58,16 @@ public class GathererSets implements Iterable<DownloadJob> {
"KTK", "FRF", "DTK",
"BFZ", "OGW",
"SOI", "EMN",
"KLD", "MPS", "AER",
"KLD", "AER",
"AKH", "HOU"
};
private static final String[] onlyMythics = {
"DRB", "V09", "V12", "V12", "V13", "V14", "V15", "V16", "EXP"
};
private static final String[] onlyMythicsAsSpecial = {
"MPS"
};
private static final HashMap<String, String> symbolsReplacements = new HashMap<>();
@ -93,6 +96,7 @@ public class GathererSets implements Iterable<DownloadJob> {
symbolsReplacements.put("LEA", "1E");
symbolsReplacements.put("LEB", "2E");
symbolsReplacements.put("LEG", "LE");
symbolsReplacements.put("MPS", "MPS_KLD");
symbolsReplacements.put("MIR", "MI");
symbolsReplacements.put("MMQ", "MM");
symbolsReplacements.put("NEM", "NE");
@ -123,41 +127,47 @@ public class GathererSets implements Iterable<DownloadJob> {
public Iterator<DownloadJob> iterator() {
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.add(Calendar.DATE, -14);
c.add(Calendar.DATE, +14); // Try to load the symbols eralies 14 days before release date
Date compareDate = c.getTime();
ArrayList<DownloadJob> jobs = new ArrayList<>();
for (String symbol : symbols) {
ExpansionSet exp = Sets.findSet(symbol);
if (exp != null && exp.getReleaseDate().before(compareDate)) {
jobs.add(generateDownloadJob(symbol, "C"));
jobs.add(generateDownloadJob(symbol, "U"));
jobs.add(generateDownloadJob(symbol, "R"));
jobs.add(generateDownloadJob(symbol, "C", "C"));
jobs.add(generateDownloadJob(symbol, "U", "U"));
jobs.add(generateDownloadJob(symbol, "R", "R"));
}
}
for (String symbol : withMythics) {
ExpansionSet exp = Sets.findSet(symbol);
if (exp != null && exp.getReleaseDate().before(compareDate)) {
jobs.add(generateDownloadJob(symbol, "C"));
jobs.add(generateDownloadJob(symbol, "U"));
jobs.add(generateDownloadJob(symbol, "R"));
jobs.add(generateDownloadJob(symbol, "M"));
jobs.add(generateDownloadJob(symbol, "C", "C"));
jobs.add(generateDownloadJob(symbol, "U", "U"));
jobs.add(generateDownloadJob(symbol, "R", "R"));
jobs.add(generateDownloadJob(symbol, "M", "M"));
}
}
for (String symbol : onlyMythics) {
ExpansionSet exp = Sets.findSet(symbol);
if (exp != null && exp.getReleaseDate().before(compareDate)) {
jobs.add(generateDownloadJob(symbol, "M"));
jobs.add(generateDownloadJob(symbol, "M", "M"));
}
}
for (String symbol : onlyMythicsAsSpecial) {
ExpansionSet exp = Sets.findSet(symbol);
if (exp != null && exp.getReleaseDate().before(compareDate)) {
jobs.add(generateDownloadJob(symbol, "M", "S"));
}
}
return jobs.iterator();
}
private DownloadJob generateDownloadJob(String set, String rarity) {
private DownloadJob generateDownloadJob(String set, String rarity, String urlRarity) {
File dst = new File(outDir, set + "-" + rarity + ".jpg");
if (symbolsReplacements.containsKey(set)) {
set = symbolsReplacements.get(set);
}
String url = "http://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=" + set + "&size=small&rarity=" + rarity;
String url = "http://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=" + set + "&size=small&rarity=" + urlRarity;
return new DownloadJob(set + "-" + rarity, fromURL(url), toFile(dst));
}

View file

@ -41,7 +41,7 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
public final static int MAGE_VERSION_MAJOR = 1;
public final static int MAGE_VERSION_MINOR = 4;
public final static int MAGE_VERSION_PATCH = 21;
public final static String MAGE_VERSION_MINOR_PATCH = "V0";
public final static String MAGE_VERSION_MINOR_PATCH = "V1";
public final static String MAGE_VERSION_INFO = "";
private final int major;

View file

@ -107,6 +107,7 @@
<draftCube name="MTGO Legacy Cube September 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
<draftCube name="MTGO Legacy Cube January 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
<draftCube name="MTGO Legacy Cube September 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
<draftCube name="MTGO Legacy Cube January 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/>

View file

@ -104,6 +104,7 @@
<draftCube name="MTGO Legacy Cube September 2015" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2015"/>
<draftCube name="MTGO Legacy Cube January 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeJanuary2016"/>
<draftCube name="MTGO Legacy Cube September 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegacyCubeSeptember2016"/>
<draftCube name="MTGO Legacy Cube January 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegacyCubeJanuary2017"/>
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2013"/>

View file

@ -107,13 +107,6 @@ public class ChatManager {
this.broadcast(chatId, userName, message, color, withTime, messageType, null);
}
private boolean containsSwearing(String message) {
if (message != null && message.toLowerCase().matches("^.*(anal|asshole|balls|bastard|bitch|blowjob|cock|crap|cunt|cum|damn|dick|dildo|douche|fag|fuck|idiot|moron|penis|piss|prick|pussy|rape|rapist|sex|screw|shit|slut|vagina).*$")) {
return true;
}
return false;
}
final Pattern cardNamePattern = Pattern.compile("\\[(.*?)\\]");
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) {
@ -167,11 +160,6 @@ public class ChatManager {
}
userMessages.put(userName, message);
if (containsSwearing(messageToCheck)) {
String informUser = "Your message appears to contain profanity";
chatSessions.get(chatId).broadcastInfoToUser(user, informUser);
return;
}
}
if (messageType == MessageType.TALK) {
@ -204,6 +192,7 @@ public class ChatManager {
String command = message.substring(1).trim().toUpperCase(Locale.ENGLISH);
if (doError) {
message += new StringBuilder("<br/>Invalid User Command '" + message + "'.").append(COMMANDS_LIST).toString();
message += "<br/>Type <font color=green>\\w " + user.getName() + " profanity 0 (or 1 or 2)</font> to use/not use the profanity filter";
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}
@ -239,6 +228,7 @@ public class ChatManager {
}
if (command.equals("L") || command.equals("LIST")) {
message += COMMANDS_LIST;
message += "<br/>Type <font color=green>\\w " + user.getName() + " profanity 0 (or 1 or 2)</font> to use/not use the profanity filter";
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}

View file

@ -27,6 +27,14 @@
*/
package mage.server;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import mage.MageException;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardLists;
@ -60,15 +68,6 @@ import mage.server.util.ThreadExecutor;
import mage.view.ChatMessage;
import org.apache.log4j.Logger;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -96,10 +95,9 @@ public class TableController {
if (userId != null) {
Optional<User> user = UserManager.getInstance().getUser(userId);
// TODO: Handle if user == null
if(user.isPresent()) {
if (user.isPresent()) {
controllerName = user.get().getName();
}
else{
} else {
controllerName = "undefined";
}
} else {
@ -578,10 +576,10 @@ public class TableController {
GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId, gameOptions);
String creator = null;
StringBuilder opponent = new StringBuilder();
for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) { // no AI players
for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) { // do only for no AI players
if (match.getPlayer(entry.getValue()) != null && !match.getPlayer(entry.getValue()).hasQuit()) {
Optional<User> _user = UserManager.getInstance().getUser(entry.getKey());
if (!_user.isPresent()) {
if (_user.isPresent()) {
User user = _user.get();
user.ccGameStarted(match.getGame().getId(), entry.getValue());
@ -978,8 +976,8 @@ public class TableController {
void cleanUp() {
if (!table.isTournamentSubTable()) {
for (Map.Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
UserManager.getInstance().getUser(entry.getKey()).ifPresent(user ->
user.removeTable(entry.getValue()));
UserManager.getInstance().getUser(entry.getKey()).ifPresent(user
-> user.removeTable(entry.getValue()));
}
}

View file

@ -313,7 +313,7 @@ public class GameController implements GameCallback {
logger.fatal("- userId: " + userId);
return;
}
if(!user.isPresent(){
if (!user.isPresent()) {
logger.fatal("User not found : "+userId);
return;
}

View file

@ -110,6 +110,8 @@ class AidFromTheCowlEffect extends OneShotEffect {
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
} else if (controller.chooseUse(Outcome.Neutral, "Put " + card.getIdName() + " on the bottom of your library?", source, game)) {
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
} else {
game.informPlayers(controller.getLogName() + " puts the revealed card back to the top of the library.");
}
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.b;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.abilities.effects.common.continuous.AddCardSubtypeAllEffect;
import mage.constants.CardType;
import mage.constants.DependencyType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent;
/**
*
* @author Galatolol
*/
public class BlanketOfNight extends CardImpl {
public BlanketOfNight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}");
// Each land is a Swamp in addition to its other land types.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new BlackManaAbility(), Duration.WhileOnBattlefield, new FilterLandPermanent(),
"Each land is a Swamp in addition to its other land types"));
ability.addEffect(new AddCardSubtypeAllEffect(new FilterLandPermanent(), "Swamp", DependencyType.BecomeSwamp));
this.addAbility(ability);
}
public BlanketOfNight(final BlanketOfNight card) {
super(card);
}
@Override
public BlanketOfNight copy() {
return new BlanketOfNight(this);
}
}

View file

@ -46,8 +46,8 @@ import mage.filter.predicate.permanent.ControllerPredicate;
* @author fireshoes
*/
public class ChiefOfTheFoundry extends CardImpl {
private static final FilterCreaturePermanent filterBoosted = new FilterCreaturePermanent("artifact creatures");
private static final FilterCreaturePermanent filterBoosted = new FilterCreaturePermanent("Other artifact creatures you control");
static {
filterBoosted.add(new CardTypePredicate(CardType.ARTIFACT));
@ -55,7 +55,7 @@ public class ChiefOfTheFoundry extends CardImpl {
}
public ChiefOfTheFoundry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT,CardType.CREATURE},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}");
this.subtype.add("Construct");
this.power = new MageInt(2);
this.toughness = new MageInt(3);

View file

@ -27,6 +27,8 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesAttachedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -37,12 +39,10 @@ import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.permanent.token.OozeToken;
import mage.game.permanent.token.Token;
import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
@ -54,17 +54,19 @@ public class CorruptedZendikon extends CardImpl {
this.subtype.add("Aura");
// Enchant land
// Enchanted land is a 3/3 black Ooze creature. It's still a land.
// When enchanted land dies, return that card to its owner's hand.
TargetPermanent auraTarget = new TargetLandPermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.PutCreatureInPlay));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
Ability ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesCreatureAttachedEffect(new OozeToken(3, 3), "Enchanted land is a 3/3 black Ooze creature. It's still a land.", Duration.WhileOnBattlefield));
// Enchanted land is a 3/3 black Ooze creature. It's still a land.
Ability ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD,
new BecomesCreatureAttachedEffect(new CorruptedZendikonOozeToken(),
"Enchanted land is a 3/3 black Ooze creature. It's still a land.", Duration.WhileOnBattlefield));
this.addAbility(ability2);
// When enchanted land dies, return that card to its owner's hand.
Ability ability3 = new DiesAttachedTriggeredAbility(new ReturnToHandAttachedEffect(), "enchanted land", false);
this.addAbility(ability3);
}
@ -78,3 +80,16 @@ public class CorruptedZendikon extends CardImpl {
return new CorruptedZendikon(this);
}
}
class CorruptedZendikonOozeToken extends Token {
public CorruptedZendikonOozeToken() {
super("Ooze", "3/3 black Ooze creature");
cardType.add(CardType.CREATURE);
color.setBlack(true);
subtype.add("Ooze");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
}
}

View file

@ -29,19 +29,20 @@ package mage.cards.d;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetControlledPermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
@ -52,7 +53,6 @@ public class Donate extends CardImpl {
public Donate(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}");
// Target player gains control of target permanent you control.
this.getSpellAbility().addEffect(new DonateEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
@ -69,10 +69,10 @@ public class Donate extends CardImpl {
}
}
class DonateEffect extends ContinuousEffectImpl {
class DonateEffect extends OneShotEffect {
public DonateEffect() {
super(Duration.EndOfGame, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.Benefit);
super(Outcome.Detriment);
this.staticText = "Target player gains control of target permanent you control";
}
@ -86,14 +86,13 @@ class DonateEffect extends ContinuousEffectImpl {
}
@Override
public boolean apply(Game game, Ability source) {
UUID controllerId = source.getTargets().get(0).getFirstTarget();
Player controller = game.getPlayer(controllerId);
public boolean apply(Game game, Ability source) {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (controller != null && permanent != null) {
permanent.changeControllerId(controllerId, game);
} else {
this.discard();
if (targetPlayer != null && permanent != null) {
ContinuousEffect effect = new GainControlTargetEffect(Duration.Custom, true, targetPlayer.getId());
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
}
return true;
}

View file

@ -53,7 +53,7 @@ import mage.game.events.GameEvent.EventType;
public class EternalScourge extends CardImpl {
public EternalScourge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}");
this.subtype.add("Eldrazi");
this.subtype.add("Horror");
this.power = new MageInt(3);
@ -101,13 +101,14 @@ class EternalScourgePlayEffect extends AsThoughEffectImpl {
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(source.getSourceId())) {
Card card = game.getCard(source.getSourceId());
if (card != null && card.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) {
if (card != null && card.getOwnerId().equals(affectedControllerId) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) {
return true;
}
}
return false;
}
}
class EternalScourgeAbility extends TriggeredAbilityImpl {
public EternalScourgeAbility() {

View file

@ -115,6 +115,9 @@ class FairgroundsTrumpeterWatcher extends Watcher {
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.COUNTER_ADDED && event.getData().equals(CounterType.P1P1.getName())) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
if (permanent == null) {
permanent = game.getPermanentEntering(event.getTargetId());
}
if (permanent != null) {
players.add(permanent.getControllerId());
}

View file

@ -71,7 +71,7 @@ class FatalPushEffect extends OneShotEffect {
FatalPushEffect() {
super(Outcome.DestroyPermanent);
this.staticText = "Destroy target creature if it has converted mana cost 2 or less.<br><i>Revolt</i> &mdash; Destroy that creature if it has converted mana cost 4 or less instead if a permanent you controlled left the battlefield this turn.";
this.staticText = "Destroy target creature if it has converted mana cost 2 or less.<br><i>Revolt</i> &mdash; Destroy that creature if it has converted mana cost 4 or less instead if a permanent you controlled left the battlefield this turn";
}
FatalPushEffect(final FatalPushEffect effect) {

View file

@ -0,0 +1,79 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.common.BlocksOrBecomesBlockedTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.ColorPredicate;
/**
*
* @author Galatolol
*/
public class GhostHounds extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("white creature");
static {
filter.add(new ColorPredicate(ObjectColor.WHITE));
}
public GhostHounds(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add("Hound");
this.subtype.add("Spirit");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
// Whenever Ghost Hounds blocks or becomes blocked by a white creature, Ghost Hounds gains first strike until end of turn.
this.addAbility(new BlocksOrBecomesBlockedTriggeredAbility(new GainAbilitySourceEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), filter, false));
}
public GhostHounds(final GhostHounds card) {
super(card);
}
@Override
public GhostHounds copy() {
return new GhostHounds(this);
}
}

View file

@ -0,0 +1,46 @@
package mage.cards.h;
import java.util.ArrayList;
import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
/**
* Created by Alexsandr0x.
*/
public class Hivestone extends CardImpl {
private final static FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
}
public Hivestone(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// Creatures you control are Slivers in addition to their other creature types.
ArrayList<String> subTypes = new ArrayList<>();
subTypes.add("Slivers");
Effect effect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, subTypes, filter, false);
effect.setText("Creatures you control are Slivers in addition to their other creature types");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
}
public Hivestone(final Hivestone card) {
super(card);
}
@Override
public Card copy() {
return new Hivestone(this);
}
}

View file

@ -33,6 +33,7 @@ import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
@ -88,7 +89,8 @@ public class HopeOfGhirapur extends CardImpl {
if (sourceObject != null) {
ability.getTargets().clear();
FilterPlayer playerFilter = new FilterPlayer("player who was dealt combat damage by " + sourceObject.getIdName() + " this turn");
playerFilter.add(new HopeOfGhirapurPlayerLostLifePredicate(ability.getSourceId()));
MageObjectReference sourceReference = new MageObjectReference(ability.getSourceId(), ability.getSourceObjectZoneChangeCounter(), game);
playerFilter.add(new HopeOfGhirapurPlayerLostLifePredicate(sourceReference));
ability.addTarget(new TargetPlayer(1, 1, false, playerFilter));
}
}
@ -155,17 +157,17 @@ class HopeOfGhirapurCantCastEffect extends ContinuousRuleModifyingEffectImpl {
class HopeOfGhirapurPlayerLostLifePredicate implements Predicate<Player> {
private final UUID sourceId;
private final MageObjectReference sourceReference;
public HopeOfGhirapurPlayerLostLifePredicate(UUID sourceId) {
this.sourceId = sourceId;
public HopeOfGhirapurPlayerLostLifePredicate(MageObjectReference sourceReference) {
this.sourceReference = sourceReference;
}
@Override
public boolean apply(Player input, Game game) {
HopeOfGhirapurCombatDamageWatcher watcher = (HopeOfGhirapurCombatDamageWatcher) game.getState().getWatchers().get(HopeOfGhirapurCombatDamageWatcher.class.getName());
if (watcher != null) {
return watcher.playerGotCombatDamage(sourceId, input.getId());
return watcher.playerGotCombatDamage(sourceReference, input.getId());
}
return false;
}
@ -173,7 +175,7 @@ class HopeOfGhirapurPlayerLostLifePredicate implements Predicate<Player> {
class HopeOfGhirapurCombatDamageWatcher extends Watcher {
private final HashMap<UUID, Set<UUID>> combatDamagedPlayers = new HashMap<>();
private final HashMap<MageObjectReference, Set<UUID>> combatDamagedPlayers = new HashMap<>();
public HopeOfGhirapurCombatDamageWatcher() {
super(HopeOfGhirapurCombatDamageWatcher.class.getName(), WatcherScope.GAME);
@ -181,10 +183,10 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
public HopeOfGhirapurCombatDamageWatcher(final HopeOfGhirapurCombatDamageWatcher watcher) {
super(watcher);
for (UUID objectId : watcher.combatDamagedPlayers.keySet()) {
for (MageObjectReference sourceReference : watcher.combatDamagedPlayers.keySet()) {
Set<UUID> players = new HashSet<>();
players.addAll(watcher.combatDamagedPlayers.get(objectId));
this.combatDamagedPlayers.put(objectId, players);
players.addAll(watcher.combatDamagedPlayers.get(sourceReference));
this.combatDamagedPlayers.put(sourceReference, players);
}
}
@ -196,28 +198,29 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == EventType.DAMAGED_PLAYER && ((DamagedPlayerEvent) event).isCombatDamage()) {
MageObjectReference sourceReference = new MageObjectReference(event.getSourceId(), game);
Set<UUID> players;
if (combatDamagedPlayers.containsKey(event.getSourceId())) {
players = combatDamagedPlayers.get(event.getSourceId());
if (combatDamagedPlayers.containsKey(sourceReference)) {
players = combatDamagedPlayers.get(sourceReference);
} else {
players = new HashSet<>();
combatDamagedPlayers.put(event.getSourceId(), players);
combatDamagedPlayers.put(sourceReference, players);
}
players.add(event.getTargetId());
}
}
/**
* Checks if the current object with sourceId has damaged the player during
* the current turn. The zoneChangeCounter will be taken into account.
* Checks if the current object has damaged the player during
* the current turn.
*
* @param sourceId
* @param game
* @param objectReference
* @param playerId
* @return
*/
public boolean playerGotCombatDamage(UUID sourceId, UUID playerId) {
if (combatDamagedPlayers.containsKey(sourceId)) {
return combatDamagedPlayers.get(sourceId).contains(playerId);
public boolean playerGotCombatDamage(MageObjectReference objectReference, UUID playerId) {
if (combatDamagedPlayers.containsKey(objectReference)) {
return combatDamagedPlayers.get(objectReference).contains(playerId);
}
return false;
}

View file

@ -54,15 +54,18 @@ import mage.target.targetpointer.FixedTarget;
public class InvaderParasite extends CardImpl {
public InvaderParasite(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}{R}");
this.subtype.add("Insect");
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Imprint - When Invader Parasite enters the battlefield, exile target land.
Ability ability = new EntersBattlefieldTriggeredAbility(new InvaderParasiteImprintEffect(), false);
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
// Whenever a land with the same name as the exiled card enters the battlefield under an opponent's control, Invader Parasite deals 2 damage to that player.
this.addAbility(new InvaderParasiteTriggeredAbility());
}
@ -77,6 +80,7 @@ public class InvaderParasite extends CardImpl {
}
class InvaderParasiteImprintEffect extends OneShotEffect {
InvaderParasiteImprintEffect() {
super(Outcome.Exile);
staticText = "exile target land";
@ -104,6 +108,7 @@ class InvaderParasiteImprintEffect extends OneShotEffect {
}
class InvaderParasiteTriggeredAbility extends TriggeredAbilityImpl {
InvaderParasiteTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(2));
}
@ -125,12 +130,12 @@ class InvaderParasiteTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getOpponents(this.controllerId).contains(event.getPlayerId())) {
Permanent p = game.getPermanent(event.getTargetId());
Permanent targetPermanent = game.getPermanent(event.getTargetId());
Permanent sourcePermanent = game.getPermanent(getSourceId());
if (p != null && sourcePermanent != null) {
if (targetPermanent != null && sourcePermanent != null) {
if (sourcePermanent.getImprinted().size() > 0) {
Card imprintedCard = game.getCard(sourcePermanent.getImprinted().get(0));
if (p.getName().equals(imprintedCard.getName())) {
if (imprintedCard != null && targetPermanent.getName().equals(imprintedCard.getName())) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}

View file

@ -87,8 +87,8 @@ class LightningRunnerEffect extends OneShotEffect {
LightningRunnerEffect() {
super(Outcome.Benefit);
staticText = "you get {E}{E}, then you may pay {E}{E}{E}{E}{E}{E}{E}{E}. If you do, " +
"untap all creatures you control and after this phase, there is an additional combat phase";
staticText = "you get {E}{E}, then you may pay {E}{E}{E}{E}{E}{E}{E}{E}. If you do, "
+ "untap all creatures you control and after this phase, there is an additional combat phase";
}
LightningRunnerEffect(final LightningRunnerEffect effect) {
@ -100,11 +100,15 @@ class LightningRunnerEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
new GetEnergyCountersControllerEffect(2).apply(game, source);
if (controller.getCounters().getCount(CounterType.ENERGY) > 5) {
Cost cost = new PayEnergyCost(6);
if (cost.pay(source, game, source.getSourceId(), source.getControllerId(), true)) {
new UntapAllControllerEffect(new FilterControlledCreaturePermanent(), "untap all creatures you control").apply(game, source);
new AdditionalCombatPhaseEffect("and after this phase, there is an additional combat phase").apply(game, source);
if (controller.getCounters().getCount(CounterType.ENERGY) > 7) {
Cost cost = new PayEnergyCost(8);
if (controller.chooseUse(outcome,
"Pay {E}{E}{E}{E}{E}{E}{E}{E} to use this? ",
"Untap all creatures you control and after this phase, there is an additional combat phase.",
"Yes", "No", source, game)
&& cost.pay(source, game, source.getSourceId(), source.getControllerId(), true)) {
new UntapAllControllerEffect(new FilterControlledCreaturePermanent()).apply(game, source);
new AdditionalCombatPhaseEffect().apply(game, source);
}
}
return true;

View file

@ -0,0 +1,62 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.m;
import java.util.UUID;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.filter.common.FilterAttackingCreature;
/**
*
* @author Galatolol
*/
public class Morale extends CardImpl {
public Morale(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{W}{W}");
// Attacking creatures get +1/+1 until end of turn.
this.getSpellAbility().addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, new FilterAttackingCreature("Attacking creatures"), false));
}
public Morale(final Morale card) {
super(card);
}
@Override
public Morale copy() {
return new Morale(this);
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.m;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Abilities;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicate;
import mage.game.Game;
/**
*
* @author anonymous
*/
public class MuragandaPetroglyphs extends CardImpl {
private static final FilterCreaturePermanent filterNoAbilities
= new FilterCreaturePermanent("Creatures with no ability");
static {
filterNoAbilities.add(new NoAbilityPredicate());
}
public MuragandaPetroglyphs(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}");
this.expansionSetCode = "FUT";
// Creatures with no abilities get +2/+2.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(
2, 2, Duration.WhileOnBattlefield, filterNoAbilities, false)));
}
public MuragandaPetroglyphs(final MuragandaPetroglyphs card) {
super(card);
}
@Override
public MuragandaPetroglyphs copy() {
return new MuragandaPetroglyphs(this);
}
}
class NoAbilityPredicate implements Predicate<MageObject> {
@Override
public boolean apply(MageObject input, Game game) {
boolean isFaceDown = false;
Abilities<Ability> abilities;
if (input instanceof Card) {
abilities = ((Card) input).getAbilities(game);
isFaceDown = ((Card) input).isFaceDown(game);
} else {
abilities = input.getAbilities();
}
if (isFaceDown) {
for (Ability ability : abilities) {
if (!ability.getSourceId().equals(input.getId())) {
return false;
}
}
return true;
}
for (Ability ability : abilities) {
if (ability.getClass() != SpellAbility.class) {
return false;
}
}
return true;
}
@Override
public String toString() {
return "with no abilities";
}
}

View file

@ -56,7 +56,7 @@ import mage.target.targetpointer.FixedTarget;
public class PossibilityStorm extends CardImpl {
public PossibilityStorm(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{R}{R}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{R}{R}");
// Whenever a player casts a spell from his or her hand, that player exiles it, then exiles cards from
// the top of his or her library until he or she exiles a card that shares a card type with it. That
@ -133,14 +133,14 @@ class PossibilityStormEffect extends OneShotEffect {
if (sourceObject != null && spell != null) {
Player spellController = game.getPlayer(spell.getControllerId());
if (spellController != null
&& spellController.moveCardToExileWithInfo(spell, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.STACK, true)) {
&& spellController.moveCardsToExile(spell, source, game, true, source.getSourceId(), sourceObject.getIdName())) {
if (spellController.getLibrary().size() > 0) {
Library library = spellController.getLibrary();
Card card;
do {
card = library.removeFromTop(game);
card = library.getFromTop(game);
if (card != null) {
spellController.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true);
spellController.moveCardsToExile(card, source, game, true, source.getSourceId(), sourceObject.getIdName());
}
} while (library.size() > 0 && card != null && !sharesType(card, spell.getCardType()));
@ -154,10 +154,7 @@ class PossibilityStormEffect extends OneShotEffect {
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
if (exile != null) {
while (exile.size() > 0) {
card = exile.getRandom(game);
spellController.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.EXILED, false, false);
}
spellController.putCardsOnBottomOfLibrary(exile, game, source, false);
}
}

View file

@ -0,0 +1,106 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.p;
import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author vereena42
*/
public class PowerstoneMinefield extends CardImpl {
public PowerstoneMinefield(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}{W}");
// Whenever a creature attacks or blocks, Powerstone Minefield deals 2 damage to it.
this.addAbility(new PowerstoneMinefieldTriggeredAbility());
}
public PowerstoneMinefield(final PowerstoneMinefield card) {
super(card);
}
@Override
public PowerstoneMinefield copy() {
return new PowerstoneMinefield(this);
}
}
class PowerstoneMinefieldTriggeredAbility extends TriggeredAbilityImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public PowerstoneMinefieldTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(2), false);
}
public PowerstoneMinefieldTriggeredAbility(PowerstoneMinefieldTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.ATTACKER_DECLARED || event.getType() == EventType.BLOCKER_DECLARED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getSourceId());
if (filter.match(permanent, getSourceId(), getControllerId(), game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(permanent, game));
}
return true;
}
return false;
}
@Override
public String getRule() {
return "Whenever a creature attacks or blocks, {this} deals 2 damage to it.";
}
@Override
public PowerstoneMinefieldTriggeredAbility copy() {
return new PowerstoneMinefieldTriggeredAbility(this);
}
}

View file

@ -1,16 +1,16 @@
/*
* 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
@ -20,23 +20,22 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.s;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
@ -49,7 +48,7 @@ import mage.target.TargetCard;
public class SeeBeyond extends CardImpl {
public SeeBeyond(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}");
this.getSpellAbility().addEffect(new SeeBeyondEffect());
}
@ -67,8 +66,6 @@ public class SeeBeyond extends CardImpl {
class SeeBeyondEffect extends OneShotEffect {
private static FilterCard filter = new FilterCard("card to shuffle into your library");
public SeeBeyondEffect() {
super(Outcome.DrawCard);
staticText = "Draw two cards, then shuffle a card from your hand into your library";
@ -80,18 +77,18 @@ class SeeBeyondEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
player.drawCards(2, game);
if (player.getHand().size() > 0) {
TargetCard target = new TargetCard(Zone.HAND, filter);
player.choose(Outcome.Detriment, player.getHand(), target, game);
Card card = player.getHand().get(target.getFirstTarget(), game);
Player controller = game.getPlayer(source.getControllerId());
controller.drawCards(2, game);
if (controller.getHand().size() > 0) {
TargetCard target = new TargetCard(Zone.HAND, new FilterCard("card to shuffle into your library"));
controller.choose(Outcome.Detriment, controller.getHand(), target, game);
Card card = controller.getHand().get(target.getFirstTarget(), game);
if (card != null) {
player.removeFromHand(card, game);
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
player.shuffleLibrary(source, game);
return true;
controller.moveCards(card, Zone.LIBRARY, source, game);
controller.shuffleLibrary(source, game);
}
return true;
}
return true;
}
@ -101,4 +98,4 @@ class SeeBeyondEffect extends OneShotEffect {
return new SeeBeyondEffect(this);
}
}
}

View file

@ -36,6 +36,7 @@ import mage.abilities.dynamicvalue.common.ParleyCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardAllEffect;
import mage.abilities.effects.common.ManaEffect;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -60,13 +61,13 @@ public class SelvalaExplorerReturned extends CardImpl {
this.toughness = new MageInt(4);
// Parley - {T}: Each player reveals the top card of his or her library. For each nonland card revealed this way, add {G} to your mana pool and you gain 1 life. Then each player draws a card.
Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, new SelvalaExplorerReturnedEffect(), new TapSourceCost());
ability.setAbilityWord(AbilityWord.PARLEY);
ActivatedManaAbilityImpl manaAbility = new SimpleManaAbility(Zone.BATTLEFIELD, new SelvalaExplorerReturnedEffect(), new TapSourceCost(), false);
manaAbility.setUndoPossible(false);
manaAbility.setAbilityWord(AbilityWord.PARLEY);
Effect effect = new DrawCardAllEffect(1);
effect.setText("Then each player draws a card");
ability.addEffect(effect);
this.addAbility(ability);
manaAbility.addEffect(effect);
this.addAbility(manaAbility);
}
public SelvalaExplorerReturned(final SelvalaExplorerReturned card) {

View file

@ -63,7 +63,7 @@ public class SelvalaHeartOfTheWilds extends CardImpl {
filter.add(new GreatestPowerPredicate());
}
private static final String rule = "Whenever another creature enters the battlefield, its controller may draw a card if its power is greater than each other creature's power";
private static final String rule = "Whenever another creature enters the battlefield, its controller may draw a card if its power is greater than each other creature's power.";
public SelvalaHeartOfTheWilds(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{G}{G}");

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.cards.s;
import java.util.UUID;
import mage.abilities.common.BecomesTappedAttachedTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersAttachedEffect;
import mage.counters.BoostCounter;
import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.effects.common.AttachEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author Galatolol
*/
public class SpiritShackle extends CardImpl {
public SpiritShackle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}{B}");
this.subtype.add("Aura");
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Whenever enchanted creature becomes tapped, put a -0/-2 counter on it.
this.addAbility(new BecomesTappedAttachedTriggeredAbility(new AddCountersAttachedEffect(new BoostCounter(0, -2), "it"), "enchanted creature"));
}
public SpiritShackle(final SpiritShackle card) {
super(card);
}
@Override
public SpiritShackle copy() {
return new SpiritShackle(this);
}
}

View file

@ -28,18 +28,16 @@
package mage.cards.s;
import java.util.UUID;
import mage.constants.*;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterCreatureSpell;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.stack.Spell;
/**
*
@ -70,8 +68,6 @@ public class SteelGolem extends CardImpl {
class SteelGolemEffect extends ContinuousRuleModifyingEffectImpl {
private static final FilterCreatureSpell filter = new FilterCreatureSpell();
public SteelGolemEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "You can't cast creature spells";
@ -94,10 +90,8 @@ class SteelGolemEffect extends ContinuousRuleModifyingEffectImpl {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getPlayerId().equals(source.getControllerId())) {
Spell spell = game.getStack().getSpell(event.getSourceId());
if (spell != null && filter.match(spell, game)) {
return true;
}
Card card = game.getCard(event.getSourceId());
return card != null && card.getCardType().contains(CardType.CREATURE);
}
return false;
}

View file

@ -32,14 +32,12 @@ import java.util.UUID;
import mage.constants.*;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.abilities.effects.common.continuous.AddCardSubtypeAllEffect;
/**
*
@ -54,7 +52,7 @@ public class UrborgTombOfYawgmoth extends CardImpl {
// Each land is a Swamp in addition to its other land types.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(new BlackManaAbility(), Duration.WhileOnBattlefield, new FilterLandPermanent(),
"Each land is a Swamp in addition to its other land types"));
ability.addEffect(new AddCardSubtypeAllEffect());
ability.addEffect(new AddCardSubtypeAllEffect(new FilterLandPermanent(), "Swamp", DependencyType.BecomeSwamp));
this.addAbility(ability);
}
@ -68,35 +66,3 @@ public class UrborgTombOfYawgmoth extends CardImpl {
return new UrborgTombOfYawgmoth(this);
}
}
class AddCardSubtypeAllEffect extends ContinuousEffectImpl {
private static final FilterLandPermanent filter = new FilterLandPermanent();
private static final String addedSubtype = "Swamp";
public AddCardSubtypeAllEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
staticText = "";
addDependencyType(DependencyType.BecomeSwamp);
}
public AddCardSubtypeAllEffect(final AddCardSubtypeAllEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (perm != null && !perm.getSubtype(game).contains(addedSubtype)) {
perm.getSubtype(game).add(addedSubtype);
}
}
return true;
}
@Override
public AddCardSubtypeAllEffect copy() {
return new AddCardSubtypeAllEffect(this);
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Zone;
/**
*
* @author anonymous
*/
public class WallOfLava extends CardImpl {
public WallOfLava(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}{R}");
this.subtype.add("Wall");
this.power = new MageInt(1);
this.toughness = new MageInt(3);
// Defender
this.addAbility(DefenderAbility.getInstance());
// {R}: Wall of Lava gets +1/+1 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{R}")));
}
public WallOfLava(final WallOfLava card) {
super(card);
}
@Override
public WallOfLava copy() {
return new WallOfLava(this);
}
}

View file

@ -110,6 +110,7 @@ public class Apocalypse extends ExpansionSet {
cards.add(new SetCardInfo("Phyrexian Gargantua", 48, Rarity.UNCOMMON, mage.cards.p.PhyrexianGargantua.class));
cards.add(new SetCardInfo("Phyrexian Rager", 49, Rarity.COMMON, mage.cards.p.PhyrexianRager.class));
cards.add(new SetCardInfo("Planar Despair", 50, Rarity.RARE, mage.cards.p.PlanarDespair.class));
cards.add(new SetCardInfo("Powerstone Minefield", 115, Rarity.RARE, mage.cards.p.PowerstoneMinefield.class));
cards.add(new SetCardInfo("Prophetic Bolt", 116, Rarity.RARE, mage.cards.p.PropheticBolt.class));
cards.add(new SetCardInfo("Putrid Warrior", 117, Rarity.COMMON, mage.cards.p.PutridWarrior.class));
cards.add(new SetCardInfo("Quagmire Druid", 51, Rarity.COMMON, mage.cards.q.QuagmireDruid.class));

View file

@ -1,11 +1,11 @@
package mage.sets;
import mage.cards.CardGraphicInfo;
import mage.cards.ExpansionSet;
import mage.cards.o.OrcishSpy;
import mage.cards.r.RukhEgg;
import mage.constants.SetType;
import mage.cards.ExpansionSet;
import mage.constants.Rarity;
import mage.cards.CardGraphicInfo;
import mage.constants.SetType;
public class EighthEdition extends ExpansionSet {
@ -100,7 +100,6 @@ public class EighthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Drudge Skeletons", 129, Rarity.COMMON, mage.cards.d.DrudgeSkeletons.class));
cards.add(new SetCardInfo("Dusk Imp", 130, Rarity.COMMON, mage.cards.d.DuskImp.class));
cards.add(new SetCardInfo("Dwarven Demolition Team", 184, Rarity.UNCOMMON, mage.cards.d.DwarvenDemolitionTeam.class));
cards.add(new SetCardInfo("Eager Cadet", 1, Rarity.COMMON, mage.cards.e.EagerCadet.class));
cards.add(new SetCardInfo("Eastern Paladin", 131, Rarity.RARE, mage.cards.e.EasternPaladin.class));
cards.add(new SetCardInfo("Elfhame Palace", 324, Rarity.UNCOMMON, mage.cards.e.ElfhamePalace.class));
cards.add(new SetCardInfo("Elite Archers", 18, Rarity.RARE, mage.cards.e.EliteArchers.class));
@ -111,7 +110,6 @@ public class EighthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Elvish Piper", 244, Rarity.RARE, mage.cards.e.ElvishPiper.class));
cards.add(new SetCardInfo("Elvish Scrapper", 245, Rarity.UNCOMMON, mage.cards.e.ElvishScrapper.class));
cards.add(new SetCardInfo("Emperor Crocodile", 246, Rarity.RARE, mage.cards.e.EmperorCrocodile.class));
cards.add(new SetCardInfo("Enormous Baloth", 6, Rarity.UNCOMMON, mage.cards.e.EnormousBaloth.class));
cards.add(new SetCardInfo("Enrage", 185, Rarity.UNCOMMON, mage.cards.e.Enrage.class));
cards.add(new SetCardInfo("Ensnaring Bridge", 300, Rarity.RARE, mage.cards.e.EnsnaringBridge.class));
cards.add(new SetCardInfo("Evacuation", 76, Rarity.RARE, mage.cards.e.Evacuation.class));
@ -282,7 +280,6 @@ public class EighthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Sanctimony", 42, Rarity.UNCOMMON, mage.cards.s.Sanctimony.class));
cards.add(new SetCardInfo("Savannah Lions", 43, Rarity.RARE, mage.cards.s.SavannahLions.class));
cards.add(new SetCardInfo("Scathe Zombies", 160, Rarity.COMMON, mage.cards.s.ScatheZombies.class));
cards.add(new SetCardInfo("Sea Eagle", 4, Rarity.COMMON, mage.cards.s.SeaEagle.class));
cards.add(new SetCardInfo("Sea Monster", 99, Rarity.COMMON, mage.cards.s.SeaMonster.class));
cards.add(new SetCardInfo("Searing Wind", 218, Rarity.RARE, mage.cards.s.SearingWind.class));
cards.add(new SetCardInfo("Seasoned Marshal", 44, Rarity.UNCOMMON, mage.cards.s.SeasonedMarshal.class));
@ -297,7 +294,6 @@ public class EighthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Shivan Oasis", 326, Rarity.UNCOMMON, mage.cards.s.ShivanOasis.class));
cards.add(new SetCardInfo("Shock", 222, Rarity.COMMON, mage.cards.s.Shock.class));
cards.add(new SetCardInfo("Shock Troops", 223, Rarity.COMMON, mage.cards.s.ShockTroops.class));
cards.add(new SetCardInfo("Silverback Ape", 7, Rarity.UNCOMMON, mage.cards.s.SilverbackApe.class));
cards.add(new SetCardInfo("Sizzle", 224, Rarity.COMMON, mage.cards.s.Sizzle.class));
cards.add(new SetCardInfo("Skull of Orm", 313, Rarity.RARE, mage.cards.s.SkullOfOrm.class));
cards.add(new SetCardInfo("Slay", 164, Rarity.UNCOMMON, mage.cards.s.Slay.class));
@ -352,14 +348,12 @@ public class EighthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Urza's Power Plant", 329, Rarity.COMMON, mage.cards.u.UrzasPowerPlant.class));
cards.add(new SetCardInfo("Urza's Tower", 330, Rarity.COMMON, mage.cards.u.UrzasTower.class));
cards.add(new SetCardInfo("Vampiric Spirit", 170, Rarity.RARE, mage.cards.v.VampiricSpirit.class));
cards.add(new SetCardInfo("Venerable Monk", 55, Rarity.COMMON, mage.cards.v.VenerableMonk.class));
cards.add(new SetCardInfo("Vengeance", 2, Rarity.UNCOMMON, mage.cards.v.Vengeance.class));
cards.add(new SetCardInfo("Venerable Monk", 55, Rarity.COMMON, mage.cards.v.VenerableMonk.class));
cards.add(new SetCardInfo("Verduran Enchantress", 285, Rarity.RARE, mage.cards.v.VerduranEnchantress.class));
cards.add(new SetCardInfo("Vernal Bloom", 286, Rarity.RARE, mage.cards.v.VernalBloom.class));
cards.add(new SetCardInfo("Viashino Sandstalker", 230, Rarity.UNCOMMON, mage.cards.v.ViashinoSandstalker.class));
cards.add(new SetCardInfo("Vicious Hunger", 171, Rarity.COMMON, mage.cards.v.ViciousHunger.class));
cards.add(new SetCardInfo("Vine Trellis", 287, Rarity.COMMON, mage.cards.v.VineTrellis.class));
cards.add(new SetCardInfo("Vizzerdrix", 5, Rarity.RARE, mage.cards.v.Vizzerdrix.class));
cards.add(new SetCardInfo("Volcanic Hammer", 231, Rarity.COMMON, mage.cards.v.VolcanicHammer.class));
cards.add(new SetCardInfo("Wall of Air", 113, Rarity.UNCOMMON, mage.cards.w.WallOfAir.class));
cards.add(new SetCardInfo("Wall of Spears", 320, Rarity.UNCOMMON, mage.cards.w.WallOfSpears.class));
@ -377,6 +371,14 @@ public class EighthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Yavimaya Enchantress", 290, Rarity.UNCOMMON, mage.cards.y.YavimayaEnchantress.class));
cards.add(new SetCardInfo("Zombify", 174, Rarity.UNCOMMON, mage.cards.z.Zombify.class));
cards.add(new SetCardInfo("Zur's Weirding", 116, Rarity.RARE, mage.cards.z.ZursWeirding.class));
// 8ed Edition Box Set (we need to create own set)
// cards.add(new SetCardInfo("Eager Cadet", 1, Rarity.COMMON, mage.cards.e.EagerCadet.class));
// cards.add(new SetCardInfo("Vengeance", 2, Rarity.UNCOMMON, mage.cards.v.Vengeance.class));
// cards.add(new SetCardInfo("Sea Eagle", 4, Rarity.COMMON, mage.cards.s.SeaEagle.class));
// cards.add(new SetCardInfo("Vizzerdrix", 5, Rarity.RARE, mage.cards.v.Vizzerdrix.class));
// cards.add(new SetCardInfo("Enormous Baloth", 6, Rarity.UNCOMMON, mage.cards.e.EnormousBaloth.class));
// cards.add(new SetCardInfo("Silverback Ape", 7, Rarity.UNCOMMON, mage.cards.s.SilverbackApe.class));
}
}

View file

@ -254,6 +254,7 @@ public class FourthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Mind Twist", 31, Rarity.RARE, mage.cards.m.MindTwist.class));
cards.add(new SetCardInfo("Mishra's Factory", 181, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class));
cards.add(new SetCardInfo("Mons's Goblin Raiders", 231, Rarity.COMMON, mage.cards.m.MonssGoblinRaiders.class));
cards.add(new SetCardInfo("Morale", 288, Rarity.COMMON, mage.cards.m.Morale.class));
cards.add(new SetCardInfo("Mountain", 182, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Mountain", 183, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Mountain", 184, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true)));
@ -325,6 +326,7 @@ public class FourthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Soul Net", 364, Rarity.UNCOMMON, mage.cards.s.SoulNet.class));
cards.add(new SetCardInfo("Spell Blast", 103, Rarity.COMMON, mage.cards.s.SpellBlast.class));
cards.add(new SetCardInfo("Spirit Link", 301, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class));
cards.add(new SetCardInfo("Spirit Shackle", 47, Rarity.UNCOMMON, mage.cards.s.SpiritShackle.class));
cards.add(new SetCardInfo("Stasis", 104, Rarity.RARE, mage.cards.s.Stasis.class));
cards.add(new SetCardInfo("Steal Artifact", 105, Rarity.UNCOMMON, mage.cards.s.StealArtifact.class));
cards.add(new SetCardInfo("Stone Giant", 241, Rarity.UNCOMMON, mage.cards.s.StoneGiant.class));

View file

@ -52,6 +52,7 @@ public class FridayNightMagic extends ExpansionSet {
cards.add(new SetCardInfo("Abzan Beastmaster", 180, Rarity.UNCOMMON, mage.cards.a.AbzanBeastmaster.class));
cards.add(new SetCardInfo("Accumulated Knowledge", 51, Rarity.COMMON, mage.cards.a.AccumulatedKnowledge.class));
cards.add(new SetCardInfo("Acidic Slime", 145, Rarity.UNCOMMON, mage.cards.a.AcidicSlime.class));
cards.add(new SetCardInfo("Aether Hub", 205, Rarity.SPECIAL, mage.cards.a.AetherHub.class));
cards.add(new SetCardInfo("Albino Troll", 20, Rarity.UNCOMMON, mage.cards.a.AlbinoTroll.class));
cards.add(new SetCardInfo("Anathemancer", 122, Rarity.UNCOMMON, mage.cards.a.Anathemancer.class));
cards.add(new SetCardInfo("Ancient Grudge", 144, Rarity.COMMON, mage.cards.a.AncientGrudge.class));
@ -206,6 +207,7 @@ public class FridayNightMagic extends ExpansionSet {
cards.add(new SetCardInfo("Searing Spear", 152, Rarity.COMMON, mage.cards.s.SearingSpear.class));
cards.add(new SetCardInfo("Serrated Arrows", 101, Rarity.UNCOMMON, mage.cards.s.SerratedArrows.class));
cards.add(new SetCardInfo("Serum Visions", 183, Rarity.COMMON, mage.cards.s.SerumVisions.class));
cards.add(new SetCardInfo("Servo Exhibition", 203, Rarity.SPECIAL, mage.cards.s.ServoExhibition.class));
cards.add(new SetCardInfo("Shock", 6, Rarity.COMMON, mage.cards.s.Shock.class));
cards.add(new SetCardInfo("Shrapnel Blast", 103, Rarity.UNCOMMON, mage.cards.s.ShrapnelBlast.class));
cards.add(new SetCardInfo("Silver Knight", 46, Rarity.UNCOMMON, mage.cards.s.SilverKnight.class));
@ -236,6 +238,7 @@ public class FridayNightMagic extends ExpansionSet {
cards.add(new SetCardInfo("Tormod's Crypt", 93, Rarity.UNCOMMON, mage.cards.t.TormodsCrypt.class));
cards.add(new SetCardInfo("Treetop Village", 50, Rarity.UNCOMMON, mage.cards.t.TreetopVillage.class));
cards.add(new SetCardInfo("Ultimate Price", 185, Rarity.UNCOMMON, mage.cards.u.UltimatePrice.class));
cards.add(new SetCardInfo("Unlicensed Disintegration", 204, Rarity.SPECIAL, mage.cards.u.UnlicensedDisintegration.class));
cards.add(new SetCardInfo("Volcanic Geyser", 4, Rarity.UNCOMMON, mage.cards.v.VolcanicGeyser.class));
cards.add(new SetCardInfo("Wall of Blossoms", 23, Rarity.UNCOMMON, mage.cards.w.WallOfBlossoms.class));
cards.add(new SetCardInfo("Wall of Omens", 130, Rarity.UNCOMMON, mage.cards.w.WallOfOmens.class));

View file

@ -146,6 +146,7 @@ public class FutureSight extends ExpansionSet {
cards.add(new SetCardInfo("Minions' Murmurs", 71, Rarity.UNCOMMON, mage.cards.m.MinionsMurmurs.class));
cards.add(new SetCardInfo("Mistmeadow Skulk", 27, Rarity.UNCOMMON, mage.cards.m.MistmeadowSkulk.class));
cards.add(new SetCardInfo("Molten Disaster", 102, Rarity.RARE, mage.cards.m.MoltenDisaster.class));
cards.add(new SetCardInfo("Muraganda Petroglyphs", 146, Rarity.RARE, mage.cards.m.MuragandaPetroglyphs.class));
cards.add(new SetCardInfo("Mystic Speculation", 41, Rarity.UNCOMMON, mage.cards.m.MysticSpeculation.class));
cards.add(new SetCardInfo("Nacatl War-Pride", 147, Rarity.UNCOMMON, mage.cards.n.NacatlWarPride.class));
cards.add(new SetCardInfo("Narcomoeba", 54, Rarity.UNCOMMON, mage.cards.n.Narcomoeba.class));

View file

@ -115,6 +115,7 @@ public class Homelands extends ExpansionSet {
cards.add(new SetCardInfo("Folk of An-Havva", 58, Rarity.COMMON, FolkOfAnHavva.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Folk of An-Havva", 59, Rarity.COMMON, FolkOfAnHavva.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Forget", 32, Rarity.RARE, mage.cards.f.Forget.class));
cards.add(new SetCardInfo("Ghost Hounds", 12, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class));
cards.add(new SetCardInfo("Grandmother Sengir", 13, Rarity.RARE, mage.cards.g.GrandmotherSengir.class));
cards.add(new SetCardInfo("Headstone", 15, Rarity.COMMON, mage.cards.h.Headstone.class));
cards.add(new SetCardInfo("Hungry Mist", 60, Rarity.COMMON, mage.cards.h.HungryMist.class, new CardGraphicInfo(null, true)));

View file

@ -277,6 +277,7 @@ public class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Veldt", 358, Rarity.RARE, mage.cards.v.Veldt.class));
cards.add(new SetCardInfo("Vertigo", 222, Rarity.UNCOMMON, mage.cards.v.Vertigo.class));
cards.add(new SetCardInfo("Walking Wall", 321, Rarity.UNCOMMON, mage.cards.w.WalkingWall.class));
cards.add(new SetCardInfo("Wall of Lava", 223, Rarity.UNCOMMON, mage.cards.w.WallOfLava.class));
cards.add(new SetCardInfo("Wall of Pine Needles", 162, Rarity.UNCOMMON, mage.cards.w.WallOfPineNeedles.class));
cards.add(new SetCardInfo("War Chariot", 323, Rarity.UNCOMMON, mage.cards.w.WarChariot.class));
cards.add(new SetCardInfo("Warning", 279, Rarity.COMMON, mage.cards.w.Warning.class));

View file

@ -24,14 +24,13 @@
* 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 mage.constants.SetType;
import mage.cards.CardGraphicInfo;
import mage.cards.ExpansionSet;
import mage.constants.Rarity;
import mage.cards.CardGraphicInfo;
import mage.constants.SetType;
/**
*
@ -50,14 +49,14 @@ public class JudgePromo extends ExpansionSet {
this.hasBoosters = false;
cards.add(new SetCardInfo("Argothian Enchantress", 12, Rarity.RARE, mage.cards.a.ArgothianEnchantress.class));
cards.add(new SetCardInfo("Armageddon", 14, Rarity.RARE, mage.cards.a.Armageddon.class));
cards.add(new SetCardInfo("Azusa, Lost but Seeking", 102, Rarity.RARE, mage.cards.a.AzusaLostButSeeking.class));
cards.add(new SetCardInfo("Azusa, Lost but Seeking", 102, Rarity.RARE, mage.cards.a.AzusaLostButSeeking.class));// 2016 003/008
cards.add(new SetCardInfo("Balance", 15, Rarity.RARE, mage.cards.b.Balance.class));
cards.add(new SetCardInfo("Ball Lightning", 7, Rarity.RARE, mage.cards.b.BallLightning.class));
cards.add(new SetCardInfo("Bitterblossom", 59, Rarity.RARE, mage.cards.b.Bitterblossom.class));
cards.add(new SetCardInfo("Bloodstained Mire", 43, Rarity.RARE, mage.cards.b.BloodstainedMire.class));
cards.add(new SetCardInfo("Bribery", 73, Rarity.RARE, mage.cards.b.Bribery.class));
cards.add(new SetCardInfo("Burning Wish", 42, Rarity.RARE, mage.cards.b.BurningWish.class));
cards.add(new SetCardInfo("Command Beacon", 105, Rarity.RARE, mage.cards.c.CommandBeacon.class));
cards.add(new SetCardInfo("Command Beacon", 105, Rarity.RARE, mage.cards.c.CommandBeacon.class));// 2016 004/008
cards.add(new SetCardInfo("Command Tower", 71, Rarity.COMMON, mage.cards.c.CommandTower.class));
cards.add(new SetCardInfo("Counterspell", 5, Rarity.COMMON, mage.cards.c.Counterspell.class));
cards.add(new SetCardInfo("Crucible of Worlds", 75, Rarity.RARE, mage.cards.c.CrucibleOfWorlds.class));
@ -66,7 +65,7 @@ public class JudgePromo extends ExpansionSet {
cards.add(new SetCardInfo("Dark Confidant", 61, Rarity.RARE, mage.cards.d.DarkConfidant.class));
cards.add(new SetCardInfo("Dark Ritual", 38, Rarity.COMMON, mage.cards.d.DarkRitual.class));
cards.add(new SetCardInfo("Decree of Justice", 32, Rarity.RARE, mage.cards.d.DecreeOfJustice.class));
cards.add(new SetCardInfo("Defense of the Heart", 106, Rarity.RARE, mage.cards.d.DefenseOfTheHeart.class));
cards.add(new SetCardInfo("Defense of the Heart", 106, Rarity.RARE, mage.cards.d.DefenseOfTheHeart.class)); // 2016 007/008
cards.add(new SetCardInfo("Demonic Tutor", 35, Rarity.UNCOMMON, mage.cards.d.DemonicTutor.class));
cards.add(new SetCardInfo("Deranged Hermit", 18, Rarity.RARE, mage.cards.d.DerangedHermit.class));
cards.add(new SetCardInfo("Doubling Season", 62, Rarity.RARE, mage.cards.d.DoublingSeason.class));
@ -91,7 +90,7 @@ public class JudgePromo extends ExpansionSet {
cards.add(new SetCardInfo("Hanna, Ship's Navigator", 84, Rarity.RARE, mage.cards.h.HannaShipsNavigator.class));
cards.add(new SetCardInfo("Hermit Druid", 19, Rarity.RARE, mage.cards.h.HermitDruid.class));
cards.add(new SetCardInfo("Imperial Recruiter", 74, Rarity.UNCOMMON, mage.cards.i.ImperialRecruiter.class));
cards.add(new SetCardInfo("Imperial Seal", 109, Rarity.SPECIAL, mage.cards.i.ImperialSeal.class));
cards.add(new SetCardInfo("Imperial Seal", 109, Rarity.SPECIAL, mage.cards.i.ImperialSeal.class));// 2016 006/008
cards.add(new SetCardInfo("Intuition", 11, Rarity.RARE, mage.cards.i.Intuition.class));
cards.add(new SetCardInfo("Island", 90, Rarity.LAND, mage.cards.basiclands.Island.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Karador, Ghost Chieftain", 80, Rarity.MYTHIC, mage.cards.k.KaradorGhostChieftain.class));
@ -102,7 +101,7 @@ public class JudgePromo extends ExpansionSet {
cards.add(new SetCardInfo("Living Death", 13, Rarity.RARE, mage.cards.l.LivingDeath.class));
cards.add(new SetCardInfo("Living Wish", 37, Rarity.RARE, mage.cards.l.LivingWish.class));
cards.add(new SetCardInfo("Mana Crypt", 60, Rarity.RARE, mage.cards.m.ManaCrypt.class));
cards.add(new SetCardInfo("Mana Drain", 103, Rarity.UNCOMMON, mage.cards.m.ManaDrain.class));
cards.add(new SetCardInfo("Mana Drain", 103, Rarity.UNCOMMON, mage.cards.m.ManaDrain.class));// 2016 002/008
cards.add(new SetCardInfo("Maze of Ith", 39, Rarity.UNCOMMON, mage.cards.m.MazeOfIth.class));
cards.add(new SetCardInfo("Meddling Mage", 26, Rarity.RARE, mage.cards.m.MeddlingMage.class));
cards.add(new SetCardInfo("Memory Lapse", 4, Rarity.COMMON, mage.cards.m.MemoryLapse.class));
@ -110,7 +109,7 @@ public class JudgePromo extends ExpansionSet {
cards.add(new SetCardInfo("Mishra's Factory", 23, Rarity.UNCOMMON, mage.cards.m.MishrasFactory.class));
cards.add(new SetCardInfo("Morphling", 53, Rarity.RARE, mage.cards.m.Morphling.class));
cards.add(new SetCardInfo("Mountain", 92, Rarity.LAND, mage.cards.basiclands.Mountain.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Mystic Confluence", 109, Rarity.SPECIAL, mage.cards.m.MysticConfluence.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Mystic Confluence", 108, Rarity.SPECIAL, mage.cards.m.MysticConfluence.class, new CardGraphicInfo(null, true))); // 2016 005/008
cards.add(new SetCardInfo("Natural Order", 49, Rarity.RARE, mage.cards.n.NaturalOrder.class));
cards.add(new SetCardInfo("Nekusar, the Mindrazer", 86, Rarity.MYTHIC, mage.cards.n.NekusarTheMindrazer.class));
cards.add(new SetCardInfo("Noble Hierarch", 66, Rarity.RARE, mage.cards.n.NobleHierarch.class));
@ -155,7 +154,7 @@ public class JudgePromo extends ExpansionSet {
cards.add(new SetCardInfo("Wooded Foothills", 47, Rarity.RARE, mage.cards.w.WoodedFoothills.class));
cards.add(new SetCardInfo("Xiahou Dun, the One-Eyed", 64, Rarity.RARE, mage.cards.x.XiahouDunTheOneEyed.class));
cards.add(new SetCardInfo("Yawgmoth's Will", 30, Rarity.RARE, mage.cards.y.YawgmothsWill.class));
cards.add(new SetCardInfo("Zur the Enchanter", 107, Rarity.RARE, mage.cards.z.ZurTheEnchanter.class));
cards.add(new SetCardInfo("Zur the Enchanter", 107, Rarity.RARE, mage.cards.z.ZurTheEnchanter.class)); // 2016 008/008
}
}
}

View file

@ -204,6 +204,7 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Sol'kanar the Swamp King", 299, Rarity.RARE, mage.cards.s.SolkanarTheSwampKing.class));
cards.add(new SetCardInfo("Spinal Villain", 161, Rarity.RARE, mage.cards.s.SpinalVillain.class));
cards.add(new SetCardInfo("Spirit Link", 206, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class));
cards.add(new SetCardInfo("Spirit Shackle", 31, Rarity.COMMON, mage.cards.s.SpiritShackle.class));
cards.add(new SetCardInfo("Storm Seeker", 119, Rarity.UNCOMMON, mage.cards.s.StormSeeker.class));
cards.add(new SetCardInfo("Sunastian Falconer", 301, Rarity.UNCOMMON, mage.cards.s.SunastianFalconer.class));
cards.add(new SetCardInfo("Sylvan Library", 121, Rarity.UNCOMMON, mage.cards.s.SylvanLibrary.class));
@ -233,7 +234,7 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Wall of Earth", 166, Rarity.COMMON, mage.cards.w.WallOfEarth.class));
cards.add(new SetCardInfo("Wall of Heat", 167, Rarity.COMMON, mage.cards.w.WallOfHeat.class));
cards.add(new SetCardInfo("Wall of Light", 212, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class));
cards.add(new SetCardInfo("Wall of Putrid Flesh", 41, Rarity.UNCOMMON, mage.cards.w.WallOfPutridFlesh.class));
cards.add(new SetCardInfo("Wall of Putrid Flesh", 41, Rarity.UNCOMMON, mage.cards.w.WallOfPutridFlesh.class));
cards.add(new SetCardInfo("Wall of Wonder", 85, Rarity.UNCOMMON, mage.cards.w.WallOfWonder.class));
cards.add(new SetCardInfo("Whirling Dervish", 125, Rarity.UNCOMMON, mage.cards.w.WhirlingDervish.class));
cards.add(new SetCardInfo("Willow Satyr", 126, Rarity.RARE, mage.cards.w.WillowSatyr.class));

View file

@ -27,11 +27,14 @@
*/
package mage.sets;
import mage.cards.CardGraphicInfo;
import mage.cards.ExpansionSet;
import mage.constants.SetType;
import mage.cards.FrameStyle;
import mage.constants.Rarity;
import mage.constants.SetType;
public class MagicPlayerRewards extends ExpansionSet {
private static final MagicPlayerRewards fINSTANCE = new MagicPlayerRewards();
public static MagicPlayerRewards getInstance() {
@ -42,58 +45,59 @@ public class MagicPlayerRewards extends ExpansionSet {
super("Magic Player Rewards", "MPRP", ExpansionSet.buildDate(1990, 1, 1), SetType.PROMOTIONAL);
this.hasBoosters = false;
this.hasBasicLands = false;
cards.add(new SetCardInfo("Bituminous Blast", 46, Rarity.SPECIAL, mage.cards.b.BituminousBlast.class));
cards.add(new SetCardInfo("Blightning", 36, Rarity.SPECIAL, mage.cards.b.Blightning.class));
cards.add(new SetCardInfo("Brave the Elements", 50, Rarity.SPECIAL, mage.cards.b.BraveTheElements.class));
cards.add(new SetCardInfo("Burst Lightning", 47, Rarity.SPECIAL, mage.cards.b.BurstLightning.class));
cards.add(new SetCardInfo("Cancel", 41, Rarity.SPECIAL, mage.cards.c.Cancel.class));
cards.add(new SetCardInfo("Celestial Purge", 45, Rarity.SPECIAL, mage.cards.c.CelestialPurge.class));
cards.add(new SetCardInfo("Condemn", 18, Rarity.SPECIAL, mage.cards.c.Condemn.class));
cards.add(new SetCardInfo("Corrupt", 30, Rarity.SPECIAL, mage.cards.c.Corrupt.class));
cards.add(new SetCardInfo("Cruel Edict", 21, Rarity.SPECIAL, mage.cards.c.CruelEdict.class));
cards.add(new SetCardInfo("Cryptic Command", 31, Rarity.SPECIAL, mage.cards.c.CrypticCommand.class));
cards.add(new SetCardInfo("Damnation", 24, Rarity.SPECIAL, mage.cards.d.Damnation.class));
cards.add(new SetCardInfo("Day of Judgment", 49, Rarity.SPECIAL, mage.cards.d.DayOfJudgment.class));
cards.add(new SetCardInfo("Disenchant", 22, Rarity.SPECIAL, mage.cards.d.Disenchant.class));
cards.add(new SetCardInfo("Doom Blade", 51, Rarity.SPECIAL, mage.cards.d.DoomBlade.class));
cards.add(new SetCardInfo("Fireball", 6, Rarity.SPECIAL, mage.cards.f.Fireball.class));
cards.add(new SetCardInfo("Flame Javelin", 32, Rarity.SPECIAL, mage.cards.f.FlameJavelin.class));
cards.add(new SetCardInfo("Giant Growth", 13, Rarity.SPECIAL, mage.cards.g.GiantGrowth.class));
cards.add(new SetCardInfo("Harmonize", 28, Rarity.SPECIAL, mage.cards.h.Harmonize.class));
cards.add(new SetCardInfo("Harrow", 48, Rarity.SPECIAL, mage.cards.h.Harrow.class));
cards.add(new SetCardInfo("Hinder", 11, Rarity.SPECIAL, mage.cards.h.Hinder.class));
CardGraphicInfo graphicInfo = new CardGraphicInfo(FrameStyle.MPRP_FULL_ART_BASIC, false);
cards.add(new SetCardInfo("Bituminous Blast", 46, Rarity.SPECIAL, mage.cards.b.BituminousBlast.class, graphicInfo));
cards.add(new SetCardInfo("Blightning", 36, Rarity.SPECIAL, mage.cards.b.Blightning.class, graphicInfo));
cards.add(new SetCardInfo("Brave the Elements", 50, Rarity.SPECIAL, mage.cards.b.BraveTheElements.class, graphicInfo));
cards.add(new SetCardInfo("Burst Lightning", 47, Rarity.SPECIAL, mage.cards.b.BurstLightning.class, graphicInfo));
cards.add(new SetCardInfo("Cancel", 41, Rarity.SPECIAL, mage.cards.c.Cancel.class, graphicInfo));
cards.add(new SetCardInfo("Celestial Purge", 45, Rarity.SPECIAL, mage.cards.c.CelestialPurge.class, graphicInfo));
cards.add(new SetCardInfo("Condemn", 18, Rarity.SPECIAL, mage.cards.c.Condemn.class, graphicInfo));
cards.add(new SetCardInfo("Corrupt", 30, Rarity.SPECIAL, mage.cards.c.Corrupt.class, graphicInfo));
cards.add(new SetCardInfo("Cruel Edict", 21, Rarity.SPECIAL, mage.cards.c.CruelEdict.class, graphicInfo));
cards.add(new SetCardInfo("Cryptic Command", 31, Rarity.SPECIAL, mage.cards.c.CrypticCommand.class, graphicInfo));
cards.add(new SetCardInfo("Damnation", 24, Rarity.SPECIAL, mage.cards.d.Damnation.class, graphicInfo));
cards.add(new SetCardInfo("Day of Judgment", 49, Rarity.SPECIAL, mage.cards.d.DayOfJudgment.class, graphicInfo));
cards.add(new SetCardInfo("Disenchant", 22, Rarity.SPECIAL, mage.cards.d.Disenchant.class, graphicInfo));
cards.add(new SetCardInfo("Doom Blade", 51, Rarity.SPECIAL, mage.cards.d.DoomBlade.class, graphicInfo));
cards.add(new SetCardInfo("Fireball", 6, Rarity.SPECIAL, mage.cards.f.Fireball.class, graphicInfo));
cards.add(new SetCardInfo("Flame Javelin", 32, Rarity.SPECIAL, mage.cards.f.FlameJavelin.class, graphicInfo));
cards.add(new SetCardInfo("Giant Growth", 13, Rarity.SPECIAL, mage.cards.g.GiantGrowth.class, graphicInfo));
cards.add(new SetCardInfo("Harmonize", 28, Rarity.SPECIAL, mage.cards.h.Harmonize.class, graphicInfo));
cards.add(new SetCardInfo("Harrow", 48, Rarity.SPECIAL, mage.cards.h.Harrow.class, graphicInfo));
cards.add(new SetCardInfo("Hinder", 11, Rarity.SPECIAL, mage.cards.h.Hinder.class, graphicInfo));
cards.add(new SetCardInfo("Hypnotic Specter", 10, Rarity.SPECIAL, mage.cards.h.HypnoticSpecter.class));
cards.add(new SetCardInfo("Incinerate", 26, Rarity.SPECIAL, mage.cards.i.Incinerate.class));
cards.add(new SetCardInfo("Infest", 43, Rarity.SPECIAL, mage.cards.i.Infest.class));
cards.add(new SetCardInfo("Lightning Bolt", 40, Rarity.SPECIAL, mage.cards.l.LightningBolt.class));
cards.add(new SetCardInfo("Lightning Helix", 16, Rarity.SPECIAL, mage.cards.l.LightningHelix.class));
cards.add(new SetCardInfo("Mana Leak", 8, Rarity.SPECIAL, mage.cards.m.ManaLeak.class));
cards.add(new SetCardInfo("Mana Tithe", 27, Rarity.SPECIAL, mage.cards.m.ManaTithe.class));
cards.add(new SetCardInfo("Mortify", 19, Rarity.SPECIAL, mage.cards.m.Mortify.class));
cards.add(new SetCardInfo("Nameless Inversion", 34, Rarity.SPECIAL, mage.cards.n.NamelessInversion.class));
cards.add(new SetCardInfo("Negate", 38, Rarity.SPECIAL, mage.cards.n.Negate.class));
cards.add(new SetCardInfo("Oxidize", 7, Rarity.SPECIAL, mage.cards.o.Oxidize.class));
cards.add(new SetCardInfo("Ponder", 29, Rarity.SPECIAL, mage.cards.p.Ponder.class));
cards.add(new SetCardInfo("Incinerate", 26, Rarity.SPECIAL, mage.cards.i.Incinerate.class, graphicInfo));
cards.add(new SetCardInfo("Infest", 43, Rarity.SPECIAL, mage.cards.i.Infest.class, graphicInfo));
cards.add(new SetCardInfo("Lightning Bolt", 40, Rarity.SPECIAL, mage.cards.l.LightningBolt.class, graphicInfo));
cards.add(new SetCardInfo("Lightning Helix", 16, Rarity.SPECIAL, mage.cards.l.LightningHelix.class, graphicInfo));
cards.add(new SetCardInfo("Mana Leak", 8, Rarity.SPECIAL, mage.cards.m.ManaLeak.class, graphicInfo));
cards.add(new SetCardInfo("Mana Tithe", 27, Rarity.SPECIAL, mage.cards.m.ManaTithe.class, graphicInfo));
cards.add(new SetCardInfo("Mortify", 19, Rarity.SPECIAL, mage.cards.m.Mortify.class, graphicInfo));
cards.add(new SetCardInfo("Nameless Inversion", 34, Rarity.SPECIAL, mage.cards.n.NamelessInversion.class, graphicInfo));
cards.add(new SetCardInfo("Negate", 38, Rarity.SPECIAL, mage.cards.n.Negate.class, graphicInfo));
cards.add(new SetCardInfo("Oxidize", 7, Rarity.SPECIAL, mage.cards.o.Oxidize.class, graphicInfo));
cards.add(new SetCardInfo("Ponder", 29, Rarity.SPECIAL, mage.cards.p.Ponder.class, graphicInfo));
cards.add(new SetCardInfo("Powder Keg", 3, Rarity.SPECIAL, mage.cards.p.PowderKeg.class));
cards.add(new SetCardInfo("Psionic Blast", 20, Rarity.COMMON, mage.cards.p.PsionicBlast.class));
cards.add(new SetCardInfo("Psionic Blast", 20, Rarity.SPECIAL, mage.cards.p.PsionicBlast.class, graphicInfo));
cards.add(new SetCardInfo("Psychatog", 4, Rarity.SPECIAL, mage.cards.p.Psychatog.class));
cards.add(new SetCardInfo("Putrefy", 14, Rarity.SPECIAL, mage.cards.p.Putrefy.class));
cards.add(new SetCardInfo("Pyroclasm", 12, Rarity.SPECIAL, mage.cards.p.Pyroclasm.class));
cards.add(new SetCardInfo("Rampant Growth", 37, Rarity.SPECIAL, mage.cards.r.RampantGrowth.class));
cards.add(new SetCardInfo("Reciprocate", 9, Rarity.SPECIAL, mage.cards.r.Reciprocate.class));
cards.add(new SetCardInfo("Recollect", 23, Rarity.SPECIAL, mage.cards.r.Recollect.class));
cards.add(new SetCardInfo("Remove Soul", 35, Rarity.SPECIAL, mage.cards.r.RemoveSoul.class));
cards.add(new SetCardInfo("Searing Blaze", 53, Rarity.SPECIAL, mage.cards.s.SearingBlaze.class));
cards.add(new SetCardInfo("Sign in Blood", 42, Rarity.SPECIAL, mage.cards.s.SignInBlood.class));
cards.add(new SetCardInfo("Terminate", 39, Rarity.SPECIAL, mage.cards.t.Terminate.class));
cards.add(new SetCardInfo("Terror", 5, Rarity.SPECIAL, mage.cards.t.Terror.class));
cards.add(new SetCardInfo("Tidings", 25, Rarity.SPECIAL, mage.cards.t.Tidings.class));
cards.add(new SetCardInfo("Treasure Hunt", 52, Rarity.SPECIAL, mage.cards.t.TreasureHunt.class));
cards.add(new SetCardInfo("Unmake", 33, Rarity.SPECIAL, mage.cards.u.Unmake.class));
cards.add(new SetCardInfo("Putrefy", 14, Rarity.SPECIAL, mage.cards.p.Putrefy.class, graphicInfo));
cards.add(new SetCardInfo("Pyroclasm", 12, Rarity.SPECIAL, mage.cards.p.Pyroclasm.class, graphicInfo));
cards.add(new SetCardInfo("Rampant Growth", 37, Rarity.SPECIAL, mage.cards.r.RampantGrowth.class, graphicInfo));
cards.add(new SetCardInfo("Reciprocate", 9, Rarity.SPECIAL, mage.cards.r.Reciprocate.class, graphicInfo));
cards.add(new SetCardInfo("Recollect", 23, Rarity.SPECIAL, mage.cards.r.Recollect.class, graphicInfo));
cards.add(new SetCardInfo("Remove Soul", 35, Rarity.SPECIAL, mage.cards.r.RemoveSoul.class, graphicInfo));
cards.add(new SetCardInfo("Searing Blaze", 53, Rarity.SPECIAL, mage.cards.s.SearingBlaze.class, graphicInfo));
cards.add(new SetCardInfo("Sign in Blood", 42, Rarity.SPECIAL, mage.cards.s.SignInBlood.class, graphicInfo));
cards.add(new SetCardInfo("Terminate", 39, Rarity.SPECIAL, mage.cards.t.Terminate.class, graphicInfo));
cards.add(new SetCardInfo("Terror", 5, Rarity.SPECIAL, mage.cards.t.Terror.class, graphicInfo));
cards.add(new SetCardInfo("Tidings", 25, Rarity.SPECIAL, mage.cards.t.Tidings.class, graphicInfo));
cards.add(new SetCardInfo("Treasure Hunt", 52, Rarity.SPECIAL, mage.cards.t.TreasureHunt.class, graphicInfo));
cards.add(new SetCardInfo("Unmake", 33, Rarity.SPECIAL, mage.cards.u.Unmake.class, graphicInfo));
cards.add(new SetCardInfo("Voidmage Prodigy", 2, Rarity.SPECIAL, mage.cards.v.VoidmageProdigy.class));
cards.add(new SetCardInfo("Volcanic Fallout", 44, Rarity.SPECIAL, mage.cards.v.VolcanicFallout.class));
cards.add(new SetCardInfo("Wasteland", 1, Rarity.SPECIAL, mage.cards.w.Wasteland.class));
cards.add(new SetCardInfo("Wrath of God", 17, Rarity.SPECIAL, mage.cards.w.WrathOfGod.class));
cards.add(new SetCardInfo("Zombify", 15, Rarity.SPECIAL, mage.cards.z.Zombify.class));
cards.add(new SetCardInfo("Volcanic Fallout", 44, Rarity.SPECIAL, mage.cards.v.VolcanicFallout.class, graphicInfo));
cards.add(new SetCardInfo("Wasteland", 1, Rarity.SPECIAL, mage.cards.w.Wasteland.class, graphicInfo));
cards.add(new SetCardInfo("Wrath of God", 17, Rarity.SPECIAL, mage.cards.w.WrathOfGod.class, graphicInfo));
cards.add(new SetCardInfo("Zombify", 15, Rarity.SPECIAL, mage.cards.z.Zombify.class, graphicInfo));
}
}

View file

@ -27,11 +27,11 @@
*/
package mage.sets;
import mage.cards.ExpansionSet;
import mage.constants.SetType;
import mage.constants.Rarity;
import mage.cards.CardGraphicInfo;
import mage.cards.ExpansionSet;
import mage.cards.FrameStyle;
import mage.constants.Rarity;
import mage.constants.SetType;
/**
*
@ -49,72 +49,60 @@ public class MasterpieceSeries extends ExpansionSet {
super("Masterpiece Series", "MPS", ExpansionSet.buildDate(2016, 9, 30), SetType.PROMOTIONAL);
this.hasBoosters = false;
this.hasBasicLands = false;
cards.add(new SetCardInfo("Aether Vial", 6, Rarity.MYTHIC, mage.cards.a.AetherVial.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Arcbound Ravager", 31, Rarity.MYTHIC, mage.cards.a.ArcboundRavager.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Black Vise", 32, Rarity.MYTHIC, mage.cards.b.BlackVise.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Cataclysmic Gearhulk", 1, Rarity.MYTHIC, mage.cards.c.CataclysmicGearhulk.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Chalice of the Void", 33, Rarity.MYTHIC, mage.cards.c.ChaliceOfTheVoid.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Champion's Helm", 7, Rarity.MYTHIC, mage.cards.c.ChampionsHelm.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Chromatic Lantern", 8, Rarity.MYTHIC, mage.cards.c.ChromaticLantern.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Chrome Mox", 9, Rarity.MYTHIC, mage.cards.c.ChromeMox.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Cloudstone Curio", 10, Rarity.MYTHIC, mage.cards.c.CloudstoneCurio.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Combustible Gearhulk", 2, Rarity.MYTHIC, mage.cards.c.CombustibleGearhulk.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Crucible of Worlds", 11, Rarity.MYTHIC, mage.cards.c.CrucibleOfWorlds.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Defense Grid", 34, Rarity.MYTHIC, mage.cards.d.DefenseGrid.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Duplicant", 35, Rarity.MYTHIC, mage.cards.d.Duplicant.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Engineered Explosives", 36, Rarity.MYTHIC, mage.cards.e.EngineeredExplosives.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Ensnaring Bridge", 37, Rarity.MYTHIC, mage.cards.e.EnsnaringBridge.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Extraplanar Lens", 38, Rarity.MYTHIC, mage.cards.e.ExtraplanarLens.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Gauntlet of Power", 12, Rarity.MYTHIC, mage.cards.g.GauntletOfPower.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Grindstone", 39, Rarity.MYTHIC, mage.cards.g.Grindstone.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Hangarback Walker", 13, Rarity.MYTHIC, mage.cards.h.HangarbackWalker.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Lightning Greaves", 14, Rarity.MYTHIC, mage.cards.l.LightningGreaves.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Lotus Petal", 15, Rarity.MYTHIC, mage.cards.l.LotusPetal.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Mana Crypt", 16, Rarity.MYTHIC, mage.cards.m.ManaCrypt.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Mana Vault", 17, Rarity.MYTHIC, mage.cards.m.ManaVault.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Meekstone", 40, Rarity.MYTHIC, mage.cards.m.Meekstone.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Mind's Eye", 18, Rarity.MYTHIC, mage.cards.m.MindsEye.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Mox Opal", 19, Rarity.MYTHIC, mage.cards.m.MoxOpal.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Noxious Gearhulk", 3, Rarity.MYTHIC, mage.cards.n.NoxiousGearhulk.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Oblivion Stone", 41, Rarity.MYTHIC, mage.cards.o.OblivionStone.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Ornithopter", 42, Rarity.MYTHIC, mage.cards.o.Ornithopter.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Painter's Servant", 20, Rarity.MYTHIC, mage.cards.p.PaintersServant.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
CardGraphicInfo cardGraphicInfo = new CardGraphicInfo(FrameStyle.KLD_INVENTION, false);
cards.add(new SetCardInfo("Aether Vial", 6, Rarity.MYTHIC, mage.cards.a.AetherVial.class, cardGraphicInfo));
cards.add(new SetCardInfo("Arcbound Ravager", 31, Rarity.MYTHIC, mage.cards.a.ArcboundRavager.class, cardGraphicInfo));
cards.add(new SetCardInfo("Black Vise", 32, Rarity.MYTHIC, mage.cards.b.BlackVise.class, cardGraphicInfo));
cards.add(new SetCardInfo("Cataclysmic Gearhulk", 1, Rarity.MYTHIC, mage.cards.c.CataclysmicGearhulk.class, cardGraphicInfo));
cards.add(new SetCardInfo("Chalice of the Void", 33, Rarity.MYTHIC, mage.cards.c.ChaliceOfTheVoid.class, cardGraphicInfo));
cards.add(new SetCardInfo("Champion's Helm", 7, Rarity.MYTHIC, mage.cards.c.ChampionsHelm.class, cardGraphicInfo));
cards.add(new SetCardInfo("Chromatic Lantern", 8, Rarity.MYTHIC, mage.cards.c.ChromaticLantern.class, cardGraphicInfo));
cards.add(new SetCardInfo("Chrome Mox", 9, Rarity.MYTHIC, mage.cards.c.ChromeMox.class, cardGraphicInfo));
cards.add(new SetCardInfo("Cloudstone Curio", 10, Rarity.MYTHIC, mage.cards.c.CloudstoneCurio.class, cardGraphicInfo));
cards.add(new SetCardInfo("Combustible Gearhulk", 2, Rarity.MYTHIC, mage.cards.c.CombustibleGearhulk.class, cardGraphicInfo));
cards.add(new SetCardInfo("Crucible of Worlds", 11, Rarity.MYTHIC, mage.cards.c.CrucibleOfWorlds.class, cardGraphicInfo));
cards.add(new SetCardInfo("Defense Grid", 34, Rarity.MYTHIC, mage.cards.d.DefenseGrid.class, cardGraphicInfo));
cards.add(new SetCardInfo("Duplicant", 35, Rarity.MYTHIC, mage.cards.d.Duplicant.class, cardGraphicInfo));
cards.add(new SetCardInfo("Engineered Explosives", 36, Rarity.MYTHIC, mage.cards.e.EngineeredExplosives.class, cardGraphicInfo));
cards.add(new SetCardInfo("Ensnaring Bridge", 37, Rarity.MYTHIC, mage.cards.e.EnsnaringBridge.class, cardGraphicInfo));
cards.add(new SetCardInfo("Extraplanar Lens", 38, Rarity.MYTHIC, mage.cards.e.ExtraplanarLens.class, cardGraphicInfo));
cards.add(new SetCardInfo("Gauntlet of Power", 12, Rarity.MYTHIC, mage.cards.g.GauntletOfPower.class, cardGraphicInfo));
cards.add(new SetCardInfo("Grindstone", 39, Rarity.MYTHIC, mage.cards.g.Grindstone.class, cardGraphicInfo));
cards.add(new SetCardInfo("Hangarback Walker", 13, Rarity.MYTHIC, mage.cards.h.HangarbackWalker.class, cardGraphicInfo));
cards.add(new SetCardInfo("Lightning Greaves", 14, Rarity.MYTHIC, mage.cards.l.LightningGreaves.class, cardGraphicInfo));
cards.add(new SetCardInfo("Lotus Petal", 15, Rarity.MYTHIC, mage.cards.l.LotusPetal.class, cardGraphicInfo));
cards.add(new SetCardInfo("Mana Crypt", 16, Rarity.MYTHIC, mage.cards.m.ManaCrypt.class, cardGraphicInfo));
cards.add(new SetCardInfo("Mana Vault", 17, Rarity.MYTHIC, mage.cards.m.ManaVault.class, cardGraphicInfo));
cards.add(new SetCardInfo("Meekstone", 40, Rarity.MYTHIC, mage.cards.m.Meekstone.class, cardGraphicInfo));
cards.add(new SetCardInfo("Mind's Eye", 18, Rarity.MYTHIC, mage.cards.m.MindsEye.class, cardGraphicInfo));
cards.add(new SetCardInfo("Mox Opal", 19, Rarity.MYTHIC, mage.cards.m.MoxOpal.class, cardGraphicInfo));
cards.add(new SetCardInfo("Noxious Gearhulk", 3, Rarity.MYTHIC, mage.cards.n.NoxiousGearhulk.class, cardGraphicInfo));
cards.add(new SetCardInfo("Oblivion Stone", 41, Rarity.MYTHIC, mage.cards.o.OblivionStone.class, cardGraphicInfo));
cards.add(new SetCardInfo("Ornithopter", 42, Rarity.MYTHIC, mage.cards.o.Ornithopter.class, cardGraphicInfo));
cards.add(new SetCardInfo("Painter's Servant", 20, Rarity.MYTHIC, mage.cards.p.PaintersServant.class, cardGraphicInfo));
cards.add(new SetCardInfo("Paradox Engine", 43, Rarity.MYTHIC, mage.cards.p.ParadoxEngine.class));
cards.add(new SetCardInfo("Pithing Needle", 44, Rarity.MYTHIC, mage.cards.p.PithingNeedle.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Pithing Needle", 44, Rarity.MYTHIC, mage.cards.p.PithingNeedle.class, cardGraphicInfo));
cards.add(new SetCardInfo("Planar Bridge", 45, Rarity.MYTHIC, mage.cards.p.PlanarBridge.class));
cards.add(new SetCardInfo("Platinum Angel", 46, Rarity.MYTHIC, mage.cards.p.PlatinumAngel.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Rings of Brighthearth", 21, Rarity.MYTHIC, mage.cards.r.RingsOfBrighthearth.class, new CardGraphicInfo(
FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Scroll Rack", 22, Rarity.MYTHIC, mage.cards.s.ScrollRack.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sculpting Steel", 23, Rarity.MYTHIC, mage.cards.s.SculptingSteel.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Solemn Simulacrum", 25, Rarity.MYTHIC, mage.cards.s.SolemnSimulacrum.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Sol Ring", 24, Rarity.MYTHIC, mage.cards.s.SolRing.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sphere of Resistance", 47, Rarity.MYTHIC, mage.cards.s.SphereOfResistance.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Staff of Domination", 48, Rarity.MYTHIC, mage.cards.s.StaffOfDomination.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Static Orb", 26, Rarity.MYTHIC, mage.cards.s.StaticOrb.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Steel Overseer", 27, Rarity.MYTHIC, mage.cards.s.SteelOverseer.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sundering Titan", 49, Rarity.MYTHIC, mage.cards.s.SunderingTitan.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sword of Body and Mind", 50, Rarity.MYTHIC, mage.cards.s.SwordOfBodyAndMind.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sword of Feast and Famine", 28, Rarity.MYTHIC, mage.cards.s.SwordOfFeastAndFamine.class, new CardGraphicInfo(
FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sword of Fire and Ice", 29, Rarity.MYTHIC, mage.cards.s.SwordOfFireAndIce.class, new CardGraphicInfo(
FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sword of Light and Shadow", 30, Rarity.MYTHIC, mage.cards.s.SwordOfLightAndShadow.class, new CardGraphicInfo(
FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Sword of War and Peace", 51, Rarity.MYTHIC, mage.cards.s.SwordOfWarAndPeace.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Torrential Gearhulk", 4, Rarity.MYTHIC, mage.cards.t.TorrentialGearhulk.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Trinisphere", 52, Rarity.MYTHIC, mage.cards.t.Trinisphere.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Vedalken Shackles", 53, Rarity.MYTHIC, mage.cards.v.VedalkenShackles.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Verdurous Gearhulk", 5, Rarity.MYTHIC, mage.cards.v.VerdurousGearhulk.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION,
false)));
cards.add(new SetCardInfo("Wurmcoil Engine", 54, Rarity.MYTHIC, mage.cards.w.WurmcoilEngine.class, new CardGraphicInfo(FrameStyle.KLD_INVENTION, false)));
cards.add(new SetCardInfo("Platinum Angel", 46, Rarity.MYTHIC, mage.cards.p.PlatinumAngel.class, cardGraphicInfo));
cards.add(new SetCardInfo("Rings of Brighthearth", 21, Rarity.MYTHIC, mage.cards.r.RingsOfBrighthearth.class, cardGraphicInfo));
cards.add(new SetCardInfo("Scroll Rack", 22, Rarity.MYTHIC, mage.cards.s.ScrollRack.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sculpting Steel", 23, Rarity.MYTHIC, mage.cards.s.SculptingSteel.class, cardGraphicInfo));
cards.add(new SetCardInfo("Solemn Simulacrum", 25, Rarity.MYTHIC, mage.cards.s.SolemnSimulacrum.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sol Ring", 24, Rarity.MYTHIC, mage.cards.s.SolRing.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sphere of Resistance", 47, Rarity.MYTHIC, mage.cards.s.SphereOfResistance.class, cardGraphicInfo));
cards.add(new SetCardInfo("Staff of Domination", 48, Rarity.MYTHIC, mage.cards.s.StaffOfDomination.class, cardGraphicInfo));
cards.add(new SetCardInfo("Static Orb", 26, Rarity.MYTHIC, mage.cards.s.StaticOrb.class, cardGraphicInfo));
cards.add(new SetCardInfo("Steel Overseer", 27, Rarity.MYTHIC, mage.cards.s.SteelOverseer.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sundering Titan", 49, Rarity.MYTHIC, mage.cards.s.SunderingTitan.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sword of Body and Mind", 50, Rarity.MYTHIC, mage.cards.s.SwordOfBodyAndMind.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sword of Feast and Famine", 28, Rarity.MYTHIC, mage.cards.s.SwordOfFeastAndFamine.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sword of Fire and Ice", 29, Rarity.MYTHIC, mage.cards.s.SwordOfFireAndIce.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sword of Light and Shadow", 30, Rarity.MYTHIC, mage.cards.s.SwordOfLightAndShadow.class, cardGraphicInfo));
cards.add(new SetCardInfo("Sword of War and Peace", 51, Rarity.MYTHIC, mage.cards.s.SwordOfWarAndPeace.class, cardGraphicInfo));
cards.add(new SetCardInfo("Torrential Gearhulk", 4, Rarity.MYTHIC, mage.cards.t.TorrentialGearhulk.class, cardGraphicInfo));
cards.add(new SetCardInfo("Trinisphere", 52, Rarity.MYTHIC, mage.cards.t.Trinisphere.class, cardGraphicInfo));
cards.add(new SetCardInfo("Vedalken Shackles", 53, Rarity.MYTHIC, mage.cards.v.VedalkenShackles.class, cardGraphicInfo));
cards.add(new SetCardInfo("Verdurous Gearhulk", 5, Rarity.MYTHIC, mage.cards.v.VerdurousGearhulk.class, cardGraphicInfo));
cards.add(new SetCardInfo("Wurmcoil Engine", 54, Rarity.MYTHIC, mage.cards.w.WurmcoilEngine.class, cardGraphicInfo));
}
}

View file

@ -204,6 +204,7 @@ public class MastersEditionIII extends ExpansionSet {
cards.add(new SetCardInfo("Sivitri Scarzam", 175, Rarity.COMMON, mage.cards.s.SivitriScarzam.class));
cards.add(new SetCardInfo("Slashing Tiger", 133, Rarity.COMMON, mage.cards.s.SlashingTiger.class));
cards.add(new SetCardInfo("Sol Grail", 201, Rarity.COMMON, mage.cards.s.SolGrail.class));
cards.add(new SetCardInfo("Spirit Shackle", 74, Rarity.COMMON, mage.cards.s.SpiritShackle.class));
cards.add(new SetCardInfo("Spoils of Victory", 134, Rarity.COMMON, mage.cards.s.SpoilsOfVictory.class));
cards.add(new SetCardInfo("Stolen Grain", 75, Rarity.UNCOMMON, mage.cards.s.StolenGrain.class));
cards.add(new SetCardInfo("Strategic Planning", 51, Rarity.COMMON, mage.cards.s.StrategicPlanning.class));

View file

@ -63,7 +63,7 @@ public class TheDark extends ExpansionSet {
cards.add(new SetCardInfo("Bog Rats", 4, Rarity.COMMON, mage.cards.b.BogRats.class));
cards.add(new SetCardInfo("Bone Flute", 94, Rarity.UNCOMMON, mage.cards.b.BoneFlute.class));
cards.add(new SetCardInfo("Book of Rass", 95, Rarity.UNCOMMON, mage.cards.b.BookOfRass.class));
cards.add(new SetCardInfo("Brainwash", 76, Rarity.COMMON, mage.cards.b.Brainwash.class));
cards.add(new SetCardInfo("Brainwash", 76, Rarity.COMMON, mage.cards.b.Brainwash.class));
cards.add(new SetCardInfo("Brothers of Fire", 58, Rarity.UNCOMMON, mage.cards.b.BrothersOfFire.class));
cards.add(new SetCardInfo("Carnivorous Plant", 38, Rarity.COMMON, mage.cards.c.CarnivorousPlant.class));
cards.add(new SetCardInfo("Cave People", 59, Rarity.UNCOMMON, mage.cards.c.CavePeople.class));
@ -104,6 +104,7 @@ public class TheDark extends ExpansionSet {
cards.add(new SetCardInfo("Marsh Viper", 44, Rarity.COMMON, mage.cards.m.MarshViper.class));
cards.add(new SetCardInfo("Maze of Ith", 114, Rarity.UNCOMMON, mage.cards.m.MazeOfIth.class));
cards.add(new SetCardInfo("Merfolk Assassin", 31, Rarity.UNCOMMON, mage.cards.m.MerfolkAssassin.class));
cards.add(new SetCardInfo("Morale", 87, Rarity.COMMON, mage.cards.m.Morale.class));
cards.add(new SetCardInfo("Murk Dwellers", 11, Rarity.COMMON, mage.cards.m.MurkDwellers.class));
cards.add(new SetCardInfo("Niall Silvain", 45, Rarity.RARE, mage.cards.n.NiallSilvain.class));
cards.add(new SetCardInfo("Orc General", 72, Rarity.UNCOMMON, mage.cards.o.OrcGeneral.class));
@ -119,7 +120,7 @@ public class TheDark extends ExpansionSet {
cards.add(new SetCardInfo("Sisters of the Flame", 73, Rarity.UNCOMMON, mage.cards.s.SistersOfTheFlame.class));
cards.add(new SetCardInfo("Skull of Orm", 106, Rarity.UNCOMMON, mage.cards.s.SkullOfOrm.class));
cards.add(new SetCardInfo("Squire", 90, Rarity.COMMON, mage.cards.s.Squire.class));
cards.add(new SetCardInfo("Standing Stones", 107, Rarity.UNCOMMON, mage.cards.s.StandingStones.class));
cards.add(new SetCardInfo("Standing Stones", 107, Rarity.UNCOMMON, mage.cards.s.StandingStones.class));
cards.add(new SetCardInfo("Stone Calendar", 108, Rarity.RARE, mage.cards.s.StoneCalendar.class));
cards.add(new SetCardInfo("Sunken City", 35, Rarity.COMMON, mage.cards.s.SunkenCity.class));
cards.add(new SetCardInfo("Tivadar's Crusade", 91, Rarity.UNCOMMON, mage.cards.t.TivadarsCrusade.class));

View file

@ -130,6 +130,7 @@ public class TimeSpiral extends ExpansionSet {
cards.add(new SetCardInfo("Haunting Hymn", 112, Rarity.UNCOMMON, mage.cards.h.HauntingHymn.class));
cards.add(new SetCardInfo("Havenwood Wurm", 199, Rarity.COMMON, mage.cards.h.HavenwoodWurm.class));
cards.add(new SetCardInfo("Herd Gnarr", 200, Rarity.COMMON, mage.cards.h.HerdGnarr.class));
cards.add(new SetCardInfo("Hivestone", 256, Rarity.RARE, mage.cards.h.Hivestone.class));
cards.add(new SetCardInfo("Hypergenesis", 201, Rarity.RARE, mage.cards.h.Hypergenesis.class));
cards.add(new SetCardInfo("Ib Halfheart, Goblin Tactician", 163, Rarity.RARE, mage.cards.i.IbHalfheartGoblinTactician.class));
cards.add(new SetCardInfo("Icatian Crier", 23, Rarity.COMMON, mage.cards.i.IcatianCrier.class));

View file

@ -58,6 +58,7 @@ public class Visions extends ExpansionSet {
cards.add(new SetCardInfo("Archangel", 101, Rarity.RARE, mage.cards.a.Archangel.class));
cards.add(new SetCardInfo("Army Ants", 126, Rarity.UNCOMMON, mage.cards.a.ArmyAnts.class));
cards.add(new SetCardInfo("Betrayal", 26, Rarity.COMMON, mage.cards.b.Betrayal.class));
cards.add(new SetCardInfo("Blanket of Night", 2, Rarity.UNCOMMON, mage.cards.b.BlanketOfNight.class));
cards.add(new SetCardInfo("Breezekeeper", 27, Rarity.COMMON, mage.cards.b.Breezekeeper.class));
cards.add(new SetCardInfo("Chronatog", 28, Rarity.RARE, mage.cards.c.Chronatog.class));
cards.add(new SetCardInfo("City of Solitude", 52, Rarity.RARE, mage.cards.c.CityOfSolitude.class));

View file

@ -67,4 +67,28 @@ public class AddingCountersToPermanentsTest extends CardTestPlayerBase {
}
/**
* Fairgrounds Trumpeter does not get a counter at the end of turn when
* Woodland Wanderer enters the battlefield
*/
@Test
public void testFairgroundsTrumpeter() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 7);
// At the beginning of each end step, if a +1/+1 counter was placed on a permanent under your control this turn, put a +1/+1 counter on Fairgrounds Trumpeter.
addCard(Zone.HAND, playerA, "Fairgrounds Trumpeter", 1); // Creature 2/2 {2}{G}
// Vigilance, trample
// <i>Converge</i> &mdash; Woodland Wanderer enters the battlefield with a +1/+1 counter on it for each color of mana spent to cast it.
addCard(Zone.HAND, playerA, "Woodland Wanderer", 1); // Creature 2/2 {3}{G}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Woodland Wanderer");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Fairgrounds Trumpeter");
setStopAt(1, PhaseStep.END_TURN);
execute();
assertPowerToughness(playerA, "Woodland Wanderer", 3, 3);
assertPowerToughness(playerA, "Fairgrounds Trumpeter", 3, 3);
}
}

View file

@ -105,4 +105,36 @@ public class GainControlTargetEffectTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Mutavault", 1);
}
/**
* Steel Golem, once Donate'd to another player does not disable their ability to play creature cards.
*/
@Test
public void testDonateSteelGolem() {
// You can't cast creature spells.
addCard(Zone.HAND, playerA, "Steel Golem", 1); // Creature 3/4 {3}
// Target player gains control of target permanent you control.
addCard(Zone.HAND, playerA, "Donate", 1); // Sorcery {2}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 6);
addCard(Zone.BATTLEFIELD, playerB, "Plains", 2);
addCard(Zone.HAND, playerB, "Silvercoat Lion", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Steel Golem");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Donate", playerB);
addTarget(playerA, "Steel Golem");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Silvercoat Lion");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Donate", 1);
assertPermanentCount(playerA, "Steel Golem", 0);
assertPermanentCount(playerB, "Steel Golem", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 0);
assertHandCount(playerB, "Silvercoat Lion", 1);
}
}

View file

@ -79,5 +79,51 @@ public class GontiLordOfLuxuryEffectTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Rashmi, Eternities Crafter", 1);
}
/**
* Opponent using Gonti, Lord of Luxury took Mirari's Wake out of my library and cast it.
* I cast Cyclonic Rift on Mirari's Wake to put it back in my hand and was unable to recast Mirari's Wake.
*/
@Test
public void testCanBeCastAgainCyclonicRift() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 9);
// Deathtouch
// When Gonti, Lord of Luxury enters the battlefield, look at the top four cards of target opponent's library, exile one of them face down,
// then put the rest on the bottom of that library in a random order. For as long as that card remains exiled,
// you may look at it, you may cast it, and you may spend mana as though it were mana of any type to cast it.
addCard(Zone.HAND, playerA, "Gonti, Lord of Luxury", 1); // Creature 2/3 {2}{B}{B}
// Creatures you control get +1/+1.
// Whenever you tap a land for mana, add one mana to your mana pool of any type that land produced.
addCard(Zone.LIBRARY, playerB, "Mirari's Wake"); // Enchantment {3}{G}{W}
skipInitShuffling();
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
addCard(Zone.BATTLEFIELD, playerB, "Forest", 2);
addCard(Zone.BATTLEFIELD, playerB, "Plains", 1);
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
// Return target nonland permanent you don't control to its owner's hand.
// Overload {6}{U} (You may cast this spell for its overload cost. If you do, change its text by replacing all instances of "target" with "each.")
addCard(Zone.HAND, playerB, "Cyclonic Rift", 1); // Intant {1}{U}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Gonti, Lord of Luxury");
addTarget(playerA, playerB);
setChoice(playerA, "Mirari's Wake");
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Mirari's Wake");
castSpell(1, PhaseStep.END_TURN, playerB, "Cyclonic Rift", "Mirari's Wake");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Mirari's Wake");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Gonti, Lord of Luxury", 1);
assertPowerToughness(playerA, "Gonti, Lord of Luxury", 2, 3);
assertGraveyardCount(playerB, "Cyclonic Rift", 1);
assertPermanentCount(playerB, "Mirari's Wake", 1);
assertPowerToughness(playerB, "Silvercoat Lion", 3, 3);
}
}

View file

@ -0,0 +1,59 @@
package org.mage.test.cards.single.aer;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author Quercitron
*/
public class HopeOfGhirapurTest extends CardTestPlayerBase {
@Test
public void testThatNoncreatureSpellsCannotBeCast() {
addCard(Zone.BATTLEFIELD, playerA, "Hope of Ghirapur");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Shock");
attack(1, playerA, "Hope of Ghirapur");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Sacrifice", playerB);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Shock", playerA);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 19);
assertPermanentCount(playerA, "Hope of Ghirapur", 0);
}
// Test that ability cannot be activated if after damage Hope of Ghirapur was removed
// from the battlefield and returned back.
@Test
public void testWhenHopeOfGhirapurWasRemovedAndReturnedBack() {
addCard(Zone.BATTLEFIELD, playerA, "Hope of Ghirapur");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
addCard(Zone.HAND, playerA, "Cloudshift");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Shock");
attack(1, playerA, "Hope of Ghirapur");
castSpell(1, PhaseStep.END_COMBAT, playerA, "Cloudshift", "Hope of Ghirapur");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Sacrifice", playerB);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Shock", playerA);
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 18);
assertLife(playerB, 19);
assertPermanentCount(playerA, "Hope of Ghirapur", 1);
}
}

View file

@ -0,0 +1,189 @@
package org.mage.test.cards.single.fut;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.filter.Filter;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* This test is based on rulings of the card Muraganda Petroglyphs in magic Gatherer site
* (http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=145110), accessed in
* 08/01/2017.
*
* @author alexsandro.
*/
public class MuragandaPetroglyphsTest extends CardTestPlayerBase {
/**
* Muraganda Petroglyphs gives a bonus only to creatures that have no rules text at all.
* This includes true vanilla creatures (such as Grizzly Bears), face-down creatures,
* many tokens, and creatures that have lost their abilities (due to Ovinize, for example).
* Any ability of any kind, whether or not the ability functions in the on the battlefield zone,
* including things like Cycling 2 means the creature doesnt get the bonus.
*/
@Test
public void trueVanillaCardsTest() {
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
addCard(Zone.BATTLEFIELD, playerB, "Grizzly Bears", 1);
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
assertPowerToughness(playerA, "Grizzly Bears", 4, 4, Filter.ComparisonScope.Any);
assertPowerToughness(playerB, "Grizzly Bears", 4, 4, Filter.ComparisonScope.Any);
}
@Test
public void faceDownCreaturesTest() {
addCard(Zone.HAND, playerA, "Pine Walker");
addCard(Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pine Walker");
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "", 1);
assertPowerToughness(playerA, "", 4, 4);
}
@Test
public void faceDownGainedAbilityTest() {
addCard(Zone.HAND, playerA, "Pine Walker");
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Mass Hysteria"); // All creatures have haste.
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Pine Walker");
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "", 1);
assertPowerToughness(playerA, "", 2, 2);
}
@Test
public void tokenTest() {
addCard(Zone.BATTLEFIELD, playerA, "Plains", 2);
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
// Put two 1/1 white Soldier creature tokens onto the battlefield.
addCard(Zone.HAND, playerA, "Raise the Alarm"); // Instant {1}{W}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Raise the Alarm");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Soldier", 3, 3);
}
@Test
public void loseAbilitiesTest() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
addCard(Zone.BATTLEFIELD, playerB, "Goblin Guide", 1);
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
addCard(Zone.HAND, playerA, "Ovinize");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ovinize", "Goblin Guide");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerB, "Goblin Guide", 2, 3);
}
@Test
public void CyclingAbilityTest() {
addCard(Zone.BATTLEFIELD, playerA, "Hundroog", 1); // Cycling {3}, 4/7
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Hundroog", 4, 7);
}
/**
* Animated basic lands have mana abilities, so they wont get the bonus.
*/
@Test
public void animateBasicLandTest() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
addCard(Zone.HAND, playerA, "Vastwood Zendikon");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Vastwood Zendikon", "Forest");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Forest", 6, 4);
}
/**
* Some Auras and Equipment grant abilities to creatures, meaning the affected creature would no longer
* get the +2/+2 bonus. For example, Flight grants flying to the enchanted creature. Other Auras and Equipment
* do not, meaning the affected creature would continue to get the +2/+2 bonus. For example, Dehydration states
* something now true about the enchanted creature, but doesnt give it any abilities. Auras and Equipment that
* grant abilities will use the words gains or has, and theyll list a keyword ability or an ability in
* quotation marks.
*/
@Test
public void grantAbilitiesTest() {
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
addCard(Zone.BATTLEFIELD, playerA, "Runeclaw Bear", 1);
// Enchanted creature gets +2/+0 and has trample.
addCard(Zone.HAND, playerA, "Rancor");
// Enchanted creature doesn't untap during itscontroller's untap step.
addCard(Zone.HAND, playerA, "Dehydration");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA,"Rancor", "Grizzly Bears");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Dehydration", "Runeclaw Bear");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Grizzly Bears", 4, 2);
assertPowerToughness(playerA, "Runeclaw Bear", 4, 4);
}
/**
* Cipher grants an ability to creatures, meaning the affected creatures would no longer get the +2/+2 bonus.
*/
@Test
public void cipherTest() {
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 6);
addCard(Zone.BATTLEFIELD, playerA, "Muraganda Petroglyphs", 1);
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
addCard(Zone.HAND, playerA, "Shadow Slice"); // {4}{B}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Shadow Slice");
setChoice(playerA, "Grizzly Bears");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPowerToughness(playerA, "Grizzly Bears", 2, 2);
}
}

View file

@ -0,0 +1,60 @@
package org.mage.test.cards.single.tsp;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.filter.Filter;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* Created by Alexsandr0x.
*/
public class HivestoneTest extends CardTestPlayerBase {
/**
* If a creature is already a Sliver, Hivestone has no effect on it.
*/
@Test
public void abilityCheckTest() {
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
addCard(Zone.BATTLEFIELD, playerA, "Hivestone", 1);
addCard(Zone.BATTLEFIELD, playerA, "Muscle Sliver", 1);
addCard(Zone.BATTLEFIELD, playerB, "Runeclaw Bear", 1);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
assertPowerToughness(playerA, "Grizzly Bears", 3, 3, Filter.ComparisonScope.Any);
assertPowerToughness(playerB, "Runeclaw Bear", 2, 2, Filter.ComparisonScope.Any);
}
/**
* Turns only your creatures on the battlefield, not in other zones, into Slivers. It wont allow you to have
* Root Sliver on the battlefield and make your Grizzly Bears uncounterable, for example.
*/
@Test
public void rootSliverTest() {
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
addCard(Zone.BATTLEFIELD, playerA, "Hivestone", 1);
// Root Sliver can't be countered. Sliver spells can't be countered by spells or abilities.
addCard(Zone.BATTLEFIELD, playerA, "Root Sliver", 1);
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
addCard(Zone.BATTLEFIELD, playerB, "Island", 2);
addCard(Zone.HAND, playerB, "Counterspell");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Counterspell", "Grizzly Bears", "Grizzly Bears");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, 1);
}
}

View file

@ -27,10 +27,8 @@
*/
package org.mage.test.cards.triggers;
import mage.cards.Card;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
@ -61,7 +59,7 @@ public class PossibilityStormTest extends CardTestPlayerBase {
// the top of his or her library until he or she exiles a card that shares a card type with it. That
// player may cast that card without paying its mana cost. Then he or she puts all cards exiled with
// Possibility Storm on the bottom of his or her library in a random order.
addCard(Zone.BATTLEFIELD, playerA, "Possibility Storm", 2);
addCard(Zone.BATTLEFIELD, playerA, "Possibility Storm", 1);
// {T}: Add {C} to your mana pool.
// Morph {2}
@ -78,14 +76,7 @@ public class PossibilityStormTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "Zoetic Cavern", 0);
boolean zoeticCavernInLibrary = false;
for (Card card : playerA.getLibrary().getCards(currentGame)) {
if (card.getName().equals("Zoetic Cavern")) {
zoeticCavernInLibrary = true;
}
}
Assert.assertEquals("Zoetic Cavern has to be in the library", true, zoeticCavernInLibrary);
assertLibraryCount(playerA, "Zoetic Cavern", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 1);
}

View file

@ -10,28 +10,50 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
* @author BetaSteward
*/
public class SpiritOfTheLabyrinthTest extends CardTestPlayerBase {
/*
* Spirit of the Labyrinth
* Enchantment Creature Spirit 3/1, 1W (2)
* Each player can't draw more than one card each turn.
*
*/
*/
// test that only 1 card is drawn
@Test
public void testDrawCard() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.BATTLEFIELD, playerA, "Spirit of the Labyrinth");
addCard(Zone.HAND, playerA, "Brilliant Plan");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brilliant Plan");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
this.assertHandCount(playerA, 1);
}
this.assertHandCount(playerA, 1);
}
// test that only 1 card is drawn
@Test
public void testDrawCardHondenOfSeeingWinds() {
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
addCard(Zone.BATTLEFIELD, playerA, "Spirit of the Labyrinth");
addCard(Zone.HAND, playerA, "Brilliant Plan");
// At the beginning of your upkeep, draw a card for each Shrine you control.
addCard(Zone.BATTLEFIELD, playerB, "Honden of Seeing Winds");
// At the beginning of your upkeep, put a 1/1 colorless Spirit creature token onto the battlefield for each Shrine you control.
addCard(Zone.BATTLEFIELD, playerB, "Honden of Life's Web");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Brilliant Plan");
setStopAt(2, PhaseStep.PRECOMBAT_MAIN);
execute();
assertPermanentCount(playerB, "Spirit", 2);
this.assertHandCount(playerA, 1);
this.assertHandCount(playerB, 1);
}
}

View file

@ -45,7 +45,7 @@ public class RevoltCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
RevoltWatcher watcher = (RevoltWatcher) game.getState().getWatchers().get("Revolt");
RevoltWatcher watcher = (RevoltWatcher) game.getState().getWatchers().get(RevoltWatcher.class.getName());
return watcher != null && watcher.revoltActive(source.getControllerId());
}

View file

@ -0,0 +1,75 @@
/*
* 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.abilities.effects.common.continuous;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
* @author Galatolol
*/
public class AddCardSubtypeAllEffect extends ContinuousEffectImpl {
private static FilterPermanent filter;
private static String addedSubtype;
public AddCardSubtypeAllEffect(FilterPermanent _filter, String _addedSubtype, DependencyType _dependency) {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
filter = _filter;
staticText = "";
addedSubtype = _addedSubtype;
addDependencyType(_dependency);
}
public AddCardSubtypeAllEffect(final AddCardSubtypeAllEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (perm != null && !perm.getSubtype(game).contains(addedSubtype)) {
perm.getSubtype(game).add(addedSubtype);
}
}
return true;
}
@Override
public AddCardSubtypeAllEffect copy() {
return new AddCardSubtypeAllEffect(this);
}
}

View file

@ -61,9 +61,9 @@ public class GetEnergyCountersControllerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
return player.addCounters(CounterType.ENERGY.createInstance(value.calculate(game, source, this)), game);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
return controller.addCounters(CounterType.ENERGY.createInstance(value.calculate(game, source, this)), game);
}
return false;
}
@ -72,7 +72,7 @@ public class GetEnergyCountersControllerEffect extends OneShotEffect {
if (!staticText.isEmpty()) {
return;
}
StringBuilder sb = new StringBuilder();
sb.append("you get ");
int val = 1;

View file

@ -100,7 +100,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
protected static final String ABILITY_KEYWORD = "Morph";
protected static final String ABILITY_KEYWORD_MEGA = "Megamorph";
protected static final String REMINDER_TEXT = "<i>(You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)</i>";
protected static final String REMINDER_TEXT_MEGA = "<i>(You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)</i>";
protected static final String REMINDER_TEXT_MEGA = "<i>(You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its megamorph cost and put a +1/+1 counter on it.)</i>";
protected String ruleText;
protected AlternativeCost2Impl alternateCosts = new AlternativeCost2Impl(ABILITY_KEYWORD, REMINDER_TEXT, new GenericManaCost(3));
protected Costs<Cost> morphCosts;
@ -194,7 +194,8 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
@Override
public boolean isAvailable(Ability source, Game game) {
return true;
return game.isMainPhase() && game.getActivePlayerId().equals(source.getControllerId())
&& (game.getStack().isEmpty() || (game.getStack().size() == 1 && game.getStack().getFirst().getSourceId().equals(source.getSourceId())));
}
@Override
@ -282,10 +283,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
@Override
public String getCastMessageSuffix(Game game) {
StringBuilder sb = new StringBuilder();
int position = 0;
sb.append(alternateCosts.getCastSuffixMessage(position));
return sb.toString();
return alternateCosts.getCastSuffixMessage(0);
}
@Override

View file

@ -98,6 +98,11 @@ public abstract class ActivatedManaAbilityImpl extends ActivatedAbilityImpl impl
return netMana.size() > 0;
}
/**
* Is it allowed to undo the mana creation.
* It's e.g. not allowed if some game revealing information is related (like reveal the top card of the library)
* @return
*/
public boolean isUndoPossible() {
return undoPossible;
}

View file

@ -29,6 +29,8 @@ package mage.abilities.mana;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.Mana;
import mage.abilities.Abilities;
import mage.abilities.Ability;
@ -161,6 +163,7 @@ class AnyColorLandsProduceManaEffect extends ManaEffect {
}
private Mana getManaTypes(Game game, Ability source) {
Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "needed to identify endless loop causing cards: {0}", source.getSourceObject(game).getName());
List<Permanent> lands = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game);
Mana types = new Mana();
for (Permanent land : lands) {

View file

@ -43,17 +43,32 @@ import mage.game.Game;
*/
public class SimpleManaAbility extends ActivatedManaAbilityImpl {
private boolean predictable;
public SimpleManaAbility(Zone zone, ManaEffect effect, Cost cost) {
this(zone, effect, cost, true);
}
/**
*
* @param zone
* @param effect
* @param cost
* @param predictable set to false if definig the mana type or amount needs to reveal information and can't be predicted
*/
public SimpleManaAbility(Zone zone, ManaEffect effect, Cost cost, boolean predictable) {
super(zone, effect, cost);
this.predictable = predictable;
}
public SimpleManaAbility(Zone zone, Mana mana, Cost cost) {
super(zone, new BasicManaEffect(mana), cost);
this.netMana.add(mana.copy());
this.predictable = true;
}
public SimpleManaAbility(final SimpleManaAbility ability) {
super(ability);
this.predictable = ability.predictable;
}
@Override
@ -63,7 +78,7 @@ public class SimpleManaAbility extends ActivatedManaAbilityImpl {
@Override
public List<Mana> getNetMana(Game game) {
if (netMana.isEmpty()) {
if (netMana.isEmpty() && predictable) {
for (Effect effect: getEffects()) {
if (effect instanceof ManaEffect) {
Mana effectMana =((ManaEffect)effect).getMana(game, this);

View file

@ -26,6 +26,10 @@ public enum FrameStyle {
* Zenkikar full art lands
*/
ZEN_FULL_ART_BASIC(BorderType.MOD, true),
/**
* Magic Player Rewards full art cards
*/
MPRP_FULL_ART_BASIC(BorderType.MOD, true),
/**
* Unhinged full art lands
*/

View file

@ -60,7 +60,7 @@ public enum CardRepository {
// raise this if db structure was changed
private static final long CARD_DB_VERSION = 50;
// raise this if new cards were added to the server
private static final long CARD_CONTENT_VERSION = 68;
private static final long CARD_CONTENT_VERSION = 69;
private final TreeSet<String> landTypes = new TreeSet();
private Dao<CardInfo, Object> cardDao;
private Set<String> classNames;

View file

@ -28,7 +28,7 @@ public enum ExpansionRepository {
private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE";
private static final String VERSION_ENTITY_NAME = "expansion";
private static final long EXPANSION_DB_VERSION = 5;
private static final long EXPANSION_CONTENT_VERSION = 11;
private static final long EXPANSION_CONTENT_VERSION = 12;
private Dao<ExpansionInfo, Object> expansionDao;

View file

@ -299,7 +299,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
}
if (damage > 0 && hasTrample(attacker)) {
defenderDamage(attacker, damage, game);
} else {
} else if (!blockerOrder.isEmpty()) {
// Assign the damge left to first blocker
assigned.put(blockerOrder.get(0), assigned.get(blockerOrder.get(0)) + damage);
}

View file

@ -432,6 +432,13 @@ public class Spell extends StackObjImpl implements Card {
@Override
public String getLogName() {
if (faceDown) {
if (getCardType().contains(CardType.CREATURE)) {
return "face down creature spell";
} else {
return "face down spell";
}
}
return GameLog.getColoredObjectIdName(card);
}
@ -451,7 +458,7 @@ public class Spell extends StackObjImpl implements Card {
@Override
public List<CardType> getCardType() {
if (this.getSpellAbility().getSpellAbilityType().equals(SpellAbilityType.FACE_DOWN_CREATURE)) {
if (faceDown) {
List<CardType> cardTypes = new ArrayList<>();
cardTypes.add(CardType.CREATURE);
return cardTypes;

View file

@ -506,6 +506,7 @@ public interface Player extends MageItem, Copyable<Player> {
* @param cards - list of cards that have to be moved
* @param game - game
* @param anyOrder - true if player can determine the order of the cards
* else random order
* @param source - source ability
* @return
*/

View file

@ -825,8 +825,10 @@ public abstract class PlayerImpl implements Player, Serializable {
if (!cardsToLibrary.isEmpty()) {
Cards cards = new CardsImpl(cardsToLibrary); // prevent possible ConcurrentModificationException
if (!anyOrder) {
for (UUID objectId : cards) {
moveObjectToLibrary(objectId, source == null ? null : source.getSourceId(), game, false, false);
while (!cards.isEmpty()) {
UUID cardId = cards.getRandom(game).getId();
cards.remove(cardId);
moveObjectToLibrary(cardId, source == null ? null : source.getSourceId(), game, false, false);
}
} else {
TargetCard target = new TargetCard(Zone.ALL, new FilterCard("card to put on the bottom of your library (last one chosen will be bottommost)"));
@ -864,8 +866,10 @@ public abstract class PlayerImpl implements Player, Serializable {
Cards cards = new CardsImpl(cardsToLibrary); // prevent possible ConcurrentModificationException
UUID sourceId = (source == null ? null : source.getSourceId());
if (!anyOrder) {
for (UUID cardId : cards) {
moveObjectToLibrary(cardId, sourceId, game, true, false);
while (!cards.isEmpty()) {
UUID cardId = cards.getRandom(game).getId();
cards.remove(cardId);
moveObjectToLibrary(cardId, source == null ? null : source.getSourceId(), game, true, false);
}
} else {
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterCard("card to put on the top of your library (last one chosen will be topmost)"));
@ -2764,7 +2768,9 @@ public abstract class PlayerImpl implements Player, Serializable {
case STATIC:
if (card.getCardType().contains(CardType.LAND) && ability instanceof AlternativeSourceCosts) {
if (canLandPlayAlternateSourceCostsAbility(card, available, ability, game)) { // e.g. Land with Morph
playable.add(card.getId());
if (game.canPlaySorcery(getId())) {
playable.add(card.getId());
}
break Abilities;
}
}
@ -3289,6 +3295,9 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardToGraveyardWithInfo(Card card, UUID sourceId, Game game, Zone fromZone) {
if (card == null) {
return false;
}
boolean result = false;
// Zone fromZone = game.getState().getZone(card.getId());
if (card.moveToZone(Zone.GRAVEYARD, sourceId, game, fromZone != null ? fromZone == Zone.BATTLEFIELD : false)) {
@ -3313,6 +3322,9 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardToLibraryWithInfo(Card card, UUID sourceId, Game game, Zone fromZone, boolean toTop, boolean withName) {
if (card == null) {
return false;
}
boolean result = false;
if (card.moveToZone(Zone.LIBRARY, sourceId, game, toTop)) {
if (!game.isSimulation()) {
@ -3342,6 +3354,9 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, UUID sourceId, Game game, Zone fromZone, boolean withName) {
if (card == null) {
return false;
}
boolean result = false;
if (card.moveToExile(exileId, exileName, sourceId, game)) {
if (!game.isSimulation()) {

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.watchers.common;
import java.util.HashSet;
@ -49,11 +48,12 @@ public class RevoltWatcher extends Watcher {
private final Set<UUID> revoltActivePlayerIds = new HashSet<>(0);
public RevoltWatcher() {
super("Revolt", WatcherScope.GAME);
super(RevoltWatcher.class.getName(), WatcherScope.GAME);
}
public RevoltWatcher(final RevoltWatcher watcher) {
super(watcher);
this.revoltActivePlayerIds.addAll(watcher.revoltActivePlayerIds);
}
@Override
@ -78,8 +78,6 @@ public class RevoltWatcher extends Watcher {
revoltActivePlayerIds.clear();
}
@Override
public RevoltWatcher copy() {
return new RevoltWatcher(this);

View file

@ -110,7 +110,7 @@ if (!exists $cards{$cardName}) {
# Check if card is already implemented
my $fileName = "../Mage.Sets/src/mage/cards/".lc(substr($cardName, 0, 1))."/".toCamelCase($cardName).".java";
if(-e $fileName) {
die "$cardName is already implemented.\n";
die "$cardName is already implemented.\n$fileName\n";
}
# Generate lines to corresponding sets